Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/GCMetadata.cpp
35233 views
//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the GCFunctionInfo class and GCModuleInfo pass.9//10//===----------------------------------------------------------------------===//1112#include "llvm/CodeGen/GCMetadata.h"13#include "llvm/ADT/StringExtras.h"14#include "llvm/CodeGen/Passes.h"15#include "llvm/IR/Function.h"16#include "llvm/IR/Module.h"17#include "llvm/InitializePasses.h"18#include "llvm/MC/MCSymbol.h"19#include "llvm/Pass.h"20#include "llvm/Support/raw_ostream.h"21#include <cassert>22#include <memory>23#include <string>2425using namespace llvm;2627bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,28ModuleAnalysisManager::Invalidator &) {29for (const auto &F : M) {30if (F.isDeclaration() || !F.hasGC())31continue;32if (!StrategyMap.contains(F.getGC()))33return true;34}35return false;36}3738AnalysisKey CollectorMetadataAnalysis::Key;3940CollectorMetadataAnalysis::Result41CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {42Result R;43auto &Map = R.StrategyMap;44for (auto &F : M) {45if (F.isDeclaration() || !F.hasGC())46continue;47if (auto GCName = F.getGC(); !Map.contains(GCName))48Map[GCName] = getGCStrategy(GCName);49}50return R;51}5253AnalysisKey GCFunctionAnalysis::Key;5455GCFunctionAnalysis::Result56GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {57assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");58assert(F.hasGC() && "Function doesn't have GC!");5960auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);61assert(62MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&63"This pass need module analysis `collector-metadata`!");64auto &Map =65MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent())66->StrategyMap;67GCFunctionInfo Info(F, *Map[F.getGC()]);68return Info;69}7071INITIALIZE_PASS(GCModuleInfo, "collector-metadata",72"Create Garbage Collector Module Metadata", false, false)7374// -----------------------------------------------------------------------------7576GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)77: F(F), S(S), FrameSize(~0LL) {}7879GCFunctionInfo::~GCFunctionInfo() = default;8081bool GCFunctionInfo::invalidate(Function &F, const PreservedAnalyses &PA,82FunctionAnalysisManager::Invalidator &) {83auto PAC = PA.getChecker<GCFunctionAnalysis>();84return !PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>();85}8687// -----------------------------------------------------------------------------8889char GCModuleInfo::ID = 0;9091GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) {92initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());93}9495GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {96assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");97assert(F.hasGC());9899finfo_map_type::iterator I = FInfoMap.find(&F);100if (I != FInfoMap.end())101return *I->second;102103GCStrategy *S = getGCStrategy(F.getGC());104Functions.push_back(std::make_unique<GCFunctionInfo>(F, *S));105GCFunctionInfo *GFI = Functions.back().get();106FInfoMap[&F] = GFI;107return *GFI;108}109110void GCModuleInfo::clear() {111Functions.clear();112FInfoMap.clear();113GCStrategyList.clear();114}115116// -----------------------------------------------------------------------------117118GCStrategy *GCModuleInfo::getGCStrategy(const StringRef Name) {119// TODO: Arguably, just doing a linear search would be faster for small N120auto NMI = GCStrategyMap.find(Name);121if (NMI != GCStrategyMap.end())122return NMI->getValue();123124std::unique_ptr<GCStrategy> S = llvm::getGCStrategy(Name);125S->Name = std::string(Name);126GCStrategyMap[Name] = S.get();127GCStrategyList.push_back(std::move(S));128return GCStrategyList.back().get();129}130131132