Index: examples/Kaleidoscope/Orc/fully_lazy/toy.cpp =================================================================== --- examples/Kaleidoscope/Orc/fully_lazy/toy.cpp +++ examples/Kaleidoscope/Orc/fully_lazy/toy.cpp @@ -717,7 +717,7 @@ M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -1179,7 +1179,7 @@ { raw_string_ostream MangledNameStream(MangledName); Mangler::getNameWithPrefix(MangledNameStream, Name, - *Session.getTarget().getDataLayout()); + Session.getTarget().createDataLayout()); } return MangledName; } Index: examples/Kaleidoscope/Orc/initial/toy.cpp =================================================================== --- examples/Kaleidoscope/Orc/initial/toy.cpp +++ examples/Kaleidoscope/Orc/initial/toy.cpp @@ -716,7 +716,7 @@ M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -1160,7 +1160,7 @@ typedef CompileLayerT::ModuleSetHandleT ModuleHandleT; KaleidoscopeJIT(SessionContext &Session) - : DL(*Session.getTarget().getDataLayout()), + : DL(Session.getTarget().createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())) {} std::string mangle(const std::string &Name) { @@ -1201,7 +1201,7 @@ } private: - const DataLayout &DL; + const DataLayout DL; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; }; Index: examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp =================================================================== --- examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp +++ examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp @@ -716,7 +716,7 @@ M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -1162,7 +1162,7 @@ typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT; KaleidoscopeJIT(SessionContext &Session) - : DL(*Session.getTarget().getDataLayout()), + : DL(Session.getTarget().createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())), LazyEmitLayer(CompileLayer) {} @@ -1204,7 +1204,7 @@ } private: - const DataLayout &DL; + const DataLayout DL; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; LazyEmitLayerT LazyEmitLayer; Index: examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp =================================================================== --- examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp +++ examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp @@ -716,7 +716,7 @@ M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -1170,7 +1170,7 @@ { raw_string_ostream MangledNameStream(MangledName); Mangler::getNameWithPrefix(MangledNameStream, Name, - *Session.getTarget().getDataLayout()); + Session.getTarget().createDataLayout()); } return MangledName; } Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -76,7 +76,12 @@ /// The Target that this machine was created for. const Target &TheTarget; - /// For ABI type size and alignment. + /// DataLayout for the target: keep ABI type size and alignment. + /// + /// The DataLayout is created based on the string representation provided + /// during construction. It is kept here only to avoid reparsing the string + /// but should not really be used during compilation, because it has an + /// internal cache that is context specific. const DataLayout DL; /// Triple string, CPU name, and target feature strings the TargetMachine @@ -125,9 +130,13 @@ return *static_cast(getSubtargetImpl(F)); } - /// This method returns a pointer to the DataLayout for the target. It should - /// be unchanging for every subtarget. - const DataLayout *getDataLayout() const { return &DL; } + /// Create a DataLayout. + const DataLayout createDataLayout() const { return DL; } + + /// Get the pointer size for this target. + /// + /// This is the only time the DataLayout in the TargetMachine is used. + unsigned getPointerSize() const { return DL.getPointerSize(); } /// \brief Reset the target options based on the function's attributes. // FIXME: Remove TargetOptions that affect per-function code generation Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -139,9 +139,9 @@ return MMI->getModule()->getDataLayout(); } -unsigned AsmPrinter::getPointerSize() const { - return TM.getDataLayout()->getPointerSize(); -} +// Do not use the cached DataLayout because some client use it without a Module +// (llmv-dsymutil, llvm-dwarfdump). +unsigned AsmPrinter::getPointerSize() const { return TM.getPointerSize(); } const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const { assert(MF && "getSubtargetInfo requires a valid MachineFunction!"); Index: lib/ExecutionEngine/MCJIT/MCJIT.cpp =================================================================== --- lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -68,7 +68,7 @@ MCJIT::MCJIT(std::unique_ptr M, std::unique_ptr TM, std::shared_ptr MemMgr, std::shared_ptr Resolver) - : ExecutionEngine(*TM->getDataLayout(), std::move(M)), TM(std::move(TM)), + : ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)), Ctx(nullptr), MemMgr(std::move(MemMgr)), Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver), ObjCache(nullptr) { Index: lib/ExecutionEngine/Orc/OrcMCJITReplacement.h =================================================================== --- lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -140,7 +140,7 @@ std::shared_ptr MemMgr, std::shared_ptr ClientResolver, std::unique_ptr TM) - : ExecutionEngine(*TM->getDataLayout()), TM(std::move(TM)), + : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)), Resolver(*this), ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this), NotifyFinalized(*this), Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -521,7 +521,7 @@ legacy::PassManager passes; // Add an appropriate DataLayout instance for this module... - mergedModule->setDataLayout(*TargetMach->getDataLayout()); + mergedModule->setDataLayout(TargetMach->createDataLayout()); passes.add( createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis())); Index: lib/LTO/LTOModule.cpp =================================================================== --- lib/LTO/LTOModule.cpp +++ lib/LTO/LTOModule.cpp @@ -232,7 +232,7 @@ TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); - M->setDataLayout(*target->getDataLayout()); + M->setDataLayout(target->createDataLayout()); std::unique_ptr IRObj( new object::IRObjectFile(Buffer, std::move(M))); Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -1370,7 +1370,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM, const SparcSubtarget &STI) : TargetLowering(TM), Subtarget(&STI) { - auto &DL = *TM.getDataLayout(); + MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize()); // Set up the register classes. addRegisterClass(MVT::i32, &SP::IntRegsRegClass); @@ -1396,10 +1396,10 @@ setTruncStoreAction(MVT::f128, MVT::f64, Expand); // Custom legalize GlobalAddress nodes into LO/HI parts. - setOperationAction(ISD::GlobalAddress, getPointerTy(DL), Custom); - setOperationAction(ISD::GlobalTLSAddress, getPointerTy(DL), Custom); - setOperationAction(ISD::ConstantPool, getPointerTy(DL), Custom); - setOperationAction(ISD::BlockAddress, getPointerTy(DL), Custom); + setOperationAction(ISD::GlobalAddress, PtrVT, Custom); + setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); + setOperationAction(ISD::ConstantPool, PtrVT, Custom); + setOperationAction(ISD::BlockAddress, PtrVT, Custom); // Sparc doesn't have sext_inreg, replace them with shl/sra setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -84,8 +84,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI) : TargetLowering(TM), Subtarget(STI) { - auto &DL = *TM.getDataLayout(); - MVT PtrVT = getPointerTy(DL); + MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize()); // Set up the register classes. if (Subtarget.hasHighWord()) Index: lib/Target/TargetMachineC.cpp =================================================================== --- lib/Target/TargetMachineC.cpp +++ lib/Target/TargetMachineC.cpp @@ -32,15 +32,25 @@ using namespace llvm; + +// The TargetMachine uses to offer access to a DataLayout member. This is reflected +// in the C API. For backward compatibility reason, this structure allows to keep +// a DataLayout member accessible to C client that have a handle to a +// LLVMTargetMachineRef. +struct LLVMOpaqueTargetMachine { + std::unique_ptr Machine; + DataLayout DL; +}; + + inline TargetMachine *unwrap(LLVMTargetMachineRef P) { - return reinterpret_cast(P); + return P->Machine.get(); } inline Target *unwrap(LLVMTargetRef P) { return reinterpret_cast(P); } inline LLVMTargetMachineRef wrap(const TargetMachine *P) { - return - reinterpret_cast(const_cast(P)); + return new LLVMOpaqueTargetMachine{ std::unique_ptr(const_cast(P)), P->createDataLayout() }; } inline LLVMTargetRef wrap(const Target * P) { return reinterpret_cast(const_cast(P)); @@ -147,7 +157,7 @@ void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { - delete unwrap(T); + delete T; } LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { @@ -170,8 +180,9 @@ return strdup(StringRep.c_str()); } +/// @deprecated: see "struct LLVMOpaqueTargetMachine" description above LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) { - return wrap(unwrap(T)->getDataLayout()); + return wrap(&T->DL); } void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T, @@ -190,14 +201,7 @@ std::string error; - const DataLayout *td = TM->getDataLayout(); - - if (!td) { - error = "No DataLayout in TargetMachine"; - *ErrorMessage = strdup(error.c_str()); - return true; - } - Mod->setDataLayout(*td); + Mod->setDataLayout(TM->createDataLayout()); TargetMachine::CodeGenFileType ft; switch (codegen) { Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -76,7 +76,7 @@ : TargetLowering(TM), Subtarget(&STI) { X86ScalarSSEf64 = Subtarget->hasSSE2(); X86ScalarSSEf32 = Subtarget->hasSSE1(); - TD = TM.getDataLayout(); + MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize()); // Set up the TargetLowering object. static const MVT IntVTs[] = { MVT::i8, MVT::i16, MVT::i32, MVT::i64 }; @@ -505,7 +505,7 @@ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - setOperationAction(ISD::DYNAMIC_STACKALLOC, getPointerTy(*TD), Custom); + setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); // GC_TRANSITION_START and GC_TRANSITION_END need custom lowering. setOperationAction(ISD::GC_TRANSITION_START, MVT::Other, Custom); @@ -16515,9 +16515,11 @@ for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I, ++Idx) - if (Attrs.hasAttribute(Idx, Attribute::InReg)) + if (Attrs.hasAttribute(Idx, Attribute::InReg)) { + auto &DL = DAG.getDataLayout(); // FIXME: should only count parameters that are lowered to integers. - InRegCount += (TD->getTypeSizeInBits(*I) + 31) / 32; + InRegCount += (DL.getTypeSizeInBits(*I) + 31) / 32; + } if (InRegCount > 2) { report_fatal_error("Nest register in use - reduce number of inreg" Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -312,8 +312,7 @@ PM.add(new TargetLibraryInfoWrapperPass(TLII)); // Add the target data from the target machine, if it exists, or the module. - if (const DataLayout *DL = Target->getDataLayout()) - M->setDataLayout(*DL); + M->setDataLayout(Target->createDataLayout()); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. Index: tools/lli/OrcLazyJIT.h =================================================================== --- tools/lli/OrcLazyJIT.h +++ tools/lli/OrcLazyJIT.h @@ -46,16 +46,17 @@ CallbackManagerBuilder; static CallbackManagerBuilder createCallbackManagerBuilder(Triple T); - - OrcLazyJIT(std::unique_ptr TM, LLVMContext &Context, - CallbackManagerBuilder &BuildCallbackMgr) - : TM(std::move(TM)), - ObjectLayer(), - CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), - IRDumpLayer(CompileLayer, createDebugDumper()), - CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)), - CODLayer(IRDumpLayer, *CCMgr, false), - CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {} + const DataLayout &DL; + + OrcLazyJIT(std::unique_ptr TM, const DataLayout &DL, + LLVMContext &Context, CallbackManagerBuilder &BuildCallbackMgr) + : DL(DL), TM(std::move(TM)), ObjectLayer(), + CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), + IRDumpLayer(CompileLayer, createDebugDumper()), + CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)), + CODLayer(IRDumpLayer, *CCMgr, false), + CXXRuntimeOverrides( + [this](const std::string &S) { return mangle(S); }) {} ~OrcLazyJIT() { // Run any destructors registered with __cxa_atexit. @@ -73,7 +74,7 @@ ModuleHandleT addModule(std::unique_ptr M) { // Attach a data-layout if one isn't already present. if (M->getDataLayout().isDefault()) - M->setDataLayout(*TM->getDataLayout()); + M->setDataLayout(DL); // Record the static constructors and destructors. We have to do this before // we hand over ownership of the module to the JIT. @@ -131,12 +132,11 @@ } private: - std::string mangle(const std::string &Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, *TM->getDataLayout()); + Mangler::getNameWithPrefix(MangledNameStream, Name, DL); } return MangledName; } Index: tools/lli/OrcLazyJIT.cpp =================================================================== --- tools/lli/OrcLazyJIT.cpp +++ tools/lli/OrcLazyJIT.cpp @@ -136,7 +136,8 @@ } // Everything looks good. Build the JIT. - OrcLazyJIT J(std::move(TM), Context, CallbackMgrBuilder); + auto &DL = M->getDataLayout(); + OrcLazyJIT J(std::move(TM), DL, Context, CallbackMgrBuilder); // Add the module, look up main and run it. auto MainHandle = J.addModule(std::move(M));