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 public: 82 MMIAddrLabelMap(MCContext &context) : Context(context) {} 83 84 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 85 86 void UpdateForDeletedBlock(BasicBlock *BB); 87 void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 88 }; 89 90 } // end namespace llvm 91 92 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 93 assert(BB->hasAddressTaken() && 94 "Shouldn't get label for block without address taken"); 95 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 96 97 // If we already had an entry for this block, just return it. 98 if (!Entry.Symbols.empty()) { 99 assert(BB->getParent() == Entry.Fn && "Parent changed"); 100 return Entry.Symbols; 101 } 102 103 // Otherwise, this is a new entry, create a new symbol for it and add an 104 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 105 BBCallbacks.emplace_back(BB); 106 BBCallbacks.back().setMap(this); 107 Entry.Index = BBCallbacks.size() - 1; 108 Entry.Fn = BB->getParent(); 109 MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 110 : Context.createTempSymbol(); 111 Entry.Symbols.push_back(Sym); 112 return Entry.Symbols; 113 } 114 115 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 116 // If the block got deleted, there is no need for the symbol. If the symbol 117 // was already emitted, we can just forget about it, otherwise we need to 118 // queue it up for later emission when the function is output. 119 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 120 AddrLabelSymbols.erase(BB); 121 assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 122 BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 123 124 assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 125 "Block/parent mismatch"); 126 127 assert(llvm::all_of(Entry.Symbols, [](MCSymbol *Sym) { 128 return Sym->isDefined(); })); 129 } 130 131 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 132 // Get the entry for the RAUW'd block and remove it from our map. 133 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 134 AddrLabelSymbols.erase(Old); 135 assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 136 137 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 138 139 // If New is not address taken, just move our symbol over to it. 140 if (NewEntry.Symbols.empty()) { 141 BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 142 NewEntry = std::move(OldEntry); // Set New's entry. 143 return; 144 } 145 146 BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 147 148 // Otherwise, we need to add the old symbols to the new block's set. 149 llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); 150 } 151 152 void MMIAddrLabelMapCallbackPtr::deleted() { 153 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 154 } 155 156 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 157 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 158 } 159 160 void MachineModuleInfo::initialize() { 161 ObjFileMMI = nullptr; 162 CurCallSite = 0; 163 UsesMSVCFloatingPoint = UsesMorestackAddr = false; 164 HasSplitStack = HasNosplitStack = false; 165 AddrLabelSymbols = nullptr; 166 } 167 168 void MachineModuleInfo::finalize() { 169 Personalities.clear(); 170 171 delete AddrLabelSymbols; 172 AddrLabelSymbols = nullptr; 173 174 Context.reset(); 175 // We don't clear the ExternalContext. 176 177 delete ObjFileMMI; 178 ObjFileMMI = nullptr; 179 } 180 181 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 182 : TM(std::move(MMI.TM)), 183 Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 184 MMI.TM.getObjFileLowering(), nullptr, nullptr, false), 185 MachineFunctions(std::move(MMI.MachineFunctions)) { 186 ObjFileMMI = MMI.ObjFileMMI; 187 CurCallSite = MMI.CurCallSite; 188 UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 189 UsesMorestackAddr = MMI.UsesMorestackAddr; 190 HasSplitStack = MMI.HasSplitStack; 191 HasNosplitStack = MMI.HasNosplitStack; 192 AddrLabelSymbols = MMI.AddrLabelSymbols; 193 ExternalContext = MMI.ExternalContext; 194 TheModule = MMI.TheModule; 195 } 196 197 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 198 : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 199 TM->getObjFileLowering(), nullptr, nullptr, false) { 200 initialize(); 201 } 202 203 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 204 MCContext *ExtContext) 205 : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 206 TM->getObjFileLowering(), nullptr, nullptr, false), 207 ExternalContext(ExtContext) { 208 initialize(); 209 } 210 211 MachineModuleInfo::~MachineModuleInfo() { finalize(); } 212 213 //===- Address of Block Management ----------------------------------------===// 214 215 ArrayRef<MCSymbol *> 216 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 217 // Lazily create AddrLabelSymbols. 218 if (!AddrLabelSymbols) 219 AddrLabelSymbols = new MMIAddrLabelMap(getContext()); 220 return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 221 } 222 223 /// \name Exception Handling 224 /// \{ 225 226 void MachineModuleInfo::addPersonality(const Function *Personality) { 227 if (!llvm::is_contained(Personalities, Personality)) 228 Personalities.push_back(Personality); 229 } 230 231 /// \} 232 233 MachineFunction * 234 MachineModuleInfo::getMachineFunction(const Function &F) const { 235 auto I = MachineFunctions.find(&F); 236 return I != MachineFunctions.end() ? I->second.get() : nullptr; 237 } 238 239 MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 240 // Shortcut for the common case where a sequence of MachineFunctionPasses 241 // all query for the same Function. 242 if (LastRequest == &F) 243 return *LastResult; 244 245 auto I = MachineFunctions.insert( 246 std::make_pair(&F, std::unique_ptr<MachineFunction>())); 247 MachineFunction *MF; 248 if (I.second) { 249 // No pre-existing machine function, create a new one. 250 const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 251 MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 252 // Update the set entry. 253 I.first->second.reset(MF); 254 } else { 255 MF = I.first->second.get(); 256 } 257 258 LastRequest = &F; 259 LastResult = MF; 260 return *MF; 261 } 262 263 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 264 MachineFunctions.erase(&F); 265 LastRequest = nullptr; 266 LastResult = nullptr; 267 } 268 269 namespace { 270 271 /// This pass frees the MachineFunction object associated with a Function. 272 class FreeMachineFunction : public FunctionPass { 273 public: 274 static char ID; 275 276 FreeMachineFunction() : FunctionPass(ID) {} 277 278 void getAnalysisUsage(AnalysisUsage &AU) const override { 279 AU.addRequired<MachineModuleInfoWrapperPass>(); 280 AU.addPreserved<MachineModuleInfoWrapperPass>(); 281 } 282 283 bool runOnFunction(Function &F) override { 284 MachineModuleInfo &MMI = 285 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 286 MMI.deleteMachineFunctionFor(F); 287 return true; 288 } 289 290 StringRef getPassName() const override { 291 return "Free MachineFunction"; 292 } 293 }; 294 295 } // end anonymous namespace 296 297 char FreeMachineFunction::ID; 298 299 FunctionPass *llvm::createFreeMachineFunctionPass() { 300 return new FreeMachineFunction(); 301 } 302 303 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 304 const LLVMTargetMachine *TM) 305 : ImmutablePass(ID), MMI(TM) { 306 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 307 } 308 309 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 310 const LLVMTargetMachine *TM, MCContext *ExtContext) 311 : ImmutablePass(ID), MMI(TM, ExtContext) { 312 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 313 } 314 315 // Handle the Pass registration stuff necessary to use DataLayout's. 316 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 317 "Machine Module Information", false, false) 318 char MachineModuleInfoWrapperPass::ID = 0; 319 320 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr, 321 std::vector<const MDNode *> &LocInfos) { 322 // Look up a LocInfo for the buffer this diagnostic is coming from. 323 unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc()); 324 const MDNode *LocInfo = nullptr; 325 if (BufNum > 0 && BufNum <= LocInfos.size()) 326 LocInfo = LocInfos[BufNum - 1]; 327 328 // If the inline asm had metadata associated with it, pull out a location 329 // cookie corresponding to which line the error occurred on. 330 unsigned LocCookie = 0; 331 if (LocInfo) { 332 unsigned ErrorLine = SMD.getLineNo() - 1; 333 if (ErrorLine >= LocInfo->getNumOperands()) 334 ErrorLine = 0; 335 336 if (LocInfo->getNumOperands() != 0) 337 if (const ConstantInt *CI = 338 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine))) 339 LocCookie = CI->getZExtValue(); 340 } 341 342 return LocCookie; 343 } 344 345 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 346 MMI.initialize(); 347 MMI.TheModule = &M; 348 // FIXME: Do this for new pass manager. 349 LLVMContext &Ctx = M.getContext(); 350 MMI.getContext().setDiagnosticHandler( 351 [&Ctx](const SMDiagnostic &SMD, bool IsInlineAsm, const SourceMgr &SrcMgr, 352 std::vector<const MDNode *> &LocInfos) { 353 unsigned LocCookie = 0; 354 if (IsInlineAsm) 355 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos); 356 Ctx.diagnose(DiagnosticInfoSrcMgr(SMD, IsInlineAsm, LocCookie)); 357 }); 358 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 359 return false; 360 } 361 362 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 363 MMI.finalize(); 364 return false; 365 } 366 367 AnalysisKey MachineModuleAnalysis::Key; 368 369 MachineModuleInfo MachineModuleAnalysis::run(Module &M, 370 ModuleAnalysisManager &) { 371 MachineModuleInfo MMI(TM); 372 MMI.TheModule = &M; 373 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 374 return MMI; 375 } 376