1f22ef01cSRoman Divacky //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
10f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfo.h"
11f22ef01cSRoman Divacky 
12f22ef01cSRoman Divacky #include "llvm/Constants.h"
13f22ef01cSRoman Divacky #include "llvm/DerivedTypes.h"
14f22ef01cSRoman Divacky #include "llvm/GlobalVariable.h"
15f22ef01cSRoman Divacky #include "llvm/Module.h"
16f22ef01cSRoman Divacky #include "llvm/Analysis/ValueTracking.h"
17f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunctionPass.h"
18f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
19f22ef01cSRoman Divacky #include "llvm/CodeGen/Passes.h"
206122f3e6SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
21f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h"
22f22ef01cSRoman Divacky #include "llvm/ADT/PointerUnion.h"
23f22ef01cSRoman Divacky #include "llvm/Support/Dwarf.h"
24f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
25f22ef01cSRoman Divacky using namespace llvm;
26f22ef01cSRoman Divacky using namespace llvm::dwarf;
27f22ef01cSRoman Divacky 
28f22ef01cSRoman Divacky // Handle the Pass registration stuff necessary to use TargetData's.
29e580952dSDimitry Andric INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
302754fe60SDimitry Andric                 "Machine Module Information", false, false)
31f22ef01cSRoman Divacky char MachineModuleInfo::ID = 0;
32f22ef01cSRoman Divacky 
33f22ef01cSRoman Divacky // Out of line virtual method.
34f22ef01cSRoman Divacky MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
35f22ef01cSRoman Divacky 
36f22ef01cSRoman Divacky namespace llvm {
37f22ef01cSRoman Divacky class MMIAddrLabelMapCallbackPtr : CallbackVH {
38f22ef01cSRoman Divacky   MMIAddrLabelMap *Map;
39f22ef01cSRoman Divacky public:
40f22ef01cSRoman Divacky   MMIAddrLabelMapCallbackPtr() : Map(0) {}
41f22ef01cSRoman Divacky   MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(0) {}
42f22ef01cSRoman Divacky 
43f22ef01cSRoman Divacky   void setPtr(BasicBlock *BB) {
44f22ef01cSRoman Divacky     ValueHandleBase::operator=(BB);
45f22ef01cSRoman Divacky   }
46f22ef01cSRoman Divacky 
47f22ef01cSRoman Divacky   void setMap(MMIAddrLabelMap *map) { Map = map; }
48f22ef01cSRoman Divacky 
49f22ef01cSRoman Divacky   virtual void deleted();
50f22ef01cSRoman Divacky   virtual void allUsesReplacedWith(Value *V2);
51f22ef01cSRoman Divacky };
52f22ef01cSRoman Divacky 
53f22ef01cSRoman Divacky class MMIAddrLabelMap {
54f22ef01cSRoman Divacky   MCContext &Context;
55f22ef01cSRoman Divacky   struct AddrLabelSymEntry {
56f22ef01cSRoman Divacky     /// Symbols - The symbols for the label.  This is a pointer union that is
57f22ef01cSRoman Divacky     /// either one symbol (the common case) or a list of symbols.
58f22ef01cSRoman Divacky     PointerUnion<MCSymbol *, std::vector<MCSymbol*>*> Symbols;
59f22ef01cSRoman Divacky 
60f22ef01cSRoman Divacky     Function *Fn;   // The containing function of the BasicBlock.
61f22ef01cSRoman Divacky     unsigned Index; // The index in BBCallbacks for the BasicBlock.
62f22ef01cSRoman Divacky   };
63f22ef01cSRoman Divacky 
64f22ef01cSRoman Divacky   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
65f22ef01cSRoman Divacky 
66f22ef01cSRoman Divacky   /// BBCallbacks - Callbacks for the BasicBlock's that we have entries for.  We
67f22ef01cSRoman Divacky   /// use this so we get notified if a block is deleted or RAUWd.
68f22ef01cSRoman Divacky   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
69f22ef01cSRoman Divacky 
70f22ef01cSRoman Divacky   /// DeletedAddrLabelsNeedingEmission - This is a per-function list of symbols
71f22ef01cSRoman Divacky   /// whose corresponding BasicBlock got deleted.  These symbols need to be
72f22ef01cSRoman Divacky   /// emitted at some point in the file, so AsmPrinter emits them after the
73f22ef01cSRoman Divacky   /// function body.
74f22ef01cSRoman Divacky   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
75f22ef01cSRoman Divacky     DeletedAddrLabelsNeedingEmission;
76f22ef01cSRoman Divacky public:
77f22ef01cSRoman Divacky 
78f22ef01cSRoman Divacky   MMIAddrLabelMap(MCContext &context) : Context(context) {}
79f22ef01cSRoman Divacky   ~MMIAddrLabelMap() {
80f22ef01cSRoman Divacky     assert(DeletedAddrLabelsNeedingEmission.empty() &&
81f22ef01cSRoman Divacky            "Some labels for deleted blocks never got emitted");
82f22ef01cSRoman Divacky 
83f22ef01cSRoman Divacky     // Deallocate any of the 'list of symbols' case.
84f22ef01cSRoman Divacky     for (DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry>::iterator
85f22ef01cSRoman Divacky          I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I)
86f22ef01cSRoman Divacky       if (I->second.Symbols.is<std::vector<MCSymbol*>*>())
87f22ef01cSRoman Divacky         delete I->second.Symbols.get<std::vector<MCSymbol*>*>();
88f22ef01cSRoman Divacky   }
89f22ef01cSRoman Divacky 
90f22ef01cSRoman Divacky   MCSymbol *getAddrLabelSymbol(BasicBlock *BB);
91f22ef01cSRoman Divacky   std::vector<MCSymbol*> getAddrLabelSymbolToEmit(BasicBlock *BB);
92f22ef01cSRoman Divacky 
93f22ef01cSRoman Divacky   void takeDeletedSymbolsForFunction(Function *F,
94f22ef01cSRoman Divacky                                      std::vector<MCSymbol*> &Result);
95f22ef01cSRoman Divacky 
96f22ef01cSRoman Divacky   void UpdateForDeletedBlock(BasicBlock *BB);
97f22ef01cSRoman Divacky   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
98f22ef01cSRoman Divacky };
99f22ef01cSRoman Divacky }
100f22ef01cSRoman Divacky 
101f22ef01cSRoman Divacky MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) {
102f22ef01cSRoman Divacky   assert(BB->hasAddressTaken() &&
103f22ef01cSRoman Divacky          "Shouldn't get label for block without address taken");
104f22ef01cSRoman Divacky   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
105f22ef01cSRoman Divacky 
106f22ef01cSRoman Divacky   // If we already had an entry for this block, just return it.
107f22ef01cSRoman Divacky   if (!Entry.Symbols.isNull()) {
108f22ef01cSRoman Divacky     assert(BB->getParent() == Entry.Fn && "Parent changed");
109f22ef01cSRoman Divacky     if (Entry.Symbols.is<MCSymbol*>())
110f22ef01cSRoman Divacky       return Entry.Symbols.get<MCSymbol*>();
111f22ef01cSRoman Divacky     return (*Entry.Symbols.get<std::vector<MCSymbol*>*>())[0];
112f22ef01cSRoman Divacky   }
113f22ef01cSRoman Divacky 
114f22ef01cSRoman Divacky   // Otherwise, this is a new entry, create a new symbol for it and add an
115f22ef01cSRoman Divacky   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
116f22ef01cSRoman Divacky   BBCallbacks.push_back(BB);
117f22ef01cSRoman Divacky   BBCallbacks.back().setMap(this);
118f22ef01cSRoman Divacky   Entry.Index = BBCallbacks.size()-1;
119f22ef01cSRoman Divacky   Entry.Fn = BB->getParent();
120f22ef01cSRoman Divacky   MCSymbol *Result = Context.CreateTempSymbol();
121f22ef01cSRoman Divacky   Entry.Symbols = Result;
122f22ef01cSRoman Divacky   return Result;
123f22ef01cSRoman Divacky }
124f22ef01cSRoman Divacky 
125f22ef01cSRoman Divacky std::vector<MCSymbol*>
126f22ef01cSRoman Divacky MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
127f22ef01cSRoman Divacky   assert(BB->hasAddressTaken() &&
128f22ef01cSRoman Divacky          "Shouldn't get label for block without address taken");
129f22ef01cSRoman Divacky   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
130f22ef01cSRoman Divacky 
131f22ef01cSRoman Divacky   std::vector<MCSymbol*> Result;
132f22ef01cSRoman Divacky 
133f22ef01cSRoman Divacky   // If we already had an entry for this block, just return it.
134f22ef01cSRoman Divacky   if (Entry.Symbols.isNull())
135f22ef01cSRoman Divacky     Result.push_back(getAddrLabelSymbol(BB));
136f22ef01cSRoman Divacky   else if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>())
137f22ef01cSRoman Divacky     Result.push_back(Sym);
138f22ef01cSRoman Divacky   else
139f22ef01cSRoman Divacky     Result = *Entry.Symbols.get<std::vector<MCSymbol*>*>();
140f22ef01cSRoman Divacky   return Result;
141f22ef01cSRoman Divacky }
142f22ef01cSRoman Divacky 
143f22ef01cSRoman Divacky 
144f22ef01cSRoman Divacky /// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
145f22ef01cSRoman Divacky /// them.
146f22ef01cSRoman Divacky void MMIAddrLabelMap::
147f22ef01cSRoman Divacky takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
148f22ef01cSRoman Divacky   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
149f22ef01cSRoman Divacky     DeletedAddrLabelsNeedingEmission.find(F);
150f22ef01cSRoman Divacky 
151f22ef01cSRoman Divacky   // If there are no entries for the function, just return.
152f22ef01cSRoman Divacky   if (I == DeletedAddrLabelsNeedingEmission.end()) return;
153f22ef01cSRoman Divacky 
154f22ef01cSRoman Divacky   // Otherwise, take the list.
155f22ef01cSRoman Divacky   std::swap(Result, I->second);
156f22ef01cSRoman Divacky   DeletedAddrLabelsNeedingEmission.erase(I);
157f22ef01cSRoman Divacky }
158f22ef01cSRoman Divacky 
159f22ef01cSRoman Divacky 
160f22ef01cSRoman Divacky void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
161f22ef01cSRoman Divacky   // If the block got deleted, there is no need for the symbol.  If the symbol
162f22ef01cSRoman Divacky   // was already emitted, we can just forget about it, otherwise we need to
163f22ef01cSRoman Divacky   // queue it up for later emission when the function is output.
164f22ef01cSRoman Divacky   AddrLabelSymEntry Entry = AddrLabelSymbols[BB];
165f22ef01cSRoman Divacky   AddrLabelSymbols.erase(BB);
166f22ef01cSRoman Divacky   assert(!Entry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
167f22ef01cSRoman Divacky   BBCallbacks[Entry.Index] = 0;  // Clear the callback.
168f22ef01cSRoman Divacky 
169f22ef01cSRoman Divacky   assert((BB->getParent() == 0 || BB->getParent() == Entry.Fn) &&
170f22ef01cSRoman Divacky          "Block/parent mismatch");
171f22ef01cSRoman Divacky 
172f22ef01cSRoman Divacky   // Handle both the single and the multiple symbols cases.
173f22ef01cSRoman Divacky   if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>()) {
174f22ef01cSRoman Divacky     if (Sym->isDefined())
175f22ef01cSRoman Divacky       return;
176f22ef01cSRoman Divacky 
177f22ef01cSRoman Divacky     // If the block is not yet defined, we need to emit it at the end of the
178f22ef01cSRoman Divacky     // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
179f22ef01cSRoman Divacky     // for the containing Function.  Since the block is being deleted, its
180f22ef01cSRoman Divacky     // parent may already be removed, we have to get the function from 'Entry'.
181f22ef01cSRoman Divacky     DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
182f22ef01cSRoman Divacky   } else {
183f22ef01cSRoman Divacky     std::vector<MCSymbol*> *Syms = Entry.Symbols.get<std::vector<MCSymbol*>*>();
184f22ef01cSRoman Divacky 
185f22ef01cSRoman Divacky     for (unsigned i = 0, e = Syms->size(); i != e; ++i) {
186f22ef01cSRoman Divacky       MCSymbol *Sym = (*Syms)[i];
187f22ef01cSRoman Divacky       if (Sym->isDefined()) continue;  // Ignore already emitted labels.
188f22ef01cSRoman Divacky 
189f22ef01cSRoman Divacky       // If the block is not yet defined, we need to emit it at the end of the
190f22ef01cSRoman Divacky       // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
191f22ef01cSRoman Divacky       // for the containing Function.  Since the block is being deleted, its
192f22ef01cSRoman Divacky       // parent may already be removed, we have to get the function from
193f22ef01cSRoman Divacky       // 'Entry'.
194f22ef01cSRoman Divacky       DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
195f22ef01cSRoman Divacky     }
196f22ef01cSRoman Divacky 
197f22ef01cSRoman Divacky     // The entry is deleted, free the memory associated with the symbol list.
198f22ef01cSRoman Divacky     delete Syms;
199f22ef01cSRoman Divacky   }
200f22ef01cSRoman Divacky }
201f22ef01cSRoman Divacky 
202f22ef01cSRoman Divacky void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
203f22ef01cSRoman Divacky   // Get the entry for the RAUW'd block and remove it from our map.
204f22ef01cSRoman Divacky   AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old];
205f22ef01cSRoman Divacky   AddrLabelSymbols.erase(Old);
206f22ef01cSRoman Divacky   assert(!OldEntry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
207f22ef01cSRoman Divacky 
208f22ef01cSRoman Divacky   AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
209f22ef01cSRoman Divacky 
210f22ef01cSRoman Divacky   // If New is not address taken, just move our symbol over to it.
211f22ef01cSRoman Divacky   if (NewEntry.Symbols.isNull()) {
212f22ef01cSRoman Divacky     BBCallbacks[OldEntry.Index].setPtr(New);    // Update the callback.
213f22ef01cSRoman Divacky     NewEntry = OldEntry;     // Set New's entry.
214f22ef01cSRoman Divacky     return;
215f22ef01cSRoman Divacky   }
216f22ef01cSRoman Divacky 
217f22ef01cSRoman Divacky   BBCallbacks[OldEntry.Index] = 0;    // Update the callback.
218f22ef01cSRoman Divacky 
219f22ef01cSRoman Divacky   // Otherwise, we need to add the old symbol to the new block's set.  If it is
220f22ef01cSRoman Divacky   // just a single entry, upgrade it to a symbol list.
221f22ef01cSRoman Divacky   if (MCSymbol *PrevSym = NewEntry.Symbols.dyn_cast<MCSymbol*>()) {
222f22ef01cSRoman Divacky     std::vector<MCSymbol*> *SymList = new std::vector<MCSymbol*>();
223f22ef01cSRoman Divacky     SymList->push_back(PrevSym);
224f22ef01cSRoman Divacky     NewEntry.Symbols = SymList;
225f22ef01cSRoman Divacky   }
226f22ef01cSRoman Divacky 
227f22ef01cSRoman Divacky   std::vector<MCSymbol*> *SymList =
228f22ef01cSRoman Divacky     NewEntry.Symbols.get<std::vector<MCSymbol*>*>();
229f22ef01cSRoman Divacky 
230f22ef01cSRoman Divacky   // If the old entry was a single symbol, add it.
231f22ef01cSRoman Divacky   if (MCSymbol *Sym = OldEntry.Symbols.dyn_cast<MCSymbol*>()) {
232f22ef01cSRoman Divacky     SymList->push_back(Sym);
233f22ef01cSRoman Divacky     return;
234f22ef01cSRoman Divacky   }
235f22ef01cSRoman Divacky 
236f22ef01cSRoman Divacky   // Otherwise, concatenate the list.
237f22ef01cSRoman Divacky   std::vector<MCSymbol*> *Syms =OldEntry.Symbols.get<std::vector<MCSymbol*>*>();
238f22ef01cSRoman Divacky   SymList->insert(SymList->end(), Syms->begin(), Syms->end());
239f22ef01cSRoman Divacky   delete Syms;
240f22ef01cSRoman Divacky }
241f22ef01cSRoman Divacky 
242f22ef01cSRoman Divacky 
243f22ef01cSRoman Divacky void MMIAddrLabelMapCallbackPtr::deleted() {
244f22ef01cSRoman Divacky   Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
245f22ef01cSRoman Divacky }
246f22ef01cSRoman Divacky 
247f22ef01cSRoman Divacky void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
248f22ef01cSRoman Divacky   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
249f22ef01cSRoman Divacky }
250f22ef01cSRoman Divacky 
251f22ef01cSRoman Divacky 
252f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
253f22ef01cSRoman Divacky 
2542754fe60SDimitry Andric MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI,
2556122f3e6SDimitry Andric                                      const MCRegisterInfo &MRI,
2566122f3e6SDimitry Andric                                      const MCObjectFileInfo *MOFI)
2576122f3e6SDimitry Andric   : ImmutablePass(ID), Context(MAI, MRI, MOFI),
2586122f3e6SDimitry Andric     ObjFileMMI(0), CompactUnwindEncoding(0), CurCallSite(0), CallsEHReturn(0),
2596122f3e6SDimitry Andric     CallsUnwindInit(0), DbgInfoAvailable(false),
260dff0c46cSDimitry Andric     UsesVAFloatArgument(false) {
2612754fe60SDimitry Andric   initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
262f22ef01cSRoman Divacky   // Always emit some info, by default "no personality" info.
263f22ef01cSRoman Divacky   Personalities.push_back(NULL);
264f22ef01cSRoman Divacky   AddrLabelSymbols = 0;
265f22ef01cSRoman Divacky   TheModule = 0;
266f22ef01cSRoman Divacky }
267f22ef01cSRoman Divacky 
268f22ef01cSRoman Divacky MachineModuleInfo::MachineModuleInfo()
2696122f3e6SDimitry Andric   : ImmutablePass(ID),
2706122f3e6SDimitry Andric     Context(*(MCAsmInfo*)0, *(MCRegisterInfo*)0, (MCObjectFileInfo*)0) {
271dff0c46cSDimitry Andric   llvm_unreachable("This MachineModuleInfo constructor should never be called, "
272dff0c46cSDimitry Andric                    "MMI should always be explicitly constructed by "
273dff0c46cSDimitry Andric                    "LLVMTargetMachine");
274f22ef01cSRoman Divacky }
275f22ef01cSRoman Divacky 
276f22ef01cSRoman Divacky MachineModuleInfo::~MachineModuleInfo() {
277f22ef01cSRoman Divacky   delete ObjFileMMI;
278f22ef01cSRoman Divacky 
279f22ef01cSRoman Divacky   // FIXME: Why isn't doFinalization being called??
280f22ef01cSRoman Divacky   //assert(AddrLabelSymbols == 0 && "doFinalization not called");
281f22ef01cSRoman Divacky   delete AddrLabelSymbols;
282f22ef01cSRoman Divacky   AddrLabelSymbols = 0;
283f22ef01cSRoman Divacky }
284f22ef01cSRoman Divacky 
285f22ef01cSRoman Divacky /// doInitialization - Initialize the state for a new module.
286f22ef01cSRoman Divacky ///
287f22ef01cSRoman Divacky bool MachineModuleInfo::doInitialization() {
288f22ef01cSRoman Divacky   assert(AddrLabelSymbols == 0 && "Improperly initialized");
289f22ef01cSRoman Divacky   return false;
290f22ef01cSRoman Divacky }
291f22ef01cSRoman Divacky 
292f22ef01cSRoman Divacky /// doFinalization - Tear down the state after completion of a module.
293f22ef01cSRoman Divacky ///
294f22ef01cSRoman Divacky bool MachineModuleInfo::doFinalization() {
295f22ef01cSRoman Divacky   delete AddrLabelSymbols;
296f22ef01cSRoman Divacky   AddrLabelSymbols = 0;
297f22ef01cSRoman Divacky   return false;
298f22ef01cSRoman Divacky }
299f22ef01cSRoman Divacky 
300f22ef01cSRoman Divacky /// EndFunction - Discard function meta information.
301f22ef01cSRoman Divacky ///
302f22ef01cSRoman Divacky void MachineModuleInfo::EndFunction() {
303f22ef01cSRoman Divacky   // Clean up frame info.
304f22ef01cSRoman Divacky   FrameMoves.clear();
305f22ef01cSRoman Divacky 
306f22ef01cSRoman Divacky   // Clean up exception info.
307f22ef01cSRoman Divacky   LandingPads.clear();
308f22ef01cSRoman Divacky   CallSiteMap.clear();
309f22ef01cSRoman Divacky   TypeInfos.clear();
310f22ef01cSRoman Divacky   FilterIds.clear();
311f22ef01cSRoman Divacky   FilterEnds.clear();
312f22ef01cSRoman Divacky   CallsEHReturn = 0;
313f22ef01cSRoman Divacky   CallsUnwindInit = 0;
3146122f3e6SDimitry Andric   CompactUnwindEncoding = 0;
315f22ef01cSRoman Divacky   VariableDbgInfo.clear();
316f22ef01cSRoman Divacky }
317f22ef01cSRoman Divacky 
318f22ef01cSRoman Divacky /// AnalyzeModule - Scan the module for global debug information.
319f22ef01cSRoman Divacky ///
320f22ef01cSRoman Divacky void MachineModuleInfo::AnalyzeModule(const Module &M) {
321f22ef01cSRoman Divacky   // Insert functions in the llvm.used array (but not llvm.compiler.used) into
322f22ef01cSRoman Divacky   // UsedFunctions.
323f22ef01cSRoman Divacky   const GlobalVariable *GV = M.getGlobalVariable("llvm.used");
324f22ef01cSRoman Divacky   if (!GV || !GV->hasInitializer()) return;
325f22ef01cSRoman Divacky 
326f22ef01cSRoman Divacky   // Should be an array of 'i8*'.
327f22ef01cSRoman Divacky   const ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
328f22ef01cSRoman Divacky   if (InitList == 0) return;
329f22ef01cSRoman Divacky 
330f22ef01cSRoman Divacky   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
331f22ef01cSRoman Divacky     if (const Function *F =
332f22ef01cSRoman Divacky           dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
333f22ef01cSRoman Divacky       UsedFunctions.insert(F);
334f22ef01cSRoman Divacky }
335f22ef01cSRoman Divacky 
336f22ef01cSRoman Divacky //===- Address of Block Management ----------------------------------------===//
337f22ef01cSRoman Divacky 
338f22ef01cSRoman Divacky 
339f22ef01cSRoman Divacky /// getAddrLabelSymbol - Return the symbol to be used for the specified basic
340f22ef01cSRoman Divacky /// block when its address is taken.  This cannot be its normal LBB label
341f22ef01cSRoman Divacky /// because the block may be accessed outside its containing function.
342f22ef01cSRoman Divacky MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) {
343f22ef01cSRoman Divacky   // Lazily create AddrLabelSymbols.
344f22ef01cSRoman Divacky   if (AddrLabelSymbols == 0)
345f22ef01cSRoman Divacky     AddrLabelSymbols = new MMIAddrLabelMap(Context);
346f22ef01cSRoman Divacky   return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
347f22ef01cSRoman Divacky }
348f22ef01cSRoman Divacky 
349f22ef01cSRoman Divacky /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
350f22ef01cSRoman Divacky /// basic block when its address is taken.  If other blocks were RAUW'd to
351f22ef01cSRoman Divacky /// this one, we may have to emit them as well, return the whole set.
352f22ef01cSRoman Divacky std::vector<MCSymbol*> MachineModuleInfo::
353f22ef01cSRoman Divacky getAddrLabelSymbolToEmit(const BasicBlock *BB) {
354f22ef01cSRoman Divacky   // Lazily create AddrLabelSymbols.
355f22ef01cSRoman Divacky   if (AddrLabelSymbols == 0)
356f22ef01cSRoman Divacky     AddrLabelSymbols = new MMIAddrLabelMap(Context);
357f22ef01cSRoman Divacky  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
358f22ef01cSRoman Divacky }
359f22ef01cSRoman Divacky 
360f22ef01cSRoman Divacky 
361f22ef01cSRoman Divacky /// takeDeletedSymbolsForFunction - If the specified function has had any
362f22ef01cSRoman Divacky /// references to address-taken blocks generated, but the block got deleted,
363f22ef01cSRoman Divacky /// return the symbol now so we can emit it.  This prevents emitting a
364f22ef01cSRoman Divacky /// reference to a symbol that has no definition.
365f22ef01cSRoman Divacky void MachineModuleInfo::
366f22ef01cSRoman Divacky takeDeletedSymbolsForFunction(const Function *F,
367f22ef01cSRoman Divacky                               std::vector<MCSymbol*> &Result) {
368f22ef01cSRoman Divacky   // If no blocks have had their addresses taken, we're done.
369f22ef01cSRoman Divacky   if (AddrLabelSymbols == 0) return;
370f22ef01cSRoman Divacky   return AddrLabelSymbols->
371f22ef01cSRoman Divacky      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
372f22ef01cSRoman Divacky }
373f22ef01cSRoman Divacky 
374f22ef01cSRoman Divacky //===- EH -----------------------------------------------------------------===//
375f22ef01cSRoman Divacky 
376f22ef01cSRoman Divacky /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
377f22ef01cSRoman Divacky /// specified MachineBasicBlock.
378f22ef01cSRoman Divacky LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
379f22ef01cSRoman Divacky     (MachineBasicBlock *LandingPad) {
380f22ef01cSRoman Divacky   unsigned N = LandingPads.size();
381f22ef01cSRoman Divacky   for (unsigned i = 0; i < N; ++i) {
382f22ef01cSRoman Divacky     LandingPadInfo &LP = LandingPads[i];
383f22ef01cSRoman Divacky     if (LP.LandingPadBlock == LandingPad)
384f22ef01cSRoman Divacky       return LP;
385f22ef01cSRoman Divacky   }
386f22ef01cSRoman Divacky 
387f22ef01cSRoman Divacky   LandingPads.push_back(LandingPadInfo(LandingPad));
388f22ef01cSRoman Divacky   return LandingPads[N];
389f22ef01cSRoman Divacky }
390f22ef01cSRoman Divacky 
391f22ef01cSRoman Divacky /// addInvoke - Provide the begin and end labels of an invoke style call and
392f22ef01cSRoman Divacky /// associate it with a try landing pad block.
393f22ef01cSRoman Divacky void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
394f22ef01cSRoman Divacky                                   MCSymbol *BeginLabel, MCSymbol *EndLabel) {
395f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
396f22ef01cSRoman Divacky   LP.BeginLabels.push_back(BeginLabel);
397f22ef01cSRoman Divacky   LP.EndLabels.push_back(EndLabel);
398f22ef01cSRoman Divacky }
399f22ef01cSRoman Divacky 
400f22ef01cSRoman Divacky /// addLandingPad - Provide the label of a try LandingPad block.
401f22ef01cSRoman Divacky ///
402f22ef01cSRoman Divacky MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
403f22ef01cSRoman Divacky   MCSymbol *LandingPadLabel = Context.CreateTempSymbol();
404f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
405f22ef01cSRoman Divacky   LP.LandingPadLabel = LandingPadLabel;
406f22ef01cSRoman Divacky   return LandingPadLabel;
407f22ef01cSRoman Divacky }
408f22ef01cSRoman Divacky 
409f22ef01cSRoman Divacky /// addPersonality - Provide the personality function for the exception
410f22ef01cSRoman Divacky /// information.
411f22ef01cSRoman Divacky void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
412f22ef01cSRoman Divacky                                        const Function *Personality) {
413f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
414f22ef01cSRoman Divacky   LP.Personality = Personality;
415f22ef01cSRoman Divacky 
416f22ef01cSRoman Divacky   for (unsigned i = 0; i < Personalities.size(); ++i)
417f22ef01cSRoman Divacky     if (Personalities[i] == Personality)
418f22ef01cSRoman Divacky       return;
419f22ef01cSRoman Divacky 
420f22ef01cSRoman Divacky   // If this is the first personality we're adding go
421f22ef01cSRoman Divacky   // ahead and add it at the beginning.
422f22ef01cSRoman Divacky   if (Personalities[0] == NULL)
423f22ef01cSRoman Divacky     Personalities[0] = Personality;
424f22ef01cSRoman Divacky   else
425f22ef01cSRoman Divacky     Personalities.push_back(Personality);
426f22ef01cSRoman Divacky }
427f22ef01cSRoman Divacky 
428f22ef01cSRoman Divacky /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
429f22ef01cSRoman Divacky ///
4306122f3e6SDimitry Andric void MachineModuleInfo::
4316122f3e6SDimitry Andric addCatchTypeInfo(MachineBasicBlock *LandingPad,
4326122f3e6SDimitry Andric                  ArrayRef<const GlobalVariable *> TyInfo) {
433f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
434f22ef01cSRoman Divacky   for (unsigned N = TyInfo.size(); N; --N)
435f22ef01cSRoman Divacky     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
436f22ef01cSRoman Divacky }
437f22ef01cSRoman Divacky 
438f22ef01cSRoman Divacky /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
439f22ef01cSRoman Divacky ///
4406122f3e6SDimitry Andric void MachineModuleInfo::
4416122f3e6SDimitry Andric addFilterTypeInfo(MachineBasicBlock *LandingPad,
4426122f3e6SDimitry Andric                   ArrayRef<const GlobalVariable *> TyInfo) {
443f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
444f22ef01cSRoman Divacky   std::vector<unsigned> IdsInFilter(TyInfo.size());
445f22ef01cSRoman Divacky   for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
446f22ef01cSRoman Divacky     IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
447f22ef01cSRoman Divacky   LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
448f22ef01cSRoman Divacky }
449f22ef01cSRoman Divacky 
450f22ef01cSRoman Divacky /// addCleanup - Add a cleanup action for a landing pad.
451f22ef01cSRoman Divacky ///
452f22ef01cSRoman Divacky void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
453f22ef01cSRoman Divacky   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
454f22ef01cSRoman Divacky   LP.TypeIds.push_back(0);
455f22ef01cSRoman Divacky }
456f22ef01cSRoman Divacky 
457f22ef01cSRoman Divacky /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
458f22ef01cSRoman Divacky /// pads.
459f22ef01cSRoman Divacky void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
460f22ef01cSRoman Divacky   for (unsigned i = 0; i != LandingPads.size(); ) {
461f22ef01cSRoman Divacky     LandingPadInfo &LandingPad = LandingPads[i];
462f22ef01cSRoman Divacky     if (LandingPad.LandingPadLabel &&
463f22ef01cSRoman Divacky         !LandingPad.LandingPadLabel->isDefined() &&
464f22ef01cSRoman Divacky         (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
465f22ef01cSRoman Divacky       LandingPad.LandingPadLabel = 0;
466f22ef01cSRoman Divacky 
467f22ef01cSRoman Divacky     // Special case: we *should* emit LPs with null LP MBB. This indicates
468f22ef01cSRoman Divacky     // "nounwind" case.
469f22ef01cSRoman Divacky     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
470f22ef01cSRoman Divacky       LandingPads.erase(LandingPads.begin() + i);
471f22ef01cSRoman Divacky       continue;
472f22ef01cSRoman Divacky     }
473f22ef01cSRoman Divacky 
474f22ef01cSRoman Divacky     for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
475f22ef01cSRoman Divacky       MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
476f22ef01cSRoman Divacky       MCSymbol *EndLabel = LandingPad.EndLabels[j];
477f22ef01cSRoman Divacky       if ((BeginLabel->isDefined() ||
478f22ef01cSRoman Divacky            (LPMap && (*LPMap)[BeginLabel] != 0)) &&
479f22ef01cSRoman Divacky           (EndLabel->isDefined() ||
480f22ef01cSRoman Divacky            (LPMap && (*LPMap)[EndLabel] != 0))) continue;
481f22ef01cSRoman Divacky 
482f22ef01cSRoman Divacky       LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
483f22ef01cSRoman Divacky       LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
484f22ef01cSRoman Divacky       --j, --e;
485f22ef01cSRoman Divacky     }
486f22ef01cSRoman Divacky 
487f22ef01cSRoman Divacky     // Remove landing pads with no try-ranges.
488f22ef01cSRoman Divacky     if (LandingPads[i].BeginLabels.empty()) {
489f22ef01cSRoman Divacky       LandingPads.erase(LandingPads.begin() + i);
490f22ef01cSRoman Divacky       continue;
491f22ef01cSRoman Divacky     }
492f22ef01cSRoman Divacky 
493f22ef01cSRoman Divacky     // If there is no landing pad, ensure that the list of typeids is empty.
494f22ef01cSRoman Divacky     // If the only typeid is a cleanup, this is the same as having no typeids.
495f22ef01cSRoman Divacky     if (!LandingPad.LandingPadBlock ||
496f22ef01cSRoman Divacky         (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
497f22ef01cSRoman Divacky       LandingPad.TypeIds.clear();
498f22ef01cSRoman Divacky     ++i;
499f22ef01cSRoman Divacky   }
500f22ef01cSRoman Divacky }
501f22ef01cSRoman Divacky 
5026122f3e6SDimitry Andric /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site
5036122f3e6SDimitry Andric /// indexes.
5046122f3e6SDimitry Andric void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
5056122f3e6SDimitry Andric                                               ArrayRef<unsigned> Sites) {
506dff0c46cSDimitry Andric   LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
5076122f3e6SDimitry Andric }
5086122f3e6SDimitry Andric 
509f22ef01cSRoman Divacky /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
510f22ef01cSRoman Divacky /// function wide.
511f22ef01cSRoman Divacky unsigned MachineModuleInfo::getTypeIDFor(const GlobalVariable *TI) {
512f22ef01cSRoman Divacky   for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
513f22ef01cSRoman Divacky     if (TypeInfos[i] == TI) return i + 1;
514f22ef01cSRoman Divacky 
515f22ef01cSRoman Divacky   TypeInfos.push_back(TI);
516f22ef01cSRoman Divacky   return TypeInfos.size();
517f22ef01cSRoman Divacky }
518f22ef01cSRoman Divacky 
519f22ef01cSRoman Divacky /// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
520f22ef01cSRoman Divacky /// function wide.
521f22ef01cSRoman Divacky int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
522f22ef01cSRoman Divacky   // If the new filter coincides with the tail of an existing filter, then
523f22ef01cSRoman Divacky   // re-use the existing filter.  Folding filters more than this requires
524f22ef01cSRoman Divacky   // re-ordering filters and/or their elements - probably not worth it.
525f22ef01cSRoman Divacky   for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
526f22ef01cSRoman Divacky        E = FilterEnds.end(); I != E; ++I) {
527f22ef01cSRoman Divacky     unsigned i = *I, j = TyIds.size();
528f22ef01cSRoman Divacky 
529f22ef01cSRoman Divacky     while (i && j)
530f22ef01cSRoman Divacky       if (FilterIds[--i] != TyIds[--j])
531f22ef01cSRoman Divacky         goto try_next;
532f22ef01cSRoman Divacky 
533f22ef01cSRoman Divacky     if (!j)
534f22ef01cSRoman Divacky       // The new filter coincides with range [i, end) of the existing filter.
535f22ef01cSRoman Divacky       return -(1 + i);
536f22ef01cSRoman Divacky 
537f22ef01cSRoman Divacky try_next:;
538f22ef01cSRoman Divacky   }
539f22ef01cSRoman Divacky 
540f22ef01cSRoman Divacky   // Add the new filter.
541f22ef01cSRoman Divacky   int FilterID = -(1 + FilterIds.size());
542f22ef01cSRoman Divacky   FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
543dff0c46cSDimitry Andric   FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
544f22ef01cSRoman Divacky   FilterEnds.push_back(FilterIds.size());
545f22ef01cSRoman Divacky   FilterIds.push_back(0); // terminator
546f22ef01cSRoman Divacky   return FilterID;
547f22ef01cSRoman Divacky }
548f22ef01cSRoman Divacky 
549f22ef01cSRoman Divacky /// getPersonality - Return the personality function for the current function.
550f22ef01cSRoman Divacky const Function *MachineModuleInfo::getPersonality() const {
551f22ef01cSRoman Divacky   // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
552f22ef01cSRoman Divacky   // function
553f22ef01cSRoman Divacky   return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
554f22ef01cSRoman Divacky }
555f22ef01cSRoman Divacky 
556f22ef01cSRoman Divacky /// getPersonalityIndex - Return unique index for current personality
557f22ef01cSRoman Divacky /// function. NULL/first personality function should always get zero index.
558f22ef01cSRoman Divacky unsigned MachineModuleInfo::getPersonalityIndex() const {
559f22ef01cSRoman Divacky   const Function* Personality = NULL;
560f22ef01cSRoman Divacky 
561f22ef01cSRoman Divacky   // Scan landing pads. If there is at least one non-NULL personality - use it.
562dff0c46cSDimitry Andric   for (unsigned i = 0, e = LandingPads.size(); i != e; ++i)
563f22ef01cSRoman Divacky     if (LandingPads[i].Personality) {
564f22ef01cSRoman Divacky       Personality = LandingPads[i].Personality;
565f22ef01cSRoman Divacky       break;
566f22ef01cSRoman Divacky     }
567f22ef01cSRoman Divacky 
568dff0c46cSDimitry Andric   for (unsigned i = 0, e = Personalities.size(); i < e; ++i) {
569f22ef01cSRoman Divacky     if (Personalities[i] == Personality)
570f22ef01cSRoman Divacky       return i;
571f22ef01cSRoman Divacky   }
572f22ef01cSRoman Divacky 
573f22ef01cSRoman Divacky   // This will happen if the current personality function is
574f22ef01cSRoman Divacky   // in the zero index.
575f22ef01cSRoman Divacky   return 0;
576f22ef01cSRoman Divacky }
577