xref: /llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp (revision 2b4c127531410e1c32d9480bb2daa7d53b87c16c)
1 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
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 #include "llvm/CodeGen/MachineModuleInfo.h"
11 #include "llvm/ADT/PointerUnion.h"
12 #include "llvm/ADT/TinyPtrVector.h"
13 #include "llvm/Analysis/EHPersonalities.h"
14 #include "llvm/Analysis/ValueTracking.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/MachineFunctionInitializer.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/GlobalVariable.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Support/Dwarf.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Target/TargetLoweringObjectFile.h"
28 #include "llvm/Target/TargetMachine.h"
29 using namespace llvm;
30 using namespace llvm::dwarf;
31 
32 // Handle the Pass registration stuff necessary to use DataLayout's.
33 INITIALIZE_TM_PASS(MachineModuleInfo, "machinemoduleinfo",
34                    "Machine Module Information", false, false)
35 char MachineModuleInfo::ID = 0;
36 
37 // Out of line virtual method.
38 MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
39 
40 namespace llvm {
41 class MMIAddrLabelMapCallbackPtr final : CallbackVH {
42   MMIAddrLabelMap *Map;
43 public:
44   MMIAddrLabelMapCallbackPtr() : Map(nullptr) {}
45   MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(nullptr) {}
46 
47   void setPtr(BasicBlock *BB) {
48     ValueHandleBase::operator=(BB);
49   }
50 
51   void setMap(MMIAddrLabelMap *map) { Map = map; }
52 
53   void deleted() override;
54   void allUsesReplacedWith(Value *V2) override;
55 };
56 
57 class MMIAddrLabelMap {
58   MCContext &Context;
59   struct AddrLabelSymEntry {
60     /// The symbols for the label.
61     TinyPtrVector<MCSymbol *> Symbols;
62 
63     Function *Fn;   // The containing function of the BasicBlock.
64     unsigned Index; // The index in BBCallbacks for the BasicBlock.
65   };
66 
67   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
68 
69   /// Callbacks for the BasicBlock's that we have entries for.  We use this so
70   /// we get notified if a block is deleted or RAUWd.
71   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
72 
73   /// This is a per-function list of symbols whose corresponding BasicBlock got
74   /// deleted.  These symbols need to be emitted at some point in the file, so
75   /// AsmPrinter emits them after the function body.
76   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
77     DeletedAddrLabelsNeedingEmission;
78 public:
79 
80   MMIAddrLabelMap(MCContext &context) : Context(context) {}
81   ~MMIAddrLabelMap() {
82     assert(DeletedAddrLabelsNeedingEmission.empty() &&
83            "Some labels for deleted blocks never got emitted");
84   }
85 
86   ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
87 
88   void takeDeletedSymbolsForFunction(Function *F,
89                                      std::vector<MCSymbol*> &Result);
90 
91   void UpdateForDeletedBlock(BasicBlock *BB);
92   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
93 };
94 }
95 
96 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
97   assert(BB->hasAddressTaken() &&
98          "Shouldn't get label for block without address taken");
99   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
100 
101   // If we already had an entry for this block, just return it.
102   if (!Entry.Symbols.empty()) {
103     assert(BB->getParent() == Entry.Fn && "Parent changed");
104     return Entry.Symbols;
105   }
106 
107   // Otherwise, this is a new entry, create a new symbol for it and add an
108   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
109   BBCallbacks.emplace_back(BB);
110   BBCallbacks.back().setMap(this);
111   Entry.Index = BBCallbacks.size() - 1;
112   Entry.Fn = BB->getParent();
113   Entry.Symbols.push_back(Context.createTempSymbol());
114   return Entry.Symbols;
115 }
116 
117 /// If we have any deleted symbols for F, return them.
118 void MMIAddrLabelMap::
119 takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
120   DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
121     DeletedAddrLabelsNeedingEmission.find(F);
122 
123   // If there are no entries for the function, just return.
124   if (I == DeletedAddrLabelsNeedingEmission.end()) return;
125 
126   // Otherwise, take the list.
127   std::swap(Result, I->second);
128   DeletedAddrLabelsNeedingEmission.erase(I);
129 }
130 
131 
132 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
133   // If the block got deleted, there is no need for the symbol.  If the symbol
134   // was already emitted, we can just forget about it, otherwise we need to
135   // queue it up for later emission when the function is output.
136   AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
137   AddrLabelSymbols.erase(BB);
138   assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
139   BBCallbacks[Entry.Index] = nullptr;  // Clear the callback.
140 
141   assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
142          "Block/parent mismatch");
143 
144   for (MCSymbol *Sym : Entry.Symbols) {
145     if (Sym->isDefined())
146       return;
147 
148     // If the block is not yet defined, we need to emit it at the end of the
149     // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list
150     // for the containing Function.  Since the block is being deleted, its
151     // parent may already be removed, we have to get the function from 'Entry'.
152     DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
153   }
154 }
155 
156 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
157   // Get the entry for the RAUW'd block and remove it from our map.
158   AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
159   AddrLabelSymbols.erase(Old);
160   assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
161 
162   AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
163 
164   // If New is not address taken, just move our symbol over to it.
165   if (NewEntry.Symbols.empty()) {
166     BBCallbacks[OldEntry.Index].setPtr(New);    // Update the callback.
167     NewEntry = std::move(OldEntry);             // Set New's entry.
168     return;
169   }
170 
171   BBCallbacks[OldEntry.Index] = nullptr;    // Update the callback.
172 
173   // Otherwise, we need to add the old symbols to the new block's set.
174   NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(),
175                           OldEntry.Symbols.end());
176 }
177 
178 
179 void MMIAddrLabelMapCallbackPtr::deleted() {
180   Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
181 }
182 
183 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
184   Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
185 }
186 
187 
188 //===----------------------------------------------------------------------===//
189 
190 MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM)
191   : ImmutablePass(ID), TM(*TM),
192     Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
193             TM->getObjFileLowering(), nullptr, false) {
194   initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
195 }
196 
197 MachineModuleInfo::~MachineModuleInfo() {
198 }
199 
200 bool MachineModuleInfo::doInitialization(Module &M) {
201 
202   ObjFileMMI = nullptr;
203   CurCallSite = 0;
204   CallsEHReturn = false;
205   CallsUnwindInit = false;
206   HasEHFunclets = false;
207   DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
208   PersonalityTypeCache = EHPersonality::Unknown;
209   AddrLabelSymbols = nullptr;
210   TheModule = &M;
211 
212   return false;
213 }
214 
215 bool MachineModuleInfo::doFinalization(Module &M) {
216 
217   Personalities.clear();
218 
219   delete AddrLabelSymbols;
220   AddrLabelSymbols = nullptr;
221 
222   Context.reset();
223 
224   delete ObjFileMMI;
225   ObjFileMMI = nullptr;
226 
227   return false;
228 }
229 
230 void MachineModuleInfo::EndFunction() {
231   // Clean up frame info.
232   FrameInstructions.clear();
233 
234   // Clean up exception info.
235   LandingPads.clear();
236   PersonalityTypeCache = EHPersonality::Unknown;
237   CallSiteMap.clear();
238   TypeInfos.clear();
239   FilterIds.clear();
240   FilterEnds.clear();
241   CallsEHReturn = false;
242   CallsUnwindInit = false;
243   HasEHFunclets = false;
244   VariableDbgInfos.clear();
245 }
246 
247 //===- Address of Block Management ----------------------------------------===//
248 
249 ArrayRef<MCSymbol *>
250 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
251   // Lazily create AddrLabelSymbols.
252   if (!AddrLabelSymbols)
253     AddrLabelSymbols = new MMIAddrLabelMap(Context);
254  return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB));
255 }
256 
257 void MachineModuleInfo::
258 takeDeletedSymbolsForFunction(const Function *F,
259                               std::vector<MCSymbol*> &Result) {
260   // If no blocks have had their addresses taken, we're done.
261   if (!AddrLabelSymbols) return;
262   return AddrLabelSymbols->
263      takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
264 }
265 
266 //===- EH -----------------------------------------------------------------===//
267 
268 LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
269     (MachineBasicBlock *LandingPad) {
270   unsigned N = LandingPads.size();
271   for (unsigned i = 0; i < N; ++i) {
272     LandingPadInfo &LP = LandingPads[i];
273     if (LP.LandingPadBlock == LandingPad)
274       return LP;
275   }
276 
277   LandingPads.push_back(LandingPadInfo(LandingPad));
278   return LandingPads[N];
279 }
280 
281 void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
282                                   MCSymbol *BeginLabel, MCSymbol *EndLabel) {
283   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
284   LP.BeginLabels.push_back(BeginLabel);
285   LP.EndLabels.push_back(EndLabel);
286 }
287 
288 MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
289   MCSymbol *LandingPadLabel = Context.createTempSymbol();
290   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
291   LP.LandingPadLabel = LandingPadLabel;
292   return LandingPadLabel;
293 }
294 
295 void MachineModuleInfo::addPersonality(const Function *Personality) {
296   for (unsigned i = 0; i < Personalities.size(); ++i)
297     if (Personalities[i] == Personality)
298       return;
299   Personalities.push_back(Personality);
300 }
301 
302 void MachineModuleInfo::
303 addCatchTypeInfo(MachineBasicBlock *LandingPad,
304                  ArrayRef<const GlobalValue *> TyInfo) {
305   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
306   for (unsigned N = TyInfo.size(); N; --N)
307     LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
308 }
309 
310 void MachineModuleInfo::
311 addFilterTypeInfo(MachineBasicBlock *LandingPad,
312                   ArrayRef<const GlobalValue *> TyInfo) {
313   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
314   std::vector<unsigned> IdsInFilter(TyInfo.size());
315   for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
316     IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
317   LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
318 }
319 
320 void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
321   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
322   LP.TypeIds.push_back(0);
323 }
324 
325 void MachineModuleInfo::addSEHCatchHandler(MachineBasicBlock *LandingPad,
326                                            const Function *Filter,
327                                            const BlockAddress *RecoverBA) {
328   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
329   SEHHandler Handler;
330   Handler.FilterOrFinally = Filter;
331   Handler.RecoverBA = RecoverBA;
332   LP.SEHHandlers.push_back(Handler);
333 }
334 
335 void MachineModuleInfo::addSEHCleanupHandler(MachineBasicBlock *LandingPad,
336                                              const Function *Cleanup) {
337   LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
338   SEHHandler Handler;
339   Handler.FilterOrFinally = Cleanup;
340   Handler.RecoverBA = nullptr;
341   LP.SEHHandlers.push_back(Handler);
342 }
343 
344 void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
345   for (unsigned i = 0; i != LandingPads.size(); ) {
346     LandingPadInfo &LandingPad = LandingPads[i];
347     if (LandingPad.LandingPadLabel &&
348         !LandingPad.LandingPadLabel->isDefined() &&
349         (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
350       LandingPad.LandingPadLabel = nullptr;
351 
352     // Special case: we *should* emit LPs with null LP MBB. This indicates
353     // "nounwind" case.
354     if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
355       LandingPads.erase(LandingPads.begin() + i);
356       continue;
357     }
358 
359     for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
360       MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
361       MCSymbol *EndLabel = LandingPad.EndLabels[j];
362       if ((BeginLabel->isDefined() ||
363            (LPMap && (*LPMap)[BeginLabel] != 0)) &&
364           (EndLabel->isDefined() ||
365            (LPMap && (*LPMap)[EndLabel] != 0))) continue;
366 
367       LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
368       LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
369       --j;
370       --e;
371     }
372 
373     // Remove landing pads with no try-ranges.
374     if (LandingPads[i].BeginLabels.empty()) {
375       LandingPads.erase(LandingPads.begin() + i);
376       continue;
377     }
378 
379     // If there is no landing pad, ensure that the list of typeids is empty.
380     // If the only typeid is a cleanup, this is the same as having no typeids.
381     if (!LandingPad.LandingPadBlock ||
382         (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
383       LandingPad.TypeIds.clear();
384     ++i;
385   }
386 }
387 
388 void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
389                                               ArrayRef<unsigned> Sites) {
390   LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
391 }
392 
393 unsigned MachineModuleInfo::getTypeIDFor(const GlobalValue *TI) {
394   for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
395     if (TypeInfos[i] == TI) return i + 1;
396 
397   TypeInfos.push_back(TI);
398   return TypeInfos.size();
399 }
400 
401 int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
402   // If the new filter coincides with the tail of an existing filter, then
403   // re-use the existing filter.  Folding filters more than this requires
404   // re-ordering filters and/or their elements - probably not worth it.
405   for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
406        E = FilterEnds.end(); I != E; ++I) {
407     unsigned i = *I, j = TyIds.size();
408 
409     while (i && j)
410       if (FilterIds[--i] != TyIds[--j])
411         goto try_next;
412 
413     if (!j)
414       // The new filter coincides with range [i, end) of the existing filter.
415       return -(1 + i);
416 
417 try_next:;
418   }
419 
420   // Add the new filter.
421   int FilterID = -(1 + FilterIds.size());
422   FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
423   FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
424   FilterEnds.push_back(FilterIds.size());
425   FilterIds.push_back(0); // terminator
426   return FilterID;
427 }
428 
429 MachineFunction &MachineModuleInfo::getMachineFunction(const Function &F) {
430   // Shortcut for the common case where a sequence of MachineFunctionPasses
431   // all query for the same Function.
432   if (LastRequest == &F)
433     return *LastResult;
434 
435   auto I = MachineFunctions.insert(
436       std::make_pair(&F, std::unique_ptr<MachineFunction>()));
437   MachineFunction *MF;
438   if (I.second) {
439     // No pre-existing machine function, create a new one.
440     MF = new MachineFunction(&F, TM, NextFnNum++, *this);
441     // Update the set entry.
442     I.first->second.reset(MF);
443 
444     if (MFInitializer)
445       if (MFInitializer->initializeMachineFunction(*MF))
446         report_fatal_error("Unable to initialize machine function");
447   } else {
448     MF = I.first->second.get();
449   }
450 
451   LastRequest = &F;
452   LastResult = MF;
453   return *MF;
454 }
455 
456 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
457   MachineFunctions.erase(&F);
458   LastRequest = nullptr;
459   LastResult = nullptr;
460 }
461 
462 namespace {
463 /// This pass frees the MachineFunction object associated with a Function.
464 class FreeMachineFunction : public FunctionPass {
465 public:
466   static char ID;
467   FreeMachineFunction() : FunctionPass(ID) {}
468 
469   void getAnalysisUsage(AnalysisUsage &AU) const override {
470     AU.addRequired<MachineModuleInfo>();
471     AU.addPreserved<MachineModuleInfo>();
472   }
473 
474   bool runOnFunction(Function &F) override {
475     MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
476     MMI.deleteMachineFunctionFor(F);
477     return true;
478   }
479 };
480 char FreeMachineFunction::ID;
481 } // end anonymous namespace
482 
483 namespace llvm {
484 FunctionPass *createFreeMachineFunctionPass() {
485   return new FreeMachineFunction();
486 }
487 } // end namespace llvm
488