diff options
author | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-09-27 22:18:46 +0000 |
---|---|---|
committer | Gordon Henriksen <gordonhenriksen@mac.com> | 2007-09-27 22:18:46 +0000 |
commit | fc3282221f90c626d80292327213e2badc3de86b (patch) | |
tree | 6eaec6aefedd7e70c0aed68ecee6f33775f7f5e7 /lib/CodeGen/CollectorMetadata.cpp | |
parent | 3f2d9ec186ce25b19bb36ae54eaee025150058fd (diff) |
CollectorMetadata abstractly describes stack maps for a function.
It includes:
- location and of each safe point in machine code (identified by a
label)
- location of each root within the stack frame (identified by an
offset), including the metadata tag provided to llvm.gcroot in
the user program
- size of the stack frame (for collectors which want to cheat on
stack crawling :)
- and eventually will include liveness
It is to be populated by back-ends during code-generation.
CollectorModuleMetadata aggregates this information across the
entire module.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42418 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CollectorMetadata.cpp')
-rw-r--r-- | lib/CodeGen/CollectorMetadata.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/lib/CodeGen/CollectorMetadata.cpp b/lib/CodeGen/CollectorMetadata.cpp new file mode 100644 index 0000000000..f86ee04c95 --- /dev/null +++ b/lib/CodeGen/CollectorMetadata.cpp @@ -0,0 +1,185 @@ +//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Gordon Henriksen and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CollectorMetadata and CollectorModuleMetadata +// classes. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/CollectorMetadata.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Function.h" +#include "llvm/Support/Compiler.h" + +using namespace llvm; + +namespace { + + class VISIBILITY_HIDDEN Printer : public MachineFunctionPass { + static char ID; + std::ostream &OS; + + public: + Printer(std::ostream &OS = *cerr); + + const char *getPassName() const; + void getAnalysisUsage(AnalysisUsage &AU) const; + + bool runOnMachineFunction(MachineFunction &MF); + }; + + class VISIBILITY_HIDDEN Deleter : public MachineFunctionPass { + static char ID; + + public: + Deleter(); + + const char *getPassName() const; + void getAnalysisUsage(AnalysisUsage &AU) const; + + bool runOnMachineFunction(MachineFunction &MF); + bool doFinalization(Module &M); + }; + + RegisterPass<CollectorModuleMetadata> + X("collector-metadata", "Create Garbage Collector Module Metadata"); + +} + +// ----------------------------------------------------------------------------- + +CollectorMetadata::CollectorMetadata(const Function &F) + : F(F), FrameSize(~0LL) {} + +CollectorMetadata::~CollectorMetadata() {} + +// ----------------------------------------------------------------------------- + +char CollectorModuleMetadata::ID = 0; + +CollectorModuleMetadata::CollectorModuleMetadata() + : ImmutablePass((intptr_t)&ID) {} + +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; +} + +CollectorMetadata* CollectorModuleMetadata::get(const Function *F) const { + map_type::iterator I = Map.find(F); + if (I == Map.end()) + return 0; + return I->second; +} + +void CollectorModuleMetadata::clear() { + for (iterator I = begin(), E = end(); I != E; ++I) + delete *I; + + Functions.clear(); + Map.clear(); +} + +// ----------------------------------------------------------------------------- + +char Printer::ID = 0; + +Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { + return new Printer(OS); +} + +Printer::Printer(std::ostream &OS) + : MachineFunctionPass(intptr_t(&ID)), OS(OS) {} + +const char *Printer::getPassName() const { + return "Print Garbage Collector Information"; +} + +void Printer::getAnalysisUsage(AnalysisUsage &AU) const { + MachineFunctionPass::getAnalysisUsage(AU); + AU.setPreservesAll(); + AU.addRequired<CollectorModuleMetadata>(); +} + +static const char *DescKind(GC::PointKind Kind) { + switch (Kind) { + default: assert(0 && "Unknown GC point kind"); + case GC::Loop: return "loop"; + case GC::Return: return "return"; + case GC::PreCall: return "pre-call"; + case GC::PostCall: return "post-call"; + } +} + +bool Printer::runOnMachineFunction(MachineFunction &MF) { + if (CollectorMetadata *FD = + getAnalysis<CollectorModuleMetadata>().get(MF.getFunction())) { + + OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; + for (CollectorMetadata::roots_iterator RI = FD->roots_begin(), + RE = FD->roots_end(); + RI != RE; ++RI) + OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; + + OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n"; + for (CollectorMetadata::iterator PI = FD->begin(), + PE = FD->end(); PI != PE; ++PI) { + + OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; + + for (CollectorMetadata::live_iterator RI = FD->live_begin(PI), + RE = FD->live_end(PI);;) { + OS << " " << RI->Num; + if (++RI == RE) + break; + OS << ","; + } + + OS << " }\n"; + } + } + + return false; +} + +// ----------------------------------------------------------------------------- + +char Deleter::ID = 0; + +Pass *llvm::createCollectorMetadataDeleter() { + return new Deleter(); +} + +Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {} + +const char *Deleter::getPassName() const { + return "Delete Garbage Collector Information"; +} + +void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<CollectorModuleMetadata>(); +} + +bool Deleter::runOnMachineFunction(MachineFunction &MF) { + return false; +} + +bool Deleter::doFinalization(Module &M) { + getAnalysis<CollectorModuleMetadata>().clear(); + return false; +} |