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/Instructions.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/Value.h" 22 #include "llvm/IR/ValueHandle.h" 23 #include "llvm/InitializePasses.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCSymbol.h" 26 #include "llvm/MC/MCSymbolXCOFF.h" 27 #include "llvm/Pass.h" 28 #include "llvm/Support/Casting.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 // Out of line virtual method. 42 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; 43 44 namespace llvm { 45 46 class MMIAddrLabelMapCallbackPtr final : CallbackVH { 47 MMIAddrLabelMap *Map = nullptr; 48 49 public: 50 MMIAddrLabelMapCallbackPtr() = default; 51 MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 52 53 void setPtr(BasicBlock *BB) { 54 ValueHandleBase::operator=(BB); 55 } 56 57 void setMap(MMIAddrLabelMap *map) { Map = map; } 58 59 void deleted() override; 60 void allUsesReplacedWith(Value *V2) override; 61 }; 62 63 class MMIAddrLabelMap { 64 MCContext &Context; 65 struct AddrLabelSymEntry { 66 /// The symbols for the label. 67 TinyPtrVector<MCSymbol *> Symbols; 68 69 Function *Fn; // The containing function of the BasicBlock. 70 unsigned Index; // The index in BBCallbacks for the BasicBlock. 71 }; 72 73 DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 74 75 /// Callbacks for the BasicBlock's that we have entries for. We use this so 76 /// we get notified if a block is deleted or RAUWd. 77 std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; 78 79 public: 80 MMIAddrLabelMap(MCContext &context) : Context(context) {} 81 82 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 83 84 void UpdateForDeletedBlock(BasicBlock *BB); 85 void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 86 }; 87 88 } // end namespace llvm 89 90 ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 91 assert(BB->hasAddressTaken() && 92 "Shouldn't get label for block without address taken"); 93 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 94 95 // If we already had an entry for this block, just return it. 96 if (!Entry.Symbols.empty()) { 97 assert(BB->getParent() == Entry.Fn && "Parent changed"); 98 return Entry.Symbols; 99 } 100 101 // Otherwise, this is a new entry, create a new symbol for it and add an 102 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 103 BBCallbacks.emplace_back(BB); 104 BBCallbacks.back().setMap(this); 105 Entry.Index = BBCallbacks.size() - 1; 106 Entry.Fn = BB->getParent(); 107 MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 108 : Context.createTempSymbol(); 109 Entry.Symbols.push_back(Sym); 110 return Entry.Symbols; 111 } 112 113 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 114 // If the block got deleted, there is no need for the symbol. If the symbol 115 // was already emitted, we can just forget about it, otherwise we need to 116 // queue it up for later emission when the function is output. 117 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 118 AddrLabelSymbols.erase(BB); 119 assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 120 BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 121 122 assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 123 "Block/parent mismatch"); 124 125 assert(llvm::all_of(Entry.Symbols, [](MCSymbol *Sym) { 126 return Sym->isDefined(); })); 127 } 128 129 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 130 // Get the entry for the RAUW'd block and remove it from our map. 131 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 132 AddrLabelSymbols.erase(Old); 133 assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 134 135 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 136 137 // If New is not address taken, just move our symbol over to it. 138 if (NewEntry.Symbols.empty()) { 139 BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 140 NewEntry = std::move(OldEntry); // Set New's entry. 141 return; 142 } 143 144 BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 145 146 // Otherwise, we need to add the old symbols to the new block's set. 147 NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), 148 OldEntry.Symbols.end()); 149 } 150 151 void MMIAddrLabelMapCallbackPtr::deleted() { 152 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 153 } 154 155 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 156 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 157 } 158 159 void MachineModuleInfo::initialize() { 160 ObjFileMMI = nullptr; 161 CurCallSite = 0; 162 UsesMSVCFloatingPoint = UsesMorestackAddr = false; 163 HasSplitStack = HasNosplitStack = false; 164 AddrLabelSymbols = nullptr; 165 } 166 167 void MachineModuleInfo::finalize() { 168 Personalities.clear(); 169 170 delete AddrLabelSymbols; 171 AddrLabelSymbols = nullptr; 172 173 Context.reset(); 174 // We don't clear the ExternalContext. 175 176 delete ObjFileMMI; 177 ObjFileMMI = nullptr; 178 } 179 180 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI) 181 : TM(std::move(MMI.TM)), 182 Context(MMI.TM.getMCAsmInfo(), MMI.TM.getMCRegisterInfo(), 183 MMI.TM.getObjFileLowering(), nullptr, nullptr, false), 184 MachineFunctions(std::move(MMI.MachineFunctions)) { 185 ObjFileMMI = MMI.ObjFileMMI; 186 CurCallSite = MMI.CurCallSite; 187 UsesMSVCFloatingPoint = MMI.UsesMSVCFloatingPoint; 188 UsesMorestackAddr = MMI.UsesMorestackAddr; 189 HasSplitStack = MMI.HasSplitStack; 190 HasNosplitStack = MMI.HasNosplitStack; 191 AddrLabelSymbols = MMI.AddrLabelSymbols; 192 ExternalContext = MMI.ExternalContext; 193 TheModule = MMI.TheModule; 194 } 195 196 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM) 197 : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 198 TM->getObjFileLowering(), nullptr, nullptr, false) { 199 initialize(); 200 } 201 202 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM, 203 MCContext *ExtContext) 204 : TM(*TM), Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), 205 TM->getObjFileLowering(), nullptr, nullptr, false), 206 ExternalContext(ExtContext) { 207 initialize(); 208 } 209 210 MachineModuleInfo::~MachineModuleInfo() { finalize(); } 211 212 //===- Address of Block Management ----------------------------------------===// 213 214 ArrayRef<MCSymbol *> 215 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 216 // Lazily create AddrLabelSymbols. 217 if (!AddrLabelSymbols) 218 AddrLabelSymbols = new MMIAddrLabelMap(getContext()); 219 return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); 220 } 221 222 /// \name Exception Handling 223 /// \{ 224 225 void MachineModuleInfo::addPersonality(const Function *Personality) { 226 for (unsigned i = 0; i < Personalities.size(); ++i) 227 if (Personalities[i] == Personality) 228 return; 229 Personalities.push_back(Personality); 230 } 231 232 /// \} 233 234 MachineFunction * 235 MachineModuleInfo::getMachineFunction(const Function &F) const { 236 auto I = MachineFunctions.find(&F); 237 return I != MachineFunctions.end() ? I->second.get() : nullptr; 238 } 239 240 MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) { 241 // Shortcut for the common case where a sequence of MachineFunctionPasses 242 // all query for the same Function. 243 if (LastRequest == &F) 244 return *LastResult; 245 246 auto I = MachineFunctions.insert( 247 std::make_pair(&F, std::unique_ptr<MachineFunction>())); 248 MachineFunction *MF; 249 if (I.second) { 250 // No pre-existing machine function, create a new one. 251 const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F); 252 MF = new MachineFunction(F, TM, STI, NextFnNum++, *this); 253 // Update the set entry. 254 I.first->second.reset(MF); 255 } else { 256 MF = I.first->second.get(); 257 } 258 259 LastRequest = &F; 260 LastResult = MF; 261 return *MF; 262 } 263 264 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { 265 MachineFunctions.erase(&F); 266 LastRequest = nullptr; 267 LastResult = nullptr; 268 } 269 270 namespace { 271 272 /// This pass frees the MachineFunction object associated with a Function. 273 class FreeMachineFunction : public FunctionPass { 274 public: 275 static char ID; 276 277 FreeMachineFunction() : FunctionPass(ID) {} 278 279 void getAnalysisUsage(AnalysisUsage &AU) const override { 280 AU.addRequired<MachineModuleInfoWrapperPass>(); 281 AU.addPreserved<MachineModuleInfoWrapperPass>(); 282 } 283 284 bool runOnFunction(Function &F) override { 285 MachineModuleInfo &MMI = 286 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 287 MMI.deleteMachineFunctionFor(F); 288 return true; 289 } 290 291 StringRef getPassName() const override { 292 return "Free MachineFunction"; 293 } 294 }; 295 296 } // end anonymous namespace 297 298 char FreeMachineFunction::ID; 299 300 FunctionPass *llvm::createFreeMachineFunctionPass() { 301 return new FreeMachineFunction(); 302 } 303 304 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 305 const LLVMTargetMachine *TM) 306 : ImmutablePass(ID), MMI(TM) { 307 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 308 } 309 310 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass( 311 const LLVMTargetMachine *TM, MCContext *ExtContext) 312 : ImmutablePass(ID), MMI(TM, ExtContext) { 313 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 314 } 315 316 // Handle the Pass registration stuff necessary to use DataLayout's. 317 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo", 318 "Machine Module Information", false, false) 319 char MachineModuleInfoWrapperPass::ID = 0; 320 321 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { 322 MMI.initialize(); 323 MMI.TheModule = &M; 324 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 325 return false; 326 } 327 328 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) { 329 MMI.finalize(); 330 return false; 331 } 332 333 AnalysisKey MachineModuleAnalysis::Key; 334 335 MachineModuleInfo MachineModuleAnalysis::run(Module &M, 336 ModuleAnalysisManager &) { 337 MachineModuleInfo MMI(TM); 338 MMI.TheModule = &M; 339 MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); 340 return MMI; 341 } 342