f86ee04c9510b6e1c47b7d61af0e22805effd0e3
[oota-llvm.git] / lib / CodeGen / CollectorMetadata.cpp
1 //===-- 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
21 using namespace llvm;
22
23 namespace {
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
58 CollectorMetadata::CollectorMetadata(const Function &F)
59   : F(F), FrameSize(~0LL) {}
60
61 CollectorMetadata::~CollectorMetadata() {}
62
63 // -----------------------------------------------------------------------------
64
65 char CollectorModuleMetadata::ID = 0;
66
67 CollectorModuleMetadata::CollectorModuleMetadata()
68   : ImmutablePass((intptr_t)&ID) {}
69
70 CollectorModuleMetadata::~CollectorModuleMetadata() {
71   clear();
72 }
73
74 CollectorMetadata& 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
82 CollectorMetadata* 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
89 void 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
99 char Printer::ID = 0;
100
101 Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
102   return new Printer(OS);
103 }
104
105 Printer::Printer(std::ostream &OS)
106   : MachineFunctionPass(intptr_t(&ID)), OS(OS) {}
107
108 const char *Printer::getPassName() const {
109   return "Print Garbage Collector Information";
110 }
111
112 void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
113   MachineFunctionPass::getAnalysisUsage(AU);
114   AU.setPreservesAll();
115   AU.addRequired<CollectorModuleMetadata>();
116 }
117
118 static 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
128 bool 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
161 char Deleter::ID = 0;
162
163 Pass *llvm::createCollectorMetadataDeleter() {
164   return new Deleter();
165 }
166
167 Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {}
168
169 const char *Deleter::getPassName() const {
170   return "Delete Garbage Collector Information";
171 }
172
173 void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
174   AU.setPreservesAll();
175   AU.addRequired<CollectorModuleMetadata>();
176 }
177
178 bool Deleter::runOnMachineFunction(MachineFunction &MF) {
179   return false;
180 }
181
182 bool Deleter::doFinalization(Module &M) {
183   getAnalysis<CollectorModuleMetadata>().clear();
184   return false;
185 }