aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CollectorMetadata.cpp
diff options
context:
space:
mode:
authorGordon Henriksen <gordonhenriksen@mac.com>2007-09-27 22:18:46 +0000
committerGordon Henriksen <gordonhenriksen@mac.com>2007-09-27 22:18:46 +0000
commitfc3282221f90c626d80292327213e2badc3de86b (patch)
tree6eaec6aefedd7e70c0aed68ecee6f33775f7f5e7 /lib/CodeGen/CollectorMetadata.cpp
parent3f2d9ec186ce25b19bb36ae54eaee025150058fd (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.cpp185
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;
+}