Skip to content

Commit

Permalink
copy module before running llvm codegen output passes (fix #11878)
Browse files Browse the repository at this point in the history
llvm may modify the Module during codegen output (as was observed to happen on ARM), so it is better to run the code emission passes on a copy rather than the actual shadow module
  • Loading branch information
vtjnash committed Jul 8, 2015
1 parent 584308d commit 050eedb
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 62 deletions.
71 changes: 32 additions & 39 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,63 +357,56 @@ extern "C" {
}
#endif

static void jl_gen_llvm_gv_array(llvm::Module *mod, SmallVector<GlobalVariable*, 8> &globalvars)
static void jl_gen_llvm_gv_array(llvm::Module *mod)
{
// emit the variable table into the code image. used just before dumping bitcode.
// afterwards, call eraseFromParent on everything in globalvars to reset code generator.
ArrayType *atype = ArrayType::get(T_psize,jl_sysimg_gvars.size());
globalvars.push_back(addComdat(new GlobalVariable(
*mod,
atype,
true,
GlobalVariable::ExternalLinkage,
ConstantArray::get(atype, ArrayRef<Constant*>(jl_sysimg_gvars)),
"jl_sysimg_gvars")));
globalvars.push_back(addComdat(new GlobalVariable(
*mod,
T_size,
true,
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_size,globalUnique+1),
"jl_globalUnique")));
addComdat(new GlobalVariable(*mod,
atype,
true,
GlobalVariable::ExternalLinkage,
ConstantArray::get(atype, ArrayRef<Constant*>(jl_sysimg_gvars)),
"jl_sysimg_gvars"));
addComdat(new GlobalVariable(*mod,
T_size,
true,
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_size,globalUnique+1),
"jl_globalUnique"));

Constant *feature_string = ConstantDataArray::getString(jl_LLVMContext, jl_options.cpu_target);
globalvars.push_back(addComdat(new GlobalVariable(
*mod,
feature_string->getType(),
true,
GlobalVariable::ExternalLinkage,
feature_string,
"jl_sysimg_cpu_target")));
addComdat(new GlobalVariable(*mod,
feature_string->getType(),
true,
GlobalVariable::ExternalLinkage,
feature_string,
"jl_sysimg_cpu_target"));

#ifdef HAVE_CPUID
// For native also store the cpuid
if (strcmp(jl_options.cpu_target,"native") == 0) {
uint32_t info[4];

jl_cpuid((int32_t*)info, 1);
globalvars.push_back(addComdat(new GlobalVariable(
*mod,
T_int64,
true,
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_int64,((uint64_t)info[2])|(((uint64_t)info[3])<<32)),
"jl_sysimg_cpu_cpuid")));
addComdat(new GlobalVariable(*mod,
T_int64,
true,
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_int64,((uint64_t)info[2])|(((uint64_t)info[3])<<32)),
"jl_sysimg_cpu_cpuid"));
}
#endif
}

static void jl_sysimg_to_llvm(llvm::Module *mod, SmallVector<GlobalVariable*, 8> &globalvars,
const char *sysimg_data, size_t sysimg_len)
static void jl_sysimg_to_llvm(llvm::Module *mod, const char *sysimg_data, size_t sysimg_len)
{
Constant *data = ConstantDataArray::get(jl_LLVMContext, ArrayRef<uint8_t>((const unsigned char*)sysimg_data, sysimg_len));
globalvars.push_back(addComdat(new GlobalVariable(*mod, data->getType(), true,
GlobalVariable::ExternalLinkage,
data, "jl_system_image_data")));
addComdat(new GlobalVariable(*mod, data->getType(), true,
GlobalVariable::ExternalLinkage,
data, "jl_system_image_data"));
Constant *len = ConstantInt::get(T_size, sysimg_len);
globalvars.push_back(addComdat(new GlobalVariable(*mod, len->getType(), true,
GlobalVariable::ExternalLinkage,
len, "jl_system_image_size")));
addComdat(new GlobalVariable(*mod, len->getType(), true,
GlobalVariable::ExternalLinkage,
len, "jl_system_image_size"));
}

static int32_t jl_assign_functionID(Function *functionObject)
Expand Down
41 changes: 18 additions & 23 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,8 @@ struct jl_varinfo_t {
};

// --- helpers for reloading IR image
static void jl_gen_llvm_gv_array(llvm::Module *mod, SmallVector<GlobalVariable*, 8> &globalvars);
static void jl_sysimg_to_llvm(llvm::Module *mod, SmallVector<GlobalVariable*, 8> &globalvars,
const char *sysimg_data, size_t sysimg_len);
static void jl_gen_llvm_gv_array(llvm::Module *mod);
static void jl_sysimg_to_llvm(llvm::Module *mod, const char *sysimg_data, size_t sysimg_len);

extern "C"
void jl_dump_bitcode(char *fname)
Expand All @@ -414,17 +413,15 @@ void jl_dump_bitcode(char *fname)
std::string err;
raw_fd_ostream OS(fname, err);
#endif
SmallVector<GlobalVariable*, 8> globalvars;
#ifdef USE_MCJIT
jl_gen_llvm_gv_array(shadow_module, globalvars);
WriteBitcodeToFile(shadow_module, OS);
Module *bitcode = CloneModule(shadow_module);
jl_gen_llvm_gv_array(bitcode);
WriteBitcodeToFile(bitcode, OS);
#else
jl_gen_llvm_gv_array(jl_Module, globalvars);
WriteBitcodeToFile(jl_Module, OS);
Module *bitcode = CloneModule(jl_Module);
jl_gen_llvm_gv_array(bitcode, globalvars);
WriteBitcodeToFile(bitcode, OS);
#endif
for (SmallVectorImpl<GlobalVariable>::iterator *I = globalvars.begin(), *E = globalvars.end(); I != E; ++I) {
(*I)->eraseFromParent();
}
}

extern "C"
Expand Down Expand Up @@ -505,26 +502,24 @@ void jl_dump_objfile(char *fname, int jit_model, const char *sysimg_data, size_t
jl_error("Could not generate obj file for this target");
}

SmallVector<GlobalVariable*, 8> globalvars;
#ifdef USE_MCJIT
Module *objfile = CloneModule(shadow_module);
if (sysimg_data)
jl_sysimg_to_llvm(shadow_module, globalvars, sysimg_data, sysimg_len);
jl_gen_llvm_gv_array(shadow_module, globalvars);
jl_sysimg_to_llvm(objfile, sysimg_data, sysimg_len);
jl_gen_llvm_gv_array(objfile);
// Reset the target triple to make sure it matches the new target machine
#ifdef LLVM37
shadow_module->setTargetTriple(TM->getTargetTriple().str());
shadow_module->setDataLayout(TM->getDataLayout()->getStringRepresentation());
objfile->setTargetTriple(TM->getTargetTriple().str());
objfile->setDataLayout(TM->getDataLayout()->getStringRepresentation());
#endif
PM.run(*shadow_module);
PM.run(*objfile);
#else
Module *objfile = CloneModule(jl_Module);
if (sysimg_data)
jl_sysimg_to_llvm(jl_Module, globalvars, sysimg_data, sysimg_len);
jl_gen_llvm_gv_array(jl_Module, globalvars);
PM.run(*jl_Module);
jl_sysimg_to_llvm(objfile, sysimg_data, sysimg_len);
jl_gen_llvm_gv_array(objfile);
PM.run(*objfile);
#endif
for (SmallVectorImpl<GlobalVariable>::iterator *I = globalvars.begin(), *E = globalvars.end(); I != E; ++I) {
(*I)->eraseFromParent();
}
}

// aggregate of array metadata
Expand Down

0 comments on commit 050eedb

Please sign in to comment.