From a16289e8fb875f5debdc18ddc8a70dc4698a630a Mon Sep 17 00:00:00 2001 From: Prem Chintalapudi Date: Thu, 13 Jan 2022 17:49:23 -0500 Subject: [PATCH 1/5] Remove jl_data_layout and jl_TargetMachine --- src/aotcompile.cpp | 20 +++---- src/codegen.cpp | 86 ++------------------------- src/disasm.cpp | 4 +- src/jitlayers.cpp | 122 +++++++++++++++++++++++++++++++++------ src/jitlayers.h | 10 ++-- src/llvm-cpufeatures.cpp | 5 +- 6 files changed, 129 insertions(+), 118 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 8a0d54b8a5932..a543a6d7d5fbd 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -445,7 +445,7 @@ void jl_dump_native_impl(void *native_code, // We don't want to use MCJIT's target machine because // it uses the large code model and we may potentially // want less optimizations there. - Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple()); + Triple TheTriple = Triple(jl_ExecutionEngine->getTargetTriple()); // make sure to emit the native object format, even if FORCE_ELF was set in codegen #if defined(_OS_WINDOWS_) TheTriple.setObjectFormat(Triple::COFF); @@ -454,11 +454,11 @@ void jl_dump_native_impl(void *native_code, TheTriple.setOS(llvm::Triple::MacOSX); #endif std::unique_ptr TM( - jl_TargetMachine->getTarget().createTargetMachine( + jl_ExecutionEngine->getTargetMachine().getTarget().createTargetMachine( TheTriple.getTriple(), - jl_TargetMachine->getTargetCPU(), - jl_TargetMachine->getTargetFeatureString(), - jl_TargetMachine->Options, + jl_ExecutionEngine->getTargetMachine().getTargetCPU(), + jl_ExecutionEngine->getTargetMachine().getTargetFeatureString(), + jl_ExecutionEngine->getTargetMachine().Options, #if defined(_OS_LINUX_) || defined(_OS_FREEBSD_) Reloc::PIC_, #else @@ -508,7 +508,7 @@ void jl_dump_native_impl(void *native_code, jl_safe_printf("ERROR: target does not support generation of object files\n"); // Reset the target triple to make sure it matches the new target machine - data->M->setTargetTriple(TM->getTargetTriple().str()); + data->M->setTargetTriple(jl_ExecutionEngine->getTargetTriple().str()); DataLayout DL = TM->createDataLayout(); DL.reset(DL.getStringRepresentation() + "-ni:10:11:12:13"); data->M->setDataLayout(DL); @@ -850,9 +850,9 @@ class JuliaPipeline : public Pass { (void)jl_init_llvm(); PMTopLevelManager *TPM = Stack.top()->getTopLevelManager(); TPMAdapter Adapter(TPM); - addTargetPasses(&Adapter, jl_TargetMachine); + addTargetPasses(&Adapter, &jl_ExecutionEngine->getTargetMachine()); addOptimizationPasses(&Adapter, OptLevel); - addMachinePasses(&Adapter, jl_TargetMachine, OptLevel); + addMachinePasses(&Adapter, &jl_ExecutionEngine->getTargetMachine(), OptLevel); } JuliaPipeline() : Pass(PT_PassManager, ID) {} Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const override { @@ -979,9 +979,9 @@ void *jl_get_llvmf_defn_impl(jl_method_instance_t *mi, LLVMContextRef ctxt, size static legacy::PassManager *PM; if (!PM) { PM = new legacy::PassManager(); - addTargetPasses(PM, jl_TargetMachine); + addTargetPasses(PM, &jl_ExecutionEngine->getTargetMachine()); addOptimizationPasses(PM, jl_options.opt_level); - addMachinePasses(PM, jl_TargetMachine, jl_options.opt_level); + addMachinePasses(PM, &jl_ExecutionEngine->getTargetMachine(), jl_options.opt_level); } // get the source code for this function diff --git a/src/codegen.cpp b/src/codegen.cpp index d188e948a383d..a7578a8d206c1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -211,8 +211,6 @@ extern void _chkstk(void); bool imaging_mode = false; // shared llvm state -TargetMachine *jl_TargetMachine; -static DataLayout &jl_data_layout = *(new DataLayout("")); #define jl_Module ctx.f->getParent() #define jl_builderModule(builder) (builder).GetInsertBlock()->getParent()->getParent() #define prepare_call(Callee) prepare_call_in(jl_Module, (Callee)) @@ -1917,8 +1915,8 @@ static void jl_setup_module(Module *m, const jl_cgparams_t *params = &jl_default if (!m->getModuleFlag("Debug Info Version")) m->addModuleFlag(llvm::Module::Warning, "Debug Info Version", llvm::DEBUG_METADATA_VERSION); - m->setDataLayout(jl_data_layout); - m->setTargetTriple(jl_TargetMachine->getTargetTriple().str()); + m->setDataLayout(jl_ExecutionEngine->getDataLayout()); + m->setTargetTriple(jl_ExecutionEngine->getTargetTriple().str()); #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION >= 130000 // tell Win32 to assume the stack is always 16-byte aligned, @@ -8239,86 +8237,10 @@ extern "C" void jl_init_llvm(void) if (clopt && clopt->getNumOccurrences() == 0) cl::ProvidePositionalOption(clopt, "4", 1); - TargetOptions options = TargetOptions(); - //options.PrintMachineCode = true; //Print machine code produced during JIT compiling -#if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION < 130000 - // tell Win32 to assume the stack is always 16-byte aligned, - // and to ensure that it is 16-byte aligned for out-going calls, - // to ensure compatibility with GCC codes - // In LLVM 13 and onwards this has turned into a module option - options.StackAlignmentOverride = 16; -#endif -#if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION < 130000 - // LLVM defaults to tls stack guard, which causes issues with Julia's tls implementation - options.StackProtectorGuard = StackProtectorGuards::Global; -#endif - Triple TheTriple(sys::getProcessTriple()); -#if defined(FORCE_ELF) - TheTriple.setObjectFormat(Triple::ELF); -#endif - uint32_t target_flags = 0; - auto target = jl_get_llvm_target(imaging_mode, target_flags); - auto &TheCPU = target.first; - SmallVector targetFeatures(target.second.begin(), target.second.end()); - std::string errorstr; - const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, errorstr); - if (!TheTarget) - jl_errorf("%s", errorstr.c_str()); - if (jl_processor_print_help || (target_flags & JL_TARGET_UNKNOWN_NAME)) { - std::unique_ptr MSTI( - TheTarget->createMCSubtargetInfo(TheTriple.str(), "", "")); - if (!MSTI->isCPUStringValid(TheCPU)) - jl_errorf("Invalid CPU name \"%s\".", TheCPU.c_str()); - if (jl_processor_print_help) { - // This is the only way I can find to print the help message once. - // It'll be nice if we can iterate through the features and print our own help - // message... - MSTI->setDefaultFeatures("help", "", ""); - } - } - // Package up features to be passed to target/subtarget - std::string FeaturesStr; - if (!targetFeatures.empty()) { - SubtargetFeatures Features; - for (unsigned i = 0; i != targetFeatures.size(); ++i) - Features.AddFeature(targetFeatures[i]); - FeaturesStr = Features.getString(); - } - // Allocate a target... - Optional codemodel = -#if defined(JL_USE_JITLINK) - // JITLink can patch up relocations between far objects so we can use the - // small code model – which is good, as the large code model is unmaintained - // on MachO/AArch64. - CodeModel::Small; -#elif defined(_P64) - // Make sure we are using the large code model on 64bit - // Let LLVM pick a default suitable for jitting on 32bit - CodeModel::Large; -#else - None; -#endif - auto optlevel = CodeGenOptLevelFor(jl_options.opt_level); - jl_TargetMachine = TheTarget->createTargetMachine( - TheTriple.getTriple(), TheCPU, FeaturesStr, - options, - Reloc::Static, // Generate simpler code for JIT - codemodel, - optlevel, - true // JIT - ); - assert(jl_TargetMachine && "Failed to select target machine -" - " Is the LLVM backend for this CPU enabled?"); - #if (!defined(_CPU_ARM_) && !defined(_CPU_PPC64_)) - // FastISel seems to be buggy for ARM. Ref #13321 - if (jl_options.opt_level < 2) - jl_TargetMachine->setFastISel(true); - #endif - - jl_ExecutionEngine = new JuliaOJIT(*jl_TargetMachine, new LLVMContext()); + jl_ExecutionEngine = new JuliaOJIT(new LLVMContext()); // Mark our address spaces as non-integral - jl_data_layout = jl_ExecutionEngine->getDataLayout(); + auto &jl_data_layout = jl_ExecutionEngine->getDataLayout(); std::string DL = jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"; jl_data_layout.reset(DL); diff --git a/src/disasm.cpp b/src/disasm.cpp index b4c14d020538f..0ae3e29eb1699 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -1201,7 +1201,7 @@ jl_value_t *jl_dump_function_asm_impl(void *F, char raw_mc, const char* asm_vari if (f != &f2 && !f->isDeclaration()) f2.deleteBody(); } - LLVMTargetMachine *TM = static_cast(jl_TargetMachine); + LLVMTargetMachine *TM = static_cast(&jl_ExecutionEngine->getTargetMachine()); legacy::PassManager PM; addTargetPasses(&PM, TM); if (raw_mc) { @@ -1226,7 +1226,7 @@ jl_value_t *jl_dump_function_asm_impl(void *F, char raw_mc, const char* asm_vari if (!strcmp(asm_variant, "intel")) OutputAsmDialect = 1; MCInstPrinter *InstPrinter = TM->getTarget().createMCInstPrinter( - TM->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI); + jl_ExecutionEngine->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI); std::unique_ptr MAB(TM->getTarget().createMCAsmBackend( STI, MRI, TM->Options.MCOptions)); std::unique_ptr MCE; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 5d19deaba1c71..b8b46f5402c5f 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -15,15 +15,21 @@ #include #include #include +#include +#include +#include + +// target machine computation +#include #if JL_LLVM_VERSION >= 140000 #include #else #include #endif -#include -#include -#include -#include +#include +#include +#include +#include using namespace llvm; @@ -32,6 +38,7 @@ using namespace llvm; #include "codegen_shared.h" #include "jitlayers.h" #include "julia_assert.h" +#include "processor.h" #ifdef JL_USE_JITLINK # if JL_LLVM_VERSION >= 140000 @@ -789,6 +796,82 @@ void registerRTDyldJITObject(const object::ObjectFile &Object, ); } #endif +namespace { + std::unique_ptr createTargetMachine() { + + TargetOptions options = TargetOptions(); + //options.PrintMachineCode = true; //Print machine code produced during JIT compiling + #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION < 130000 + // tell Win32 to assume the stack is always 16-byte aligned, + // and to ensure that it is 16-byte aligned for out-going calls, + // to ensure compatibility with GCC codes + // In LLVM 13 and onwards this has turned into a module option + options.StackAlignmentOverride = 16; + #endif + #if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION < 130000 + // LLVM defaults to tls stack guard, which causes issues with Julia's tls implementation + options.StackProtectorGuard = StackProtectorGuards::Global; + #endif + Triple TheTriple(sys::getProcessTriple()); + #if defined(FORCE_ELF) + TheTriple.setObjectFormat(Triple::ELF); + #endif + uint32_t target_flags = 0; + auto target = jl_get_llvm_target(imaging_mode, target_flags); + auto &TheCPU = target.first; + SmallVector targetFeatures(target.second.begin(), target.second.end()); + std::string errorstr; + const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple, errorstr); + if (!TheTarget) + jl_errorf("%s", errorstr.c_str()); + if (jl_processor_print_help || (target_flags & JL_TARGET_UNKNOWN_NAME)) { + std::unique_ptr MSTI( + TheTarget->createMCSubtargetInfo(TheTriple.str(), "", "")); + if (!MSTI->isCPUStringValid(TheCPU)) + jl_errorf("Invalid CPU name \"%s\".", TheCPU.c_str()); + if (jl_processor_print_help) { + // This is the only way I can find to print the help message once. + // It'll be nice if we can iterate through the features and print our own help + // message... + MSTI->setDefaultFeatures("help", "", ""); + } + } + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (!targetFeatures.empty()) { + SubtargetFeatures Features; + for (unsigned i = 0; i != targetFeatures.size(); ++i) + Features.AddFeature(targetFeatures[i]); + FeaturesStr = Features.getString(); + } + // Allocate a target... + Optional codemodel = +#ifdef _P64 + // Make sure we are using the large code model on 64bit + // Let LLVM pick a default suitable for jitting on 32bit + CodeModel::Large; +#else + None; +#endif + auto optlevel = CodeGenOptLevelFor(jl_options.opt_level); + auto TM = TheTarget->createTargetMachine( + TheTriple.getTriple(), TheCPU, FeaturesStr, + options, + Reloc::Static, // Generate simpler code for JIT + codemodel, + optlevel, + true // JIT + ); + assert(TM && "Failed to select target machine -" + " Is the LLVM backend for this CPU enabled?"); + #if (!defined(_CPU_ARM_) && !defined(_CPU_PPC64_)) + // FastISel seems to be buggy for ARM. Ref #13321 + if (jl_options.opt_level < 2) + TM->setFastISel(true); + #endif + return std::unique_ptr(TM); + } +} // namespace namespace { orc::JITTargetMachineBuilder createJTMBFromTM(TargetMachine &TM, int optlevel) { @@ -802,14 +885,14 @@ namespace { } } -JuliaOJIT::JuliaOJIT(TargetMachine &TM, LLVMContext *LLVMCtx) - : TM(TM), - DL(TM.createDataLayout()), +JuliaOJIT::JuliaOJIT(LLVMContext *LLVMCtx) + : TM(createTargetMachine()), + DL(TM->createDataLayout()), TMs{ - cantFail(createJTMBFromTM(TM, 0).createTargetMachine()), - cantFail(createJTMBFromTM(TM, 1).createTargetMachine()), - cantFail(createJTMBFromTM(TM, 2).createTargetMachine()), - cantFail(createJTMBFromTM(TM, 3).createTargetMachine()) + cantFail(createJTMBFromTM(*TM, 0).createTargetMachine()), + cantFail(createJTMBFromTM(*TM, 1).createTargetMachine()), + cantFail(createJTMBFromTM(*TM, 2).createTargetMachine()), + cantFail(createJTMBFromTM(*TM, 3).createTargetMachine()) }, TSCtx(std::unique_ptr(LLVMCtx)), #if JL_LLVM_VERSION >= 130000 @@ -837,10 +920,10 @@ JuliaOJIT::JuliaOJIT(TargetMachine &TM, LLVMContext *LLVMCtx) } ), #endif - CompileLayer0(ES, ObjectLayer, std::make_unique(createJTMBFromTM(TM, 0))), - CompileLayer1(ES, ObjectLayer, std::make_unique(createJTMBFromTM(TM, 1))), - CompileLayer2(ES, ObjectLayer, std::make_unique(createJTMBFromTM(TM, 2))), - CompileLayer3(ES, ObjectLayer, std::make_unique(createJTMBFromTM(TM, 3))), + CompileLayer0(ES, ObjectLayer, std::make_unique(createJTMBFromTM(*TM, 0))), + CompileLayer1(ES, ObjectLayer, std::make_unique(createJTMBFromTM(*TM, 1))), + CompileLayer2(ES, ObjectLayer, std::make_unique(createJTMBFromTM(*TM, 2))), + CompileLayer3(ES, ObjectLayer, std::make_unique(createJTMBFromTM(*TM, 3))), OptimizeLayers{ {ES, CompileLayer0, OptimizerT(PM0, 0)}, {ES, CompileLayer1, OptimizerT(PM1, 1)}, @@ -1058,14 +1141,19 @@ orc::ThreadSafeContext &JuliaOJIT::getContext() { return TSCtx; } -const DataLayout& JuliaOJIT::getDataLayout() const +DataLayout& JuliaOJIT::getDataLayout() { return DL; } +TargetMachine &JuliaOJIT::getTargetMachine() +{ + return *TM; +} + const Triple& JuliaOJIT::getTargetTriple() const { - return TM.getTargetTriple(); + return TM->getTargetTriple(); } std::string JuliaOJIT::getMangledName(StringRef Name) diff --git a/src/jitlayers.h b/src/jitlayers.h index 6c55001551b16..803a0d85a5a30 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -48,7 +48,6 @@ using namespace llvm; extern "C" jl_cgparams_t jl_default_cgparams; -extern TargetMachine *jl_TargetMachine; extern bool imaging_mode; void addTargetPasses(legacy::PassManagerBase *PM, TargetMachine *TM); @@ -218,7 +217,7 @@ class JuliaOJIT { public: - JuliaOJIT(TargetMachine &TM, LLVMContext *Ctx); + JuliaOJIT(LLVMContext *Ctx); void enableJITDebuggingSupport(); #ifndef JL_USE_JITLINK @@ -235,15 +234,16 @@ class JuliaOJIT { uint64_t getFunctionAddress(StringRef Name); StringRef getFunctionAtAddress(uint64_t Addr, jl_code_instance_t *codeinst); orc::ThreadSafeContext &getContext(); - const DataLayout& getDataLayout() const; + DataLayout& getDataLayout(); + TargetMachine &getTargetMachine(); const Triple& getTargetTriple() const; size_t getTotalBytes() const; private: std::string getMangledName(StringRef Name); std::string getMangledName(const GlobalValue *GV); - TargetMachine &TM; - const DataLayout DL; + std::unique_ptr TM; + DataLayout DL; // Should be big enough that in the common case, The // object fits in its entirety legacy::PassManager PM0; // per-optlevel pass managers diff --git a/src/llvm-cpufeatures.cpp b/src/llvm-cpufeatures.cpp index ec0767d63e18b..15b017785ba61 100644 --- a/src/llvm-cpufeatures.cpp +++ b/src/llvm-cpufeatures.cpp @@ -25,12 +25,13 @@ #include #include "julia.h" +#include "jitlayers.h" #define DEBUG_TYPE "cpufeatures" using namespace llvm; -extern TargetMachine *jl_TargetMachine; +extern JuliaOJIT *jl_ExecutionEngine; // whether this platform unconditionally (i.e. without needing multiversioning) supports FMA Optional always_have_fma(Function &intr) { @@ -55,7 +56,7 @@ bool have_fma(Function &intr, Function &caller) { Attribute FSAttr = caller.getFnAttribute("target-features"); StringRef FS = - FSAttr.isValid() ? FSAttr.getValueAsString() : jl_TargetMachine->getTargetFeatureString(); + FSAttr.isValid() ? FSAttr.getValueAsString() : jl_ExecutionEngine->getTargetMachine().getTargetFeatureString(); SmallVector Features; FS.split(Features, ','); From 4ba6871f6da1f5ee84a9b30d9e542b216a5d62c2 Mon Sep 17 00:00:00 2001 From: Prem Chintalapudi Date: Fri, 21 Jan 2022 22:19:29 -0500 Subject: [PATCH 2/5] Move FORCE_ELF define --- src/codegen.cpp | 5 ----- src/jitlayers.cpp | 17 +++++++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index a7578a8d206c1..6164c7b426fd6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2,11 +2,6 @@ #include "llvm-version.h" #include "platform.h" -#if defined(_OS_WINDOWS_) -// use ELF because RuntimeDyld COFF i686 support didn't exist -// use ELF because RuntimeDyld COFF X86_64 doesn't seem to work (fails to generate function pointers)? -#define FORCE_ELF -#endif #if defined(_CPU_X86_) #define JL_NEED_FLOATTEMP_VAR 1 #endif diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index b8b46f5402c5f..bd4c5f110393f 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -800,22 +800,27 @@ namespace { std::unique_ptr createTargetMachine() { TargetOptions options = TargetOptions(); +#if defined(_OS_WINDOWS_) + // use ELF because RuntimeDyld COFF i686 support didn't exist + // use ELF because RuntimeDyld COFF X86_64 doesn't seem to work (fails to generate function pointers)? +#define FORCE_ELF +#endif //options.PrintMachineCode = true; //Print machine code produced during JIT compiling - #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION < 130000 +#if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION < 130000 // tell Win32 to assume the stack is always 16-byte aligned, // and to ensure that it is 16-byte aligned for out-going calls, // to ensure compatibility with GCC codes // In LLVM 13 and onwards this has turned into a module option options.StackAlignmentOverride = 16; - #endif - #if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION < 130000 +#endif +#if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION < 130000 // LLVM defaults to tls stack guard, which causes issues with Julia's tls implementation options.StackProtectorGuard = StackProtectorGuards::Global; - #endif +#endif Triple TheTriple(sys::getProcessTriple()); - #if defined(FORCE_ELF) +#if defined(FORCE_ELF) TheTriple.setObjectFormat(Triple::ELF); - #endif +#endif uint32_t target_flags = 0; auto target = jl_get_llvm_target(imaging_mode, target_flags); auto &TheCPU = target.first; From c154c5475560fa9f1349bfb02185312a9e96caf0 Mon Sep 17 00:00:00 2001 From: Prem Chintalapudi Date: Fri, 21 Jan 2022 23:00:48 -0500 Subject: [PATCH 3/5] Fuse jl_setup_module into _jl_create_llvm_module --- src/codegen.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 6164c7b426fd6..6fcafae71dc7d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1894,8 +1894,9 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_ return jl_cgval_t(v, typ, new_tindex); } -static void jl_setup_module(Module *m, const jl_cgparams_t *params = &jl_default_cgparams) +Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cgparams_t *params) { + Module *m = new Module(name, context); // Some linkers (*cough* OS X) don't understand DWARF v4, so we use v2 in // imaging mode. The structure of v4 is slightly nicer for debugging JIT // code. @@ -1922,13 +1923,7 @@ static void jl_setup_module(Module *m, const jl_cgparams_t *params = &jl_default #if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION >= 130000 m->setStackProtectorGuard("global"); #endif -} - -Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cgparams_t *params) -{ - Module *M = new Module(name, context); - jl_setup_module(M, params); - return M; + return m; } Module *jl_create_llvm_module(StringRef name, LLVMContext &context) From 44943c2a323caef76ecf6c8a633682884bd252f9 Mon Sep 17 00:00:00 2001 From: Prem Chintalapudi Date: Fri, 28 Jan 2022 14:10:11 -0500 Subject: [PATCH 4/5] Make data_layout const --- src/Makefile | 1 + src/codegen.cpp | 5 ----- src/jitlayers.cpp | 12 ++++++++++-- src/jitlayers.h | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Makefile b/src/Makefile index b673dda90116c..ea3fa34da29b5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -297,6 +297,7 @@ $(BUILDDIR)/jltypes.o $(BUILDDIR)/jltypes.dbg.obj: $(SRCDIR)/builtin_proto.h $(build_shlibdir)/libllvmcalltest.$(SHLIB_EXT): $(SRCDIR)/codegen_shared.h $(BUILDDIR)/julia_version.h $(BUILDDIR)/llvm-alloc-helpers.o $(BUILDDIR)/llvm-alloc-helpers.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-alloc-helpers.h $(BUILDDIR)/llvm-alloc-opt.o $(BUILDDIR)/llvm-alloc-opt.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-alloc-helpers.h +$(BUILDDIR)/llvm-cpufeatures.o $(BUILDDIR)/llvm-cpufeatures.dbg.obj: $(SRCDIR)/jitlayers.h $(BUILDDIR)/llvm-final-gc-lowering.o $(BUILDDIR)/llvm-final-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(BUILDDIR)/llvm-gc-invariant-verifier.o $(BUILDDIR)/llvm-gc-invariant-verifier.dbg.obj: $(SRCDIR)/codegen_shared.h $(BUILDDIR)/llvm-julia-licm.o $(BUILDDIR)/llvm-julia-licm.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/llvm-alloc-helpers.h $(SRCDIR)/llvm-pass-helpers.h diff --git a/src/codegen.cpp b/src/codegen.cpp index 6fcafae71dc7d..e62078f70add6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8229,11 +8229,6 @@ extern "C" void jl_init_llvm(void) jl_ExecutionEngine = new JuliaOJIT(new LLVMContext()); - // Mark our address spaces as non-integral - auto &jl_data_layout = jl_ExecutionEngine->getDataLayout(); - std::string DL = jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"; - jl_data_layout.reset(DL); - // Register GDB event listener #if defined(JL_DEBUG_BUILD) jl_using_gdb_jitevents = 1; diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index bd4c5f110393f..6cdd07fda83de 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -876,6 +876,14 @@ namespace { #endif return std::unique_ptr(TM); } + + llvm::DataLayout createDataLayout(TargetMachine &TM) { + // Mark our address spaces as non-integral + auto jl_data_layout = TM.createDataLayout(); + std::string DL = jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"; + jl_data_layout.reset(DL); + return jl_data_layout; + } } // namespace namespace { @@ -892,7 +900,7 @@ namespace { JuliaOJIT::JuliaOJIT(LLVMContext *LLVMCtx) : TM(createTargetMachine()), - DL(TM->createDataLayout()), + DL(createDataLayout(*TM)), TMs{ cantFail(createJTMBFromTM(*TM, 0).createTargetMachine()), cantFail(createJTMBFromTM(*TM, 1).createTargetMachine()), @@ -1146,7 +1154,7 @@ orc::ThreadSafeContext &JuliaOJIT::getContext() { return TSCtx; } -DataLayout& JuliaOJIT::getDataLayout() +const DataLayout& JuliaOJIT::getDataLayout() const { return DL; } diff --git a/src/jitlayers.h b/src/jitlayers.h index 803a0d85a5a30..dcc77a8ee2795 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -234,7 +234,7 @@ class JuliaOJIT { uint64_t getFunctionAddress(StringRef Name); StringRef getFunctionAtAddress(uint64_t Addr, jl_code_instance_t *codeinst); orc::ThreadSafeContext &getContext(); - DataLayout& getDataLayout(); + const DataLayout& getDataLayout() const; TargetMachine &getTargetMachine(); const Triple& getTargetTriple() const; size_t getTotalBytes() const; From cfa83a723a69e74528f6b8d0de3284fe66bf1987 Mon Sep 17 00:00:00 2001 From: Prem Chintalapudi Date: Fri, 18 Feb 2022 19:14:23 -0500 Subject: [PATCH 5/5] Parameterize jl_create_llvm_module with DataLayout and Triple --- src/aotcompile.cpp | 6 ++---- src/codegen.cpp | 14 +++++++------- src/jitlayers.cpp | 17 ++++++++--------- src/jitlayers.h | 3 ++- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index a543a6d7d5fbd..5e5fa131d260a 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -508,10 +508,8 @@ void jl_dump_native_impl(void *native_code, jl_safe_printf("ERROR: target does not support generation of object files\n"); // Reset the target triple to make sure it matches the new target machine - data->M->setTargetTriple(jl_ExecutionEngine->getTargetTriple().str()); - DataLayout DL = TM->createDataLayout(); - DL.reset(DL.getStringRepresentation() + "-ni:10:11:12:13"); - data->M->setDataLayout(DL); + data->M->setTargetTriple(TM->getTargetTriple().str()); + data->M->setDataLayout(create_jl_data_layout(*TM)); Type *T_size; if (sizeof(size_t) == 8) T_size = Type::getInt64Ty(Context); diff --git a/src/codegen.cpp b/src/codegen.cpp index e62078f70add6..225c4299281c3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1894,7 +1894,7 @@ static jl_cgval_t convert_julia_type(jl_codectx_t &ctx, const jl_cgval_t &v, jl_ return jl_cgval_t(v, typ, new_tindex); } -Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cgparams_t *params) +Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cgparams_t *params, const DataLayout &DL, const Triple &triple) { Module *m = new Module(name, context); // Some linkers (*cough* OS X) don't understand DWARF v4, so we use v2 in @@ -1911,8 +1911,8 @@ Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cg if (!m->getModuleFlag("Debug Info Version")) m->addModuleFlag(llvm::Module::Warning, "Debug Info Version", llvm::DEBUG_METADATA_VERSION); - m->setDataLayout(jl_ExecutionEngine->getDataLayout()); - m->setTargetTriple(jl_ExecutionEngine->getTargetTriple().str()); + m->setDataLayout(DL); + m->setTargetTriple(triple.str()); #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) && JL_LLVM_VERSION >= 130000 // tell Win32 to assume the stack is always 16-byte aligned, @@ -1926,9 +1926,9 @@ Module *_jl_create_llvm_module(StringRef name, LLVMContext &context, const jl_cg return m; } -Module *jl_create_llvm_module(StringRef name, LLVMContext &context) +Module *jl_create_llvm_module(StringRef name, LLVMContext &ctx, const DataLayout *DL, const Triple *triple) { - return _jl_create_llvm_module(name, context, &jl_default_cgparams); + return _jl_create_llvm_module(name, ctx, &jl_default_cgparams, DL ? *DL : jl_ExecutionEngine->getDataLayout(), triple ? *triple : jl_ExecutionEngine->getTargetTriple()); } static void jl_init_function(Function *F) @@ -6438,7 +6438,7 @@ static std::pair, jl_llvm_functions_t> declarations.specFunctionObject = funcName.str(); // allocate Function declarations and wrapper objects - Module *M = _jl_create_llvm_module(ctx.name, ctx.builder.getContext(), ctx.params); + Module *M = _jl_create_llvm_module(ctx.name, ctx.builder.getContext(), ctx.params, jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); jl_returninfo_t returninfo = {}; Function *f = NULL; bool has_sret = false; @@ -8294,7 +8294,7 @@ extern "C" JL_DLLEXPORT void jl_init_codegen_impl(void) jl_init_jit(); init_jit_functions(); - Module *m = _jl_create_llvm_module("julia", *jl_ExecutionEngine->getContext().getContext(), &jl_default_cgparams); + Module *m = _jl_create_llvm_module("julia", *jl_ExecutionEngine->getContext().getContext(), &jl_default_cgparams, jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); init_julia_llvm_env(m); jl_init_intrinsic_functions_codegen(); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 6cdd07fda83de..231b37778eae5 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -876,14 +876,6 @@ namespace { #endif return std::unique_ptr(TM); } - - llvm::DataLayout createDataLayout(TargetMachine &TM) { - // Mark our address spaces as non-integral - auto jl_data_layout = TM.createDataLayout(); - std::string DL = jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"; - jl_data_layout.reset(DL); - return jl_data_layout; - } } // namespace namespace { @@ -898,9 +890,16 @@ namespace { } } +llvm::DataLayout create_jl_data_layout(TargetMachine &TM) { + // Mark our address spaces as non-integral + auto jl_data_layout = TM.createDataLayout(); + jl_data_layout.reset(jl_data_layout.getStringRepresentation() + "-ni:10:11:12:13"); + return jl_data_layout; +} + JuliaOJIT::JuliaOJIT(LLVMContext *LLVMCtx) : TM(createTargetMachine()), - DL(createDataLayout(*TM)), + DL(create_jl_data_layout(*TM)), TMs{ cantFail(createJTMBFromTM(*TM, 0).createTargetMachine()), cantFail(createJTMBFromTM(*TM, 1).createTargetMachine()), diff --git a/src/jitlayers.h b/src/jitlayers.h index dcc77a8ee2795..035e81bead88d 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -55,8 +55,9 @@ void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool lowe void addMachinePasses(legacy::PassManagerBase *PM, TargetMachine *TM, int optlevel); void jl_finalize_module(std::unique_ptr m); void jl_merge_module(Module *dest, std::unique_ptr src); -Module *jl_create_llvm_module(StringRef name, LLVMContext &ctxt); +Module *jl_create_llvm_module(StringRef name, LLVMContext &ctx, const DataLayout *DL = nullptr, const Triple *triple = nullptr); GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M); +DataLayout create_jl_data_layout(TargetMachine &TM); typedef struct _jl_llvm_functions_t { std::string functionObject; // jlcall llvm Function name