brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 85e07ef Raw
130 lines · cpp
1//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the GCFunctionInfo class and GCModuleInfo pass.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/GCMetadata.h"14#include "llvm/IR/Function.h"15#include "llvm/IR/Module.h"16#include "llvm/InitializePasses.h"17#include "llvm/Pass.h"18#include <cassert>19#include <memory>20#include <string>21 22using namespace llvm;23 24bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,25                               ModuleAnalysisManager::Invalidator &) {26  for (const auto &F : M) {27    if (F.isDeclaration() || !F.hasGC())28      continue;29    if (!contains(F.getGC()))30      return true;31  }32  return false;33}34 35AnalysisKey CollectorMetadataAnalysis::Key;36 37CollectorMetadataAnalysis::Result38CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {39  Result StrategyMap;40  for (auto &F : M) {41    if (F.isDeclaration() || !F.hasGC())42      continue;43    StringRef GCName = F.getGC();44    auto [It, Inserted] = StrategyMap.try_emplace(GCName);45    if (Inserted) {46      It->second = getGCStrategy(GCName);47      It->second->Name = GCName;48    }49  }50  return StrategyMap;51}52 53AnalysisKey GCFunctionAnalysis::Key;54 55GCFunctionAnalysis::Result56GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {57  assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");58  assert(F.hasGC() && "Function doesn't have GC!");59 60  auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);61  assert(62      MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&63      "This pass need module analysis `collector-metadata`!");64  auto &Map =65      *MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent());66  GCStrategy &S = *Map.try_emplace(F.getGC()).first->second;67  GCFunctionInfo Info(F, S);68  return Info;69}70 71INITIALIZE_PASS(GCModuleInfo, "collector-metadata",72                "Create Garbage Collector Module Metadata", false, true)73 74// -----------------------------------------------------------------------------75 76GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)77    : F(F), S(S), FrameSize(~0LL) {}78 79GCFunctionInfo::~GCFunctionInfo() = default;80 81bool GCFunctionInfo::invalidate(Function &F, const PreservedAnalyses &PA,82                                FunctionAnalysisManager::Invalidator &) {83  auto PAC = PA.getChecker<GCFunctionAnalysis>();84  return !PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>();85}86 87// -----------------------------------------------------------------------------88 89char GCModuleInfo::ID = 0;90 91GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) {92  initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());93}94 95GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {96  assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");97  assert(F.hasGC());98 99  finfo_map_type::iterator I = FInfoMap.find(&F);100  if (I != FInfoMap.end())101    return *I->second;102 103  GCStrategy *S = getGCStrategy(F.getGC());104  Functions.push_back(std::make_unique<GCFunctionInfo>(F, *S));105  GCFunctionInfo *GFI = Functions.back().get();106  FInfoMap[&F] = GFI;107  return *GFI;108}109 110void GCModuleInfo::clear() {111  Functions.clear();112  FInfoMap.clear();113  GCStrategyList.clear();114}115 116// -----------------------------------------------------------------------------117 118GCStrategy *GCModuleInfo::getGCStrategy(const StringRef Name) {119  // TODO: Arguably, just doing a linear search would be faster for small N120  auto NMI = GCStrategyMap.find(Name);121  if (NMI != GCStrategyMap.end())122    return NMI->getValue();123 124  std::unique_ptr<GCStrategy> S = llvm::getGCStrategy(Name);125  S->Name = std::string(Name);126  GCStrategyMap[Name] = S.get();127  GCStrategyList.push_back(std::move(S));128  return GCStrategyList.back().get();129}130