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