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/StringRef.h" 13 #include "llvm/ADT/TinyPtrVector.h" 14 #include "llvm/CodeGen/MachineFunction.h" 15 #include "llvm/CodeGen/Passes.h" 16 #include "llvm/IR/BasicBlock.h" 17 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/DiagnosticInfo.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/ValueHandle.h" 22 #include "llvm/InitializePasses.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 // Out of line virtual method. 40 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 41 42 namespace llvm { 43 44 class MMIAddrLabelMapCallbackPtr final : CallbackVH { 45 MMIAddrLabelMap *Map = nullptr; 46 47 public: 48 MMIAddrLabelMapCallbackPtr() = default; 49 MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 50 51 void setPtr(BasicBlock *BB) { 52 ValueHandleBase::operator=(BB); 53 } 54 55 void setMap(MMIAddrLabelMap *map) { Map = map; } 56 57 void deleted() override; 58 void allUsesReplacedWith(Value *V2) override; 59 }; 60 61 class MMIAddrLabelMap { 62 MCContext &Context; 63 struct AddrLabelSymEntry { 64 /// The symbols for the label. 65 TinyPtrVector<MCSymbol *> Symbols; 66 67 Function *Fn; // The containing function of the BasicBlock. 68 unsigned Index; // The index in BBCallbacks for the BasicBlock. 69 }; 70 71 DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 72 73 /// Callbacks for the BasicBlock's that we have entries for. We use this so 74 /// we get notified if a block is deleted or RAUWd. 75 std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 76 77 /// This is a per-function list of symbols whose corresponding BasicBlock got 78 /// deleted. These symbols need to be emitted at some point in the file, so 79 /// AsmPrinter emits them after the function body. 80 DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> 81 DeletedAddrLabelsNeedingEmission; 82 83 public: 84 MMIAddrLabelMap(MCContext &context) : Context(context) {} 85 86 ~MMIAddrLabelMap() { 87 assert(DeletedAddrLabelsNeedingEmission.empty() && 88 "Some labels for deleted blocks never got emitted"); 89 } 90 91 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 92 93 void takeDeletedSymbolsForFunction(Function *F, 94 std::vector<MCSymbol*> &Result); 95 96 void UpdateForDeletedBlock(BasicBlock *BB); 97 void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 98 }; 99 100 } // end namespace llvm 101 102 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 103 assert(BB->hasAddressTaken() && 104 "Shouldn't get label for block without address taken"); 105 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 106 107 // If we already had an entry for this block, just return it. 108 if (!Entry.Symbols.empty()) { 109 assert(BB->getParent() == Entry.Fn && "Parent changed"); 110 return Entry.Symbols; 111 } 112 113 // Otherwise, this is a new entry, create a new symbol for it and add an 114 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 115 BBCallbacks.emplace_back(BB); 116 BBCallbacks.back().setMap(this); 117 Entry.Index = BBCallbacks.size() - 1; 118 Entry.Fn = BB->getParent(); 119 MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 120 : Context.createTempSymbol(); 121 Entry.Symbols.push_back(Sym); 122 return Entry.Symbols; 123 } 124 125 /// If we have any deleted symbols for F, return them. 126 void MMIAddrLabelMap:: 127 takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { 128 DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = 129 DeletedAddrLabelsNeedingEmission.find(F); 130 131 // If there are no entries for the function, just return. 132 if (I == DeletedAddrLabelsNeedingEmission.end()) return; 133 134 // Otherwise, take the list. 135 std::swap(Result, I->second); 136 DeletedAddrLabelsNeedingEmission.erase(I); 137 } 138 139 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 140 // If the block got deleted, there is no need for the symbol. If the symbol 141 // was already emitted, we can just forget about it, otherwise we need to 142 // queue it up for later emission when the function is output. 143 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 144 AddrLabelSymbols.erase(BB); 145 assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 146 BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 147 148 assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 149 "Block/parent mismatch"); 150 151 for (MCSymbol *Sym : Entry.Symbols) { 152 if (Sym->isDefined()) 153 return; 154 155 // If the block is not yet defined, we need to emit it at the end of the 156 // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 157 // for the containing Function. Since the block is being deleted, its 158 // parent may already be removed, we have to get the function from 'Entry'. 159 DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 160 } 161 } 162 163 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 164 // Get the entry for the RAUW'd block and remove it from our map. 165 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 166 AddrLabelSymbols.erase(Old); 167 assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 168 169 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 170 171 // If New is not address taken, just move our symbol over to it. 172 if (NewEntry.Symbols.empty()) { 173 BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 174 NewEntry = std::move(OldEntry); // Set New's entry. 175 return; 176 } 177 178 BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 179 180 // Otherwise, we need to add the old symbols to the new block's set. 181 llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); 182 } 183 184 void MMIAddrLabelMapCallbackPtr::deleted() { 185 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 186 } 187 188 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 189 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 190 } 191 192 void MachineModuleInfo::initialize() { 193 ObjFileMMI = nullptr; 194 CurCallSite = 0; 195 NextFnNum = 0; 196 UsesMSVCFloatingPoint = UsesMorestackAddr = false; 197 HasSplitStack = HasNosplitStack = false; 198 AddrLabelSymbols = nullptr; 199 } 200 201 void MachineModuleInfo::finalize() { 202 Personalities.clear(); 203 204 delete AddrLabelSymbols; 205 AddrLabelSymbols = nullptr; 206 207 Context.reset(); 208 // We don't clear the ExternalContext. 209 210 delete ObjFileMMI; 211 ObjFileMMI = nullptr; 212 } 213 214 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 215 : TM(std::move(MMI.TM)), 216 Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(), 217 MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr, 218 nullptr, false), 219 MachineFunctions(std::move(MMI.MachineFunctions)) { 220 Context.setObjectFileInfo(MMI.TM.getObjFileLowering()); 221 ObjFileMMI = MMI.ObjFileMMI; 222 CurCallSite = MMI.CurCallSite; 223 UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 224 UsesMorestackAddr = MMI.UsesMorestackAddr; 225 HasSplitStack = MMI.HasSplitStack; 226 HasNosplitStack = MMI.HasNosplitStack; 227 AddrLabelSymbols = MMI.AddrLabelSymbols; 228 ExternalContext = MMI.ExternalContext; 229 TheModule = MMI.TheModule; 230 } 231 232 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 233 : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 234 TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 235 nullptr, nullptr, false) { 236 Context.setObjectFileInfo(TM->getObjFileLowering()); 237 initialize(); 238 } 239 240 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 241 MCContext *ExtContext) 242 : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(), 243 TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), 244 nullptr, nullptr, false), 245 ExternalContext(ExtContext) { 246 Context.setObjectFileInfo(TM->getObjFileLowering()); 247 initialize(); 248 } 249 250 MachineModuleInfo::~MachineModuleInfo() { finalize(); } 251 252 //===- Address of Block Management ----------------------------------------===// 253 254 ArrayRef<MCSymbol *> 255 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 256 // Lazily create AddrLabelSymbols. 257 if (!AddrLabelSymbols) 258 AddrLabelSymbols = new MMIAddrLabelMap(getContext()); 259 return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 260 } 261 262 void MachineModuleInfo:: 263 takeDeletedSymbolsForFunction(const Function *F, 264 std::vector<MCSymbol*> &Result) { 265 // If no blocks have had their addresses taken, we're done. 266 if (!AddrLabelSymbols) return; 267 return AddrLabelSymbols-> 268 takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); 269 } 270 271 /// \name Exception Handling 272 /// \{ 273 274 void MachineModuleInfo::addPersonality(const Function *Personality) { 275 if (!llvm::is_contained(Personalities, Personality)) 276 Personalities.push_back(Personality); 277 } 278 279 /// \} 280 281 MachineFunction * 282 MachineModuleInfo::getMachineFunction(const Function &F) const { 283 auto I = MachineFunctions.find(&F); 284 return I != MachineFunctions.end() ? I->second.get() : nullptr; 285 } 286 287 MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 288 // Shortcut for the common case where a sequence of MachineFunctionPasses 289 // all query for the same Function. 290 if (LastRequest == &F) 291 return *LastResult; 292 293 auto I = MachineFunctions.insert( 294 std::make_pair(&F, std::unique_ptr<MachineFunction>())); 295 MachineFunction *MF; 296 if (I.second) { 297 // No pre-existing machine function, create a new one. 298 const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 299 MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 300 // Update the set entry. 301 I.first->second.reset(MF); 302 } else { 303 MF = I.first->second.get(); 304 } 305 306 LastRequest = &F; 307 LastResult = MF; 308 return *MF; 309 } 310 311 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 312 MachineFunctions.erase(&F); 313 LastRequest = nullptr; 314 LastResult = nullptr; 315 } 316 317 namespace { 318 319 /// This pass frees the MachineFunction object associated with a Function. 320 class FreeMachineFunction : public FunctionPass { 321 public: 322 static char ID; 323 324 FreeMachineFunction() : FunctionPass(ID) {} 325 326 void getAnalysisUsage(AnalysisUsage &AU) const override { 327 AU.addRequired<MachineModuleInfoWrapperPass>(); 328 AU.addPreserved<MachineModuleInfoWrapperPass>(); 329 } 330 331 bool runOnFunction(Function &F) override { 332 MachineModuleInfo &MMI = 333 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 334 MMI.deleteMachineFunctionFor(F); 335 return true; 336 } 337 338 StringRef getPassName() const override { 339 return "Free MachineFunction"; 340 } 341 }; 342 343 } // end anonymous namespace 344 345 char FreeMachineFunction::ID; 346 347 FunctionPass *llvm::createFreeMachineFunctionPass() { 348 return new FreeMachineFunction(); 349 } 350 351 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 352 const LLVMTargetMachine *TM) 353 : ImmutablePass(ID), MMI(TM) { 354 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 355 } 356 357 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 358 const LLVMTargetMachine *TM, MCContext *ExtContext) 359 : ImmutablePass(ID), MMI(TM, ExtContext) { 360 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 361 } 362 363 // Handle the Pass registration stuff necessary to use DataLayout's. 364 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 365 "Machine Module Information", false, false) 366 char MachineModuleInfoWrapperPass::ID = 0; 367 368 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 369 std::vector<const MDNode *> &LocInfos) { 370 // Look up a LocInfo for the buffer this diagnostic is coming from. 371 unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 372 const MDNode *LocInfo = nullptr; 373 if (BufNum > 0 && BufNum <= LocInfos.size()) 374 LocInfo = LocInfos[BufNum - 1]; 375 376 // If the inline asm had metadata associated with it, pull out a location 377 // cookie corresponding to which line the error occurred on. 378 unsigned LocCookie = 0; 379 if (LocInfo) { 380 unsigned ErrorLine = SMD.getLineNo() - 1; 381 if (ErrorLine >= LocInfo->getNumOperands()) 382 ErrorLine = 0; 383 384 if (LocInfo->getNumOperands() != 0) 385 if (const ConstantInt *CI = 386 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 387 LocCookie = CI->getZExtValue(); 388 } 389 390 return LocCookie; 391 } 392 393 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 394 MMI.initialize(); 395 MMI.TheModule = &M; 396 // FIXME: Do this for new pass manager. 397 LLVMContext &Ctx = M.getContext(); 398 MMI.getContext().setDiagnosticHandler( 399 [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm, 400 const SourceMgr &SrcMgr, 401 std::vector<const MDNode *> &LocInfos) { 402 unsigned LocCookie = 0; 403 if (IsInlineAsm) 404 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 405 Ctx.diagnose( 406 DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie)); 407 }); 408 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 409 return false; 410 } 411 412 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 413 MMI.finalize(); 414 return false; 415 } 416 417 AnalysisKey MachineModuleAnalysis::Key; 418 419 MachineModuleInfo MachineModuleAnalysis::run(Module &M, 420 ModuleAnalysisManager &) { 421 MachineModuleInfo MMI(TM); 422 MMI.TheModule = &M; 423 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 424 return MMI; 425 } 426