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