1 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/CodeGen/MachineModuleInfo.h" 10 #include "llvm/ADT/ArrayRef.h" 11 #include "llvm/ADT/DenseMap.h" 12 #include "llvm/ADT/PostOrderIterator.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/ADT/TinyPtrVector.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/Passes.h" 17 #include "llvm/IR/BasicBlock.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/Instructions.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/Value.h" 22 #include "llvm/IR/ValueHandle.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCSymbol.h" 25 #include "llvm/Pass.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Target/TargetLoweringObjectFile.h" 29 #include "llvm/Target/TargetMachine.h" 30 #include <algorithm> 31 #include <cassert> 32 #include <memory> 33 #include <utility> 34 #include <vector> 35 36 using namespace llvm; 37 using namespace llvm::dwarf; 38 39 // Handle the Pass registration stuff necessary to use DataLayout's. 40 INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo", 41 "Machine Module Information", false, false) 42 char MachineModuleInfo::ID = 0; 43 44 // Out of line virtual method. 45 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 46 47 namespace llvm { 48 49 class MMIAddrLabelMapCallbackPtr final : CallbackVH { 50 MMIAddrLabelMap *Map = nullptr; 51 52 public: 53 MMIAddrLabelMapCallbackPtr() = default; 54 MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 55 56 void setPtr(BasicBlock *BB) { 57 ValueHandleBase::operator=(BB); 58 } 59 60 void setMap(MMIAddrLabelMap *map) { Map = map; } 61 62 void deleted() override; 63 void allUsesReplacedWith(Value *V2) override; 64 }; 65 66 class MMIAddrLabelMap { 67 MCContext &Context; 68 struct AddrLabelSymEntry { 69 /// The symbols for the label. 70 TinyPtrVector<MCSymbol *> Symbols; 71 72 Function *Fn; // The containing function of the BasicBlock. 73 unsigned Index; // The index in BBCallbacks for the BasicBlock. 74 }; 75 76 DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 77 78 /// Callbacks for the BasicBlock's that we have entries for. We use this so 79 /// we get notified if a block is deleted or RAUWd. 80 std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 81 82 /// This is a per-function list of symbols whose corresponding BasicBlock got 83 /// deleted. These symbols need to be emitted at some point in the file, so 84 /// AsmPrinter emits them after the function body. 85 DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 86 DeletedAddrLabelsNeedingEmission; 87 88 public: 89 MMIAddrLabelMap(MCContext &context) : Context(context) {} 90 91 ~MMIAddrLabelMap() { 92 assert(DeletedAddrLabelsNeedingEmission.empty() && 93 "Some labels for deleted blocks never got emitted"); 94 } 95 96 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 97 98 void takeDeletedSymbolsForFunction(Function *F, 99 std::vector<MCSymbol*> &Result); 100 101 void UpdateForDeletedBlock(BasicBlock *BB); 102 void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 103 }; 104 105 } // end namespace llvm 106 107 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 108 assert(BB->hasAddressTaken() && 109 "Shouldn't get label for block without address taken"); 110 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 111 112 // If we already had an entry for this block, just return it. 113 if (!Entry.Symbols.empty()) { 114 assert(BB->getParent() == Entry.Fn && "Parent changed"); 115 return Entry.Symbols; 116 } 117 118 // Otherwise, this is a new entry, create a new symbol for it and add an 119 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 120 BBCallbacks.emplace_back(BB); 121 BBCallbacks.back().setMap(this); 122 Entry.Index = BBCallbacks.size() - 1; 123 Entry.Fn = BB->getParent(); 124 Entry.Symbols.push_back(Context.createTempSymbol(!BB->hasAddressTaken())); 125 return Entry.Symbols; 126 } 127 128 /// If we have any deleted symbols for F, return them. 129 void MMIAddrLabelMap:: 130 takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 131 DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 132 DeletedAddrLabelsNeedingEmission.find(F); 133 134 // If there are no entries for the function, just return. 135 if (I == DeletedAddrLabelsNeedingEmission.end()) return; 136 137 // Otherwise, take the list. 138 std::swap(Result, I->second); 139 DeletedAddrLabelsNeedingEmission.erase(I); 140 } 141 142 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 143 // If the block got deleted, there is no need for the symbol. If the symbol 144 // was already emitted, we can just forget about it, otherwise we need to 145 // queue it up for later emission when the function is output. 146 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 147 AddrLabelSymbols.erase(BB); 148 assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 149 BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 150 151 assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 152 "Block/parent mismatch"); 153 154 for (MCSymbol *Sym : Entry.Symbols) { 155 if (Sym->isDefined()) 156 return; 157 158 // If the block is not yet defined, we need to emit it at the end of the 159 // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 160 // for the containing Function. Since the block is being deleted, its 161 // parent may already be removed, we have to get the function from 'Entry'. 162 DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 163 } 164 } 165 166 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 167 // Get the entry for the RAUW'd block and remove it from our map. 168 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 169 AddrLabelSymbols.erase(Old); 170 assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 171 172 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 173 174 // If New is not address taken, just move our symbol over to it. 175 if (NewEntry.Symbols.empty()) { 176 BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 177 NewEntry = std::move(OldEntry); // Set New's entry. 178 return; 179 } 180 181 BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 182 183 // Otherwise, we need to add the old symbols to the new block's set. 184 NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 185 OldEntry.Symbols.end()); 186 } 187 188 void MMIAddrLabelMapCallbackPtr::deleted() { 189 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 190 } 191 192 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 193 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 194 } 195 196 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 197 : ImmutablePass(ID), TM(*TM), 198 Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 199 TM->getObjFileLowering(), nullptr, false) { 200 initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); 201 } 202 203 MachineModuleInfo::~MachineModuleInfo() = default; 204 205 bool MachineModuleInfo::doInitialization(Module &M) { 206 ObjFileMMI = nullptr; 207 CurCallSite = 0; 208 UsesMSVCFloatingPoint = UsesMorestackAddr = false; 209 HasSplitStack = HasNosplitStack = false; 210 AddrLabelSymbols = nullptr; 211 TheModule = &M; 212 DbgInfoAvailable = !llvm::empty(M.debug_compile_units()); 213 return false; 214 } 215 216 bool MachineModuleInfo::doFinalization(Module &M) { 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 //===- Address of Block Management ----------------------------------------===// 231 232 ArrayRef<MCSymbol *> 233 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 234 // Lazily create AddrLabelSymbols. 235 if (!AddrLabelSymbols) 236 AddrLabelSymbols = new MMIAddrLabelMap(Context); 237 return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 238 } 239 240 void MachineModuleInfo:: 241 takeDeletedSymbolsForFunction(const Function *F, 242 std::vector<MCSymbol*> &Result) { 243 // If no blocks have had their addresses taken, we're done. 244 if (!AddrLabelSymbols) return; 245 return AddrLabelSymbols-> 246 takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 247 } 248 249 /// \name Exception Handling 250 /// \{ 251 252 void MachineModuleInfo::addPersonality(const Function *Personality) { 253 for (unsigned i = 0; i < Personalities.size(); ++i) 254 if (Personalities[i] == Personality) 255 return; 256 Personalities.push_back(Personality); 257 } 258 259 /// \} 260 261 MachineFunction * 262 MachineModuleInfo::getMachineFunction(const Function &F) const { 263 auto I = MachineFunctions.find(&F); 264 return I != MachineFunctions.end() ? I->second.get() : nullptr; 265 } 266 267 MachineFunction & 268 MachineModuleInfo::getOrCreateMachineFunction(const Function &F) { 269 // Shortcut for the common case where a sequence of MachineFunctionPasses 270 // all query for the same Function. 271 if (LastRequest == &F) 272 return *LastResult; 273 274 auto I = MachineFunctions.insert( 275 std::make_pair(&F, std::unique_ptr<MachineFunction>())); 276 MachineFunction *MF; 277 if (I.second) { 278 // No pre-existing machine function, create a new one. 279 const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 280 MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 281 // Update the set entry. 282 I.first->second.reset(MF); 283 } else { 284 MF = I.first->second.get(); 285 } 286 287 LastRequest = &F; 288 LastResult = MF; 289 return *MF; 290 } 291 292 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 293 MachineFunctions.erase(&F); 294 LastRequest = nullptr; 295 LastResult = nullptr; 296 } 297 298 namespace { 299 300 /// This pass frees the MachineFunction object associated with a Function. 301 class FreeMachineFunction : public FunctionPass { 302 public: 303 static char ID; 304 305 FreeMachineFunction() : FunctionPass(ID) {} 306 307 void getAnalysisUsage(AnalysisUsage &AU) const override { 308 AU.addRequired<MachineModuleInfo>(); 309 AU.addPreserved<MachineModuleInfo>(); 310 } 311 312 bool runOnFunction(Function &F) override { 313 MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); 314 MMI.deleteMachineFunctionFor(F); 315 return true; 316 } 317 318 StringRef getPassName() const override { 319 return "Free MachineFunction"; 320 } 321 }; 322 323 } // end anonymous namespace 324 325 char FreeMachineFunction::ID; 326 327 FunctionPass *llvm::createFreeMachineFunctionPass() { 328 return new FreeMachineFunction(); 329 } 330