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