diff options
author | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-12-11 00:30:17 +0000 |
---|---|---|
committer | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-12-11 00:30:17 +0000 |
commit | ad93c4f936d220570535711262e0fff8857f798a (patch) | |
tree | 285ad723e6fbc86a2e38e2dcdabb27288d6fe8f6 /lib/CodeGen | |
parent | 519452282b1fc4d48c112f4b945700629ac34585 (diff) |
CollectorMetadata and Collector are rejiggered to get along with
per-function collector model. Collector is now the factory for
CollectorMetadata, so the latter may be subclassed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44827 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/Collector.cpp | 205 | ||||
-rw-r--r-- | lib/CodeGen/CollectorMetadata.cpp | 92 |
2 files changed, 186 insertions, 111 deletions
diff --git a/lib/CodeGen/Collector.cpp b/lib/CodeGen/Collector.cpp index 29dc50420b..67b392889e 100644 --- a/lib/CodeGen/Collector.cpp +++ b/lib/CodeGen/Collector.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/Collector.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/PassManager.h" @@ -29,38 +30,40 @@ using namespace llvm; namespace { - /// This pass rewrites calls to the llvm.gcread or llvm.gcwrite intrinsics, - /// replacing them with simple loads and stores as directed by the Collector. - /// This is useful for most garbage collectors. + /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or + /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as + /// directed by the Collector. It also performs automatic root initialization + /// and custom intrinsic lowering. class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass { - const Collector &Coll; - /// GCRootInt, GCReadInt, GCWriteInt - The function prototypes for the /// llvm.gc* intrinsics. Function *GCRootInt, *GCReadInt, *GCWriteInt; + static bool NeedsDefaultLoweringPass(const Collector &C); + static bool NeedsCustomLoweringPass(const Collector &C); static bool CouldBecomeSafePoint(Instruction *I); - static void InsertRootInitializers(Function &F, + bool PerformDefaultLowering(Function &F, Collector &Coll); + static bool InsertRootInitializers(Function &F, AllocaInst **Roots, unsigned Count); public: static char ID; - LowerIntrinsics(const Collector &GC); + LowerIntrinsics(); const char *getPassName() const; + void getAnalysisUsage(AnalysisUsage &AU) const; bool doInitialization(Module &M); bool runOnFunction(Function &F); }; - /// This is a target-independent pass over the machine function representation - /// to identify safe points for the garbage collector in the machine code. It - /// inserts labels at safe points and populates the GCInfo class. + /// MachineCodeAnalysis - This is a target-independent pass over the machine + /// function representation to identify safe points for the garbage collector + /// in the machine code. It inserts labels at safe points and populates a + /// CollectorMetadata record for each function. class VISIBILITY_HIDDEN MachineCodeAnalysis : public MachineFunctionPass { - const Collector &Coll; - const TargetMachine &Targ; - + const TargetMachine *TM; CollectorMetadata *MD; MachineModuleInfo *MMI; const TargetInstrInfo *TII; @@ -76,7 +79,7 @@ namespace { public: static char ID; - MachineCodeAnalysis(const Collector &C, const TargetMachine &T); + MachineCodeAnalysis(); const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; @@ -87,8 +90,6 @@ namespace { // ----------------------------------------------------------------------------- -const Collector *llvm::TheCollector = 0; - Collector::Collector() : NeededSafePoints(0), CustomReadBarriers(false), @@ -97,85 +98,85 @@ Collector::Collector() : InitRoots(true) {} -Collector::~Collector() {} - -void Collector::addLoweringPasses(FunctionPassManager &PM) const { - if (NeedsDefaultLoweringPass()) - PM.add(new LowerIntrinsics(*this)); - - if (NeedsCustomLoweringPass()) - PM.add(createCustomLoweringPass()); -} - -void Collector::addLoweringPasses(PassManager &PM) const { - if (NeedsDefaultLoweringPass()) - PM.add(new LowerIntrinsics(*this)); - - if (NeedsCustomLoweringPass()) - PM.add(createCustomLoweringPass()); -} - -void Collector::addGenericMachineCodePass(FunctionPassManager &PM, - const TargetMachine &TM, - bool Fast) const { - if (needsSafePoints()) - PM.add(new MachineCodeAnalysis(*this, TM)); -} - -bool Collector::NeedsDefaultLoweringPass() const { - // Default lowering is necessary only if read or write barriers have a default - // action. The default for roots is no action. - return !customWriteBarrier() - || !customReadBarrier() - || initializeRoots(); -} - -bool Collector::NeedsCustomLoweringPass() const { - // Custom lowering is only necessary if enabled for some action. - return customWriteBarrier() - || customReadBarrier() - || customRoots(); +Collector::~Collector() { + for (iterator I = begin(), E = end(); I != E; ++I) + delete *I; + + Functions.clear(); } - -Pass *Collector::createCustomLoweringPass() const { - cerr << "Collector must override createCustomLoweringPass.\n"; + +bool Collector::initializeCustomLowering(Module &M) { return false; } + +bool Collector::performCustomLowering(Function &F) { + cerr << "gc " << getName() << " must override performCustomLowering.\n"; abort(); return 0; } -void Collector::beginAssembly(Module &M, std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI) const { +void Collector::beginAssembly(std::ostream &OS, AsmPrinter &AP, + const TargetAsmInfo &TAI) { // Default is no action. } -void Collector::finishAssembly(Module &M, CollectorModuleMetadata &CMM, - std::ostream &OS, AsmPrinter &AP, - const TargetAsmInfo &TAI) const { +void Collector::finishAssembly(std::ostream &OS, AsmPrinter &AP, + const TargetAsmInfo &TAI) { // Default is no action. } + +CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) { + CollectorMetadata *CM = new CollectorMetadata(F, *this); + Functions.push_back(CM); + return CM; +} // ----------------------------------------------------------------------------- +FunctionPass *llvm::createGCLoweringPass() { + return new LowerIntrinsics(); +} + char LowerIntrinsics::ID = 0; -LowerIntrinsics::LowerIntrinsics(const Collector &C) - : FunctionPass((intptr_t)&ID), Coll(C), +LowerIntrinsics::LowerIntrinsics() + : FunctionPass((intptr_t)&ID), GCRootInt(0), GCReadInt(0), GCWriteInt(0) {} const char *LowerIntrinsics::getPassName() const { return "Lower Garbage Collection Instructions"; } -/// doInitialization - If this module uses the GC intrinsics, find them now. If -/// not, this pass does not do anything. +void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const { + FunctionPass::getAnalysisUsage(AU); + AU.addRequired<CollectorModuleMetadata>(); +} + +/// doInitialization - If this module uses the GC intrinsics, find them now. bool LowerIntrinsics::doInitialization(Module &M) { GCReadInt = M.getFunction("llvm.gcread"); GCWriteInt = M.getFunction("llvm.gcwrite"); GCRootInt = M.getFunction("llvm.gcroot"); - return false; + + // FIXME: This is rather antisocial in the context of a JIT since it performs + // work against the entire module. But this cannot be done at + // runFunction time (initializeCustomLowering likely needs to change + // the module). + CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); + assert(CMM && "LowerIntrinsics didn't require CollectorModuleMetadata!?"); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->hasCollector()) + CMM->get(*I); // Instantiate the Collector. + + bool MadeChange = false; + for (CollectorModuleMetadata::iterator I = CMM->begin(), + E = CMM->end(); I != E; ++I) + if (NeedsCustomLoweringPass(**I)) + if ((*I)->initializeCustomLowering(M)) + MadeChange = true; + + return MadeChange; } -void LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots, +bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots, unsigned Count) { // Scroll past alloca instructions. BasicBlock::iterator IP = F.getEntryBlock().begin(); @@ -190,11 +191,32 @@ void LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots, InitedRoots.insert(AI); // Add root initializers. + bool MadeChange = false; + for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I) - if (!InitedRoots.count(*I)) + if (!InitedRoots.count(*I)) { new StoreInst(ConstantPointerNull::get(cast<PointerType>( cast<PointerType>((*I)->getType())->getElementType())), *I, IP); + MadeChange = true; + } + + return MadeChange; +} + +bool LowerIntrinsics::NeedsDefaultLoweringPass(const Collector &C) { + // Default lowering is necessary only if read or write barriers have a default + // action. The default for roots is no action. + return !C.customWriteBarrier() + || !C.customReadBarrier() + || C.initializeRoots(); +} + +bool LowerIntrinsics::NeedsCustomLoweringPass(const Collector &C) { + // Custom lowering is only necessary if enabled for some action. + return C.customWriteBarrier() + || C.customReadBarrier() + || C.customRoots(); } /// CouldBecomeSafePoint - Predicate to conservatively determine whether the @@ -228,9 +250,24 @@ bool LowerIntrinsics::CouldBecomeSafePoint(Instruction *I) { /// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores. /// Leave gcroot intrinsics; the code generator needs to see those. bool LowerIntrinsics::runOnFunction(Function &F) { - // Quick exit for programs that do not declare the intrinsics. - if (!GCReadInt && !GCWriteInt && !GCRootInt) return false; + // Quick exit for functions that do not use GC. + if (!F.hasCollector()) return false; + + CollectorMetadata &MD = getAnalysis<CollectorModuleMetadata>().get(F); + Collector &Coll = MD.getCollector(); + + bool MadeChange = false; + + if (NeedsDefaultLoweringPass(Coll)) + MadeChange |= PerformDefaultLowering(F, Coll); + + if (NeedsCustomLoweringPass(Coll)) + MadeChange |= Coll.performCustomLowering(F); + return MadeChange; +} + +bool LowerIntrinsics::PerformDefaultLowering(Function &F, Collector &Coll) { bool LowerWr = !Coll.customWriteBarrier(); bool LowerRd = !Coll.customReadBarrier(); bool InitRoots = Coll.initializeRoots(); @@ -268,17 +305,21 @@ bool LowerIntrinsics::runOnFunction(Function &F) { } if (Roots.size()) - InsertRootInitializers(F, Roots.begin(), Roots.size()); + MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size()); return MadeChange; } // ----------------------------------------------------------------------------- +FunctionPass *llvm::createGCMachineCodeAnalysisPass() { + return new MachineCodeAnalysis(); +} + char MachineCodeAnalysis::ID = 0; -MachineCodeAnalysis::MachineCodeAnalysis(const Collector &C, const TargetMachine &T) - : MachineFunctionPass(intptr_t(&ID)), Coll(C), Targ(T) {} +MachineCodeAnalysis::MachineCodeAnalysis() + : MachineFunctionPass(intptr_t(&ID)) {} const char *MachineCodeAnalysis::getPassName() const { return "Analyze Machine Code For Garbage Collection"; @@ -304,10 +345,10 @@ void MachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) { MachineBasicBlock::iterator RAI = CI; ++RAI; - if (Coll.needsSafePoint(GC::PreCall)) + if (MD->getCollector().needsSafePoint(GC::PreCall)) MD->addSafePoint(GC::PreCall, InsertLabel(*CI->getParent(), CI)); - if (Coll.needsSafePoint(GC::PostCall)) + if (MD->getCollector().needsSafePoint(GC::PostCall)) MD->addSafePoint(GC::PostCall, InsertLabel(*CI->getParent(), RAI)); } @@ -323,7 +364,7 @@ void MachineCodeAnalysis::FindSafePoints(MachineFunction &MF) { void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) { uint64_t StackSize = MFI->getStackSize(); uint64_t OffsetAdjustment = MFI->getOffsetAdjustment(); - uint64_t OffsetOfLocalArea = Targ.getFrameInfo()->getOffsetOfLocalArea(); + uint64_t OffsetOfLocalArea = TM->getFrameInfo()->getOffsetOfLocalArea(); for (CollectorMetadata::roots_iterator RI = MD->roots_begin(), RE = MD->roots_end(); RI != RE; ++RI) @@ -332,12 +373,16 @@ void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) { } bool MachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) { - if (!Coll.needsSafePoints()) + // Quick exit for functions that do not use GC. + if (!MF.getFunction()->hasCollector()) return false; + + MD = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction()); + if (!MD->getCollector().needsSafePoints()) return false; - MD = getAnalysis<CollectorModuleMetadata>().get(MF.getFunction()); + TM = &MF.getTarget(); MMI = &getAnalysis<MachineModuleInfo>(); - TII = MF.getTarget().getInstrInfo(); + TII = TM->getInstrInfo(); MFI = MF.getFrameInfo(); // Find the size of the stack frame. diff --git a/lib/CodeGen/CollectorMetadata.cpp b/lib/CodeGen/CollectorMetadata.cpp index f86ee04c95..57349390b0 100644 --- a/lib/CodeGen/CollectorMetadata.cpp +++ b/lib/CodeGen/CollectorMetadata.cpp @@ -13,8 +13,11 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/CollectorMetadata.h" +#include "llvm/CodeGen/Collector.h" +#include "llvm/CodeGen/Collectors.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Pass.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" #include "llvm/Support/Compiler.h" @@ -22,7 +25,7 @@ using namespace llvm; namespace { - class VISIBILITY_HIDDEN Printer : public MachineFunctionPass { + class VISIBILITY_HIDDEN Printer : public FunctionPass { static char ID; std::ostream &OS; @@ -32,10 +35,10 @@ namespace { const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; - bool runOnMachineFunction(MachineFunction &MF); + bool runOnFunction(Function &F); }; - class VISIBILITY_HIDDEN Deleter : public MachineFunctionPass { + class VISIBILITY_HIDDEN Deleter : public FunctionPass { static char ID; public: @@ -44,7 +47,7 @@ namespace { const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; - bool runOnMachineFunction(MachineFunction &MF); + bool runOnFunction(Function &F); bool doFinalization(Module &M); }; @@ -55,8 +58,8 @@ namespace { // ----------------------------------------------------------------------------- -CollectorMetadata::CollectorMetadata(const Function &F) - : F(F), FrameSize(~0LL) {} +CollectorMetadata::CollectorMetadata(const Function &F, Collector &C) + : F(F), C(C), FrameSize(~0LL) {} CollectorMetadata::~CollectorMetadata() {} @@ -71,46 +74,71 @@ CollectorModuleMetadata::~CollectorModuleMetadata() { clear(); } -CollectorMetadata& CollectorModuleMetadata::insert(const Function *F) { - assert(Map.find(F) == Map.end() && "Function GC metadata already exists!"); - CollectorMetadata *FMD = new CollectorMetadata(*F); - Functions.push_back(FMD); - Map[F] = FMD; - return *FMD; +Collector *CollectorModuleMetadata:: +getOrCreateCollector(const Module *M, const std::string &Name) { + const char *Start = Name.c_str(); + + collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size()); + if (NMI != NameMap.end()) + return NMI->getValue(); + + for (CollectorRegistry::iterator I = CollectorRegistry::begin(), + E = CollectorRegistry::end(); I != E; ++I) { + if (strcmp(Start, I->getName()) == 0) { + Collector *C = I->instantiate(); + C->M = M; + C->Name = Name; + NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C); + Collectors.push_back(C); + return C; + } + } + + cerr << "unsupported collector: " << Name << "\n"; + abort(); } -CollectorMetadata* CollectorModuleMetadata::get(const Function *F) const { - map_type::iterator I = Map.find(F); - if (I == Map.end()) - return 0; - return I->second; +CollectorMetadata &CollectorModuleMetadata::get(const Function &F) { + assert(F.hasCollector()); + function_map_type::iterator I = Map.find(&F); + if (I != Map.end()) + return *I->second; + + Collector *C = getOrCreateCollector(F.getParent(), F.getCollector()); + CollectorMetadata *MD = C->insertFunctionMetadata(F); + Map[&F] = MD; + return *MD; } void CollectorModuleMetadata::clear() { + Map.clear(); + + // TODO: StringMap should provide a clear method. + while (!NameMap.empty()) + NameMap.erase(NameMap.begin()); + for (iterator I = begin(), E = end(); I != E; ++I) delete *I; - - Functions.clear(); - Map.clear(); + Collectors.clear(); } // ----------------------------------------------------------------------------- char Printer::ID = 0; -Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { +FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { return new Printer(OS); } Printer::Printer(std::ostream &OS) - : MachineFunctionPass(intptr_t(&ID)), OS(OS) {} + : FunctionPass(intptr_t(&ID)), OS(OS) {} const char *Printer::getPassName() const { return "Print Garbage Collector Information"; } void Printer::getAnalysisUsage(AnalysisUsage &AU) const { - MachineFunctionPass::getAnalysisUsage(AU); + FunctionPass::getAnalysisUsage(AU); AU.setPreservesAll(); AU.addRequired<CollectorModuleMetadata>(); } @@ -125,9 +153,9 @@ static const char *DescKind(GC::PointKind Kind) { } } -bool Printer::runOnMachineFunction(MachineFunction &MF) { - if (CollectorMetadata *FD = - getAnalysis<CollectorModuleMetadata>().get(MF.getFunction())) { +bool Printer::runOnFunction(Function &F) { + if (F.hasCollector()) { + CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F); OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; for (CollectorMetadata::roots_iterator RI = FD->roots_begin(), @@ -160,11 +188,11 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) { char Deleter::ID = 0; -Pass *llvm::createCollectorMetadataDeleter() { +FunctionPass *llvm::createCollectorMetadataDeleter() { return new Deleter(); } -Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {} +Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {} const char *Deleter::getPassName() const { return "Delete Garbage Collector Information"; @@ -175,11 +203,13 @@ void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<CollectorModuleMetadata>(); } -bool Deleter::runOnMachineFunction(MachineFunction &MF) { +bool Deleter::runOnFunction(Function &MF) { return false; } bool Deleter::doFinalization(Module &M) { - getAnalysis<CollectorModuleMetadata>().clear(); + CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); + assert(CMM && "Deleter didn't require CollectorModuleMetadata?!"); + CMM->clear(); return false; } |