Eliminate several more unnecessary intptr_t casts.
[oota-llvm.git] / lib / CodeGen / GCMetadata.cpp
1 //===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the GCFunctionInfo class and GCModuleInfo pass.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/CodeGen/GCMetadata.h"
15 #include "llvm/CodeGen/GCStrategy.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/Pass.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/Function.h"
20 #include "llvm/Support/Compiler.h"
21
22 using namespace llvm;
23
24 namespace {
25   
26   class VISIBILITY_HIDDEN Printer : public FunctionPass {
27     static char ID;
28     std::ostream &OS;
29     
30   public:
31     explicit Printer(std::ostream &OS = *cerr);
32     
33     const char *getPassName() const;
34     void getAnalysisUsage(AnalysisUsage &AU) const;
35     
36     bool runOnFunction(Function &F);
37   };
38   
39   class VISIBILITY_HIDDEN Deleter : public FunctionPass {
40     static char ID;
41     
42   public:
43     Deleter();
44     
45     const char *getPassName() const;
46     void getAnalysisUsage(AnalysisUsage &AU) const;
47     
48     bool runOnFunction(Function &F);
49     bool doFinalization(Module &M);
50   };
51   
52 }
53
54 static RegisterPass<GCModuleInfo>
55 X("collector-metadata", "Create Garbage Collector Module Metadata");
56
57 // -----------------------------------------------------------------------------
58
59 GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
60   : F(F), S(S), FrameSize(~0LL) {}
61
62 GCFunctionInfo::~GCFunctionInfo() {}
63
64 // -----------------------------------------------------------------------------
65
66 char GCModuleInfo::ID = 0;
67
68 GCModuleInfo::GCModuleInfo()
69   : ImmutablePass(&ID) {}
70
71 GCModuleInfo::~GCModuleInfo() {
72   clear();
73 }
74
75 GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
76                                               const std::string &Name) {
77   const char *Start = Name.c_str();
78   
79   strategy_map_type::iterator NMI =
80     StrategyMap.find(Start, Start + Name.size());
81   if (NMI != StrategyMap.end())
82     return NMI->getValue();
83   
84   for (GCRegistry::iterator I = GCRegistry::begin(),
85                             E = GCRegistry::end(); I != E; ++I) {
86     if (strcmp(Start, I->getName()) == 0) {
87       GCStrategy *S = I->instantiate();
88       S->M = M;
89       S->Name = Name;
90       StrategyMap.GetOrCreateValue(Start, Start + Name.size()).setValue(S);
91       StrategyList.push_back(S);
92       return S;
93     }
94   }
95   
96   cerr << "unsupported GC: " << Name << "\n";
97   abort();
98 }
99
100 GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
101   assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
102   assert(F.hasGC());
103   
104   finfo_map_type::iterator I = FInfoMap.find(&F);
105   if (I != FInfoMap.end())
106     return *I->second;
107   
108   GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
109   GCFunctionInfo *GFI = S->insertFunctionInfo(F);
110   FInfoMap[&F] = GFI;
111   return *GFI;
112 }
113
114 void GCModuleInfo::clear() {
115   FInfoMap.clear();
116   StrategyMap.clear();
117   
118   for (iterator I = begin(), E = end(); I != E; ++I)
119     delete *I;
120   StrategyList.clear();
121 }
122
123 // -----------------------------------------------------------------------------
124
125 char Printer::ID = 0;
126
127 FunctionPass *llvm::createGCInfoPrinter(std::ostream &OS) {
128   return new Printer(OS);
129 }
130
131 Printer::Printer(std::ostream &OS)
132   : FunctionPass(&ID), OS(OS) {}
133
134 const char *Printer::getPassName() const {
135   return "Print Garbage Collector Information";
136 }
137
138 void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
139   FunctionPass::getAnalysisUsage(AU);
140   AU.setPreservesAll();
141   AU.addRequired<GCModuleInfo>();
142 }
143
144 static const char *DescKind(GC::PointKind Kind) {
145   switch (Kind) {
146     default: assert(0 && "Unknown GC point kind");
147     case GC::Loop:     return "loop";
148     case GC::Return:   return "return";
149     case GC::PreCall:  return "pre-call";
150     case GC::PostCall: return "post-call";
151   }
152 }
153
154 bool Printer::runOnFunction(Function &F) {
155   if (!F.hasGC()) {
156     GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
157     
158     OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
159     for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
160                                         RE = FD->roots_end(); RI != RE; ++RI)
161       OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
162     
163     OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n";
164     for (GCFunctionInfo::iterator PI = FD->begin(),
165                                   PE = FD->end(); PI != PE; ++PI) {
166       
167       OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
168       
169       for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
170                                          RE = FD->live_end(PI);;) {
171         OS << " " << RI->Num;
172         if (++RI == RE)
173           break;
174         OS << ",";
175       }
176       
177       OS << " }\n";
178     }
179   }
180   
181   return false;
182 }
183
184 // -----------------------------------------------------------------------------
185
186 char Deleter::ID = 0;
187
188 FunctionPass *llvm::createGCInfoDeleter() {
189   return new Deleter();
190 }
191
192 Deleter::Deleter() : FunctionPass(&ID) {}
193
194 const char *Deleter::getPassName() const {
195   return "Delete Garbage Collector Information";
196 }
197
198 void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
199   AU.setPreservesAll();
200   AU.addRequired<GCModuleInfo>();
201 }
202
203 bool Deleter::runOnFunction(Function &MF) {
204   return false;
205 }
206
207 bool Deleter::doFinalization(Module &M) {
208   GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
209   assert(GMI && "Deleter didn't require GCModuleInfo?!");
210   GMI->clear();
211   return false;
212 }