blob: f86ee04c9510b6e1c47b7d61af0e22805effd0e3 [file] [log] [blame]
Gordon Henriksenfc328222007-09-27 22:18:46 +00001//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Gordon Henriksen and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the CollectorMetadata and CollectorModuleMetadata
11// classes.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/CollectorMetadata.h"
16#include "llvm/CodeGen/MachineFrameInfo.h"
17#include "llvm/CodeGen/MachineFunctionPass.h"
18#include "llvm/Function.h"
19#include "llvm/Support/Compiler.h"
20
21using namespace llvm;
22
23namespace {
24
25 class VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
26 static char ID;
27 std::ostream &OS;
28
29 public:
30 Printer(std::ostream &OS = *cerr);
31
32 const char *getPassName() const;
33 void getAnalysisUsage(AnalysisUsage &AU) const;
34
35 bool runOnMachineFunction(MachineFunction &MF);
36 };
37
38 class VISIBILITY_HIDDEN Deleter : public MachineFunctionPass {
39 static char ID;
40
41 public:
42 Deleter();
43
44 const char *getPassName() const;
45 void getAnalysisUsage(AnalysisUsage &AU) const;
46
47 bool runOnMachineFunction(MachineFunction &MF);
48 bool doFinalization(Module &M);
49 };
50
51 RegisterPass<CollectorModuleMetadata>
52 X("collector-metadata", "Create Garbage Collector Module Metadata");
53
54}
55
56// -----------------------------------------------------------------------------
57
58CollectorMetadata::CollectorMetadata(const Function &F)
59 : F(F), FrameSize(~0LL) {}
60
61CollectorMetadata::~CollectorMetadata() {}
62
63// -----------------------------------------------------------------------------
64
65char CollectorModuleMetadata::ID = 0;
66
67CollectorModuleMetadata::CollectorModuleMetadata()
68 : ImmutablePass((intptr_t)&ID) {}
69
70CollectorModuleMetadata::~CollectorModuleMetadata() {
71 clear();
72}
73
74CollectorMetadata& CollectorModuleMetadata::insert(const Function *F) {
75 assert(Map.find(F) == Map.end() && "Function GC metadata already exists!");
76 CollectorMetadata *FMD = new CollectorMetadata(*F);
77 Functions.push_back(FMD);
78 Map[F] = FMD;
79 return *FMD;
80}
81
82CollectorMetadata* CollectorModuleMetadata::get(const Function *F) const {
83 map_type::iterator I = Map.find(F);
84 if (I == Map.end())
85 return 0;
86 return I->second;
87}
88
89void CollectorModuleMetadata::clear() {
90 for (iterator I = begin(), E = end(); I != E; ++I)
91 delete *I;
92
93 Functions.clear();
94 Map.clear();
95}
96
97// -----------------------------------------------------------------------------
98
99char Printer::ID = 0;
100
101Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
102 return new Printer(OS);
103}
104
105Printer::Printer(std::ostream &OS)
106 : MachineFunctionPass(intptr_t(&ID)), OS(OS) {}
107
108const char *Printer::getPassName() const {
109 return "Print Garbage Collector Information";
110}
111
112void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
113 MachineFunctionPass::getAnalysisUsage(AU);
114 AU.setPreservesAll();
115 AU.addRequired<CollectorModuleMetadata>();
116}
117
118static const char *DescKind(GC::PointKind Kind) {
119 switch (Kind) {
120 default: assert(0 && "Unknown GC point kind");
121 case GC::Loop: return "loop";
122 case GC::Return: return "return";
123 case GC::PreCall: return "pre-call";
124 case GC::PostCall: return "post-call";
125 }
126}
127
128bool Printer::runOnMachineFunction(MachineFunction &MF) {
129 if (CollectorMetadata *FD =
130 getAnalysis<CollectorModuleMetadata>().get(MF.getFunction())) {
131
132 OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
133 for (CollectorMetadata::roots_iterator RI = FD->roots_begin(),
134 RE = FD->roots_end();
135 RI != RE; ++RI)
136 OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
137
138 OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n";
139 for (CollectorMetadata::iterator PI = FD->begin(),
140 PE = FD->end(); PI != PE; ++PI) {
141
142 OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
143
144 for (CollectorMetadata::live_iterator RI = FD->live_begin(PI),
145 RE = FD->live_end(PI);;) {
146 OS << " " << RI->Num;
147 if (++RI == RE)
148 break;
149 OS << ",";
150 }
151
152 OS << " }\n";
153 }
154 }
155
156 return false;
157}
158
159// -----------------------------------------------------------------------------
160
161char Deleter::ID = 0;
162
163Pass *llvm::createCollectorMetadataDeleter() {
164 return new Deleter();
165}
166
167Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {}
168
169const char *Deleter::getPassName() const {
170 return "Delete Garbage Collector Information";
171}
172
173void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
174 AU.setPreservesAll();
175 AU.addRequired<CollectorModuleMetadata>();
176}
177
178bool Deleter::runOnMachineFunction(MachineFunction &MF) {
179 return false;
180}
181
182bool Deleter::doFinalization(Module &M) {
183 getAnalysis<CollectorModuleMetadata>().clear();
184 return false;
185}