Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/src/devdocs/llvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ environment. In addition, it exposes the `-julia` meta-pass, which runs the
entire Julia pass-pipeline over the IR. As an example, to generate a system
image, one could do:
```
opt -load libjulia-internal.so -julia -o opt.bc unopt.bc
opt -enable-new-pm=0 -load libjulia-internal.so -julia -o opt.bc unopt.bc
llc -o sys.o opt.bc
cc -shared -o sys.so sys.o
```
Expand Down
2 changes: 1 addition & 1 deletion src/abi_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Type *isHFAorHVA(jl_datatype_t *dt, size_t &nele, LLVMContext &ctx) const
return NULL;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
// B.2
// If the argument type is an HFA or an HVA, then the argument is used
Expand Down
2 changes: 1 addition & 1 deletion src/abi_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

struct ABI_ARMLayout : AbiLayout {

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &abi, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &abi, LLVMContext &ctx, Type *Ty) override
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/abi_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bool use_sret(jl_datatype_t *ty, LLVMContext &ctx) override
return false;
}

bool needPassByRef(jl_datatype_t *ty, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *ty, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
return false;
}
Expand Down
6 changes: 5 additions & 1 deletion src/abi_ppc64le.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,16 @@ bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override
return false;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
jl_datatype_t *ty0 = NULL;
bool hva = false;
if (jl_datatype_size(dt) > 64 && isHFA(dt, &ty0, &hva) > 8) {
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
ab.addByValAttr(Ty);
#endif
return true;
}
return false;
Expand Down
6 changes: 5 additions & 1 deletion src/abi_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override
return true;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
// Use pass by reference for all structs
if (dt->layout->nfields > 0) {
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
ab.addByValAttr(Ty);
#endif
return true;
}
return false;
Expand Down
9 changes: 7 additions & 2 deletions src/abi_win64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,19 @@ bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override
return true;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
nargs++;
size_t size = jl_datatype_size(dt);
if (win64_reg_size(size))
return false;
if (nargs <= 4)
if (nargs <= 4) {
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
ab.addByValAttr(Ty);
#endif
}
return true;
}

Expand Down
8 changes: 6 additions & 2 deletions src/abi_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,16 @@ bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override
return true;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
size_t size = jl_datatype_size(dt);
if (is_complex64(dt) || is_complex128(dt) || (jl_is_primitivetype(dt) && size <= 8))
return false;
ab.addAttribute(Attribute::ByVal);
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
ab.addByValAttr(Ty);
#endif
return true;
}

Expand Down
11 changes: 10 additions & 1 deletion src/abi_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,15 @@ bool use_sret(jl_datatype_t *dt, LLVMContext &ctx) override
return sret;
}

bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) override
bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *Ty) override
{
Classification cl = classify(dt);
if (cl.isMemory) {
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
ab.addByValAttr(Ty);
#endif
return true;
}

Expand All @@ -202,7 +206,12 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx) overrid
else if (jl_is_structtype(dt)) {
// spill to memory even though we would ordinarily pass
// it in registers
#if JL_LLVM_VERSION < 120000
ab.addAttribute(Attribute::ByVal);
#else
Type* Ty = preferred_llvm_type(dt, false, ctx);
ab.addByValAttr(Ty);
#endif
return true;
}
return false;
Expand Down
4 changes: 4 additions & 0 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@ void jl_dump_native_impl(void *native_code,
std::unique_ptr<Module> sysimage(new Module("sysimage", Context));
sysimage->setTargetTriple(data->M->getTargetTriple());
sysimage->setDataLayout(data->M->getDataLayout());
#if JL_LLVM_VERSION >= 130000
sysimage->setStackProtectorGuard(data->M->getStackProtectorGuard());
sysimage->setOverrideStackAlignment(data->M->getOverrideStackAlignment());
#endif
data->M.reset(); // free memory for data->M

if (sysimg_data) {
Expand Down
8 changes: 6 additions & 2 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ class AbiLayout {
public:
virtual ~AbiLayout() {}
virtual bool use_sret(jl_datatype_t *ty, LLVMContext &ctx) = 0;
virtual bool needPassByRef(jl_datatype_t *ty, AttrBuilder&, LLVMContext &ctx) = 0;
virtual bool needPassByRef(jl_datatype_t *ty, AttrBuilder&, LLVMContext &ctx, Type* llvm_t) = 0;
virtual Type *preferred_llvm_type(jl_datatype_t *ty, bool isret, LLVMContext &ctx) const = 0;
};

Expand Down Expand Up @@ -891,6 +891,10 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
// copy module properties that should always match
Mod->setTargetTriple(jl_Module->getTargetTriple());
Mod->setDataLayout(jl_Module->getDataLayout());
#if JL_LLVM_VERSION >= 130000
Mod->setStackProtectorGuard(jl_Module->getStackProtectorGuard());
Mod->setOverrideStackAlignment(jl_Module->getOverrideStackAlignment());
#endif

// verify the definition
Function *def = Mod->getFunction(ir_name);
Expand Down Expand Up @@ -1086,7 +1090,7 @@ std::string generate_func_sig(const char *fname)
}

// Whether or not LLVM wants us to emit a pointer to the data
bool byRef = abi->needPassByRef((jl_datatype_t*)tti, ab, jl_LLVMContext);
bool byRef = abi->needPassByRef((jl_datatype_t*)tti, ab, jl_LLVMContext, t);

if (jl_is_cpointer_type(tti)) {
pat = t;
Expand Down
21 changes: 16 additions & 5 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ extern JITEventListener *CreateJuliaJITEventListener();
bool imaging_mode = false;

// shared llvm state
JL_DLLEXPORT LLVMContext &jl_LLVMContext = *(new LLVMContext());
static LLVMContext &jl_LLVMContext = *(new LLVMContext());
TargetMachine *jl_TargetMachine;
static DataLayout &jl_data_layout = *(new DataLayout(""));
#define jl_Module ctx.f->getParent()
Expand Down Expand Up @@ -1707,6 +1707,16 @@ static void jl_setup_module(Module *m, const jl_cgparams_t *params = &jl_default
llvm::DEBUG_METADATA_VERSION);
m->setDataLayout(jl_data_layout);
m->setTargetTriple(jl_TargetMachine->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,
// and to ensure that it is 16-byte aligned for out-going calls,
// to ensure compatibility with GCC codes
m->setOverrideStackAlignment(16);
#endif
#if defined(JL_DEBUG_BUILD) && JL_LLVM_VERSION >= 130000
m->setStackProtectorGuard("global");
#endif
}

Module *jl_create_llvm_module(StringRef name)
Expand Down Expand Up @@ -4780,7 +4790,7 @@ static Value *get_current_task(jl_codectx_t &ctx)
// Get PTLS through current task.
static Value *get_current_ptls(jl_codectx_t &ctx)
{
return get_current_ptls_from_task(ctx.builder, get_current_task(ctx));
return get_current_ptls_from_task(ctx.builder, get_current_task(ctx), tbaa_gcframe);
}

// Store world age at the entry block of the function. This function should be
Expand Down Expand Up @@ -7679,7 +7689,7 @@ void jl_compile_workqueue(

// --- initialization ---

std::pair<MDNode*,MDNode*> tbaa_make_child(const char *name, MDNode *parent=nullptr, bool isConstant=false)
static std::pair<MDNode*,MDNode*> tbaa_make_child(const char *name, MDNode *parent=nullptr, bool isConstant=false)
{
MDBuilder mbuilder(jl_LLVMContext);
if (tbaa_root == nullptr) {
Expand Down Expand Up @@ -8033,13 +8043,14 @@ extern "C" void jl_init_llvm(void)

TargetOptions options = TargetOptions();
//options.PrintMachineCode = true; //Print machine code produced during JIT compiling
#if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_)
#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
#ifdef JL_DEBUG_BUILD
#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
Expand Down
9 changes: 3 additions & 6 deletions src/codegen_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ static inline std::pair<llvm::MDNode*,llvm::MDNode*> tbaa_make_child_with_contex
return std::make_pair(n, scalar);
}

static inline llvm::MDNode *get_tbaa_gcframe(llvm::LLVMContext &ctxt) {
return tbaa_make_child_with_context(ctxt, "jtbaa_gcframe").first;
}
static inline llvm::MDNode *get_tbaa_const(llvm::LLVMContext &ctxt) {
return tbaa_make_child_with_context(ctxt, "jtbaa_const", nullptr, true).first;
}
Expand Down Expand Up @@ -132,7 +129,7 @@ static inline llvm::Value *emit_bitcast_with_builder(llvm::IRBuilder<> &builder,
}

// Get PTLS through current task.
static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder, llvm::Value *current_task)
static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder, llvm::Value *current_task, llvm::MDNode *tbaa)
{
using namespace llvm;
auto T_ppjlvalue = JuliaType::get_ppjlvalue_ty(builder.getContext());
Expand All @@ -145,9 +142,9 @@ static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder
LoadInst *ptls_load = builder.CreateAlignedLoad(
emit_bitcast_with_builder(builder, pptls, T_ppjlvalue), Align(sizeof(void *)), "ptls_load");
// Note: Corresponding store (`t->ptls = ptls`) happens in `ctx_switch` of tasks.c.
tbaa_decorate(get_tbaa_gcframe(builder.getContext()), ptls_load);
tbaa_decorate(tbaa, ptls_load);
// Using `CastInst::Create` to get an `Instruction*` without explicit cast:
auto ptls = CastInst::Create(Instruction::BitCast, ptls_load, T_ppjlvalue, "ptls");
builder.Insert(ptls);
return ptls;
}
}
15 changes: 5 additions & 10 deletions src/debuginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,6 @@ struct revcomp {
{ return lhs>rhs; }
};

struct strrefcomp {
bool operator() (const StringRef& lhs, const StringRef& rhs) const
{
return lhs.compare(rhs) > 0;
}
};

class JuliaJITEventListener: public JITEventListener
{
std::map<size_t, ObjectInfo, revcomp> objectmap;
Expand Down Expand Up @@ -234,11 +227,13 @@ class JuliaJITEventListener: public JITEventListener
SavedObject.second.release();

object::section_iterator EndSection = debugObj.section_end();
std::map<StringRef, object::SectionRef, strrefcomp> loadedSections;
StringMap<object::SectionRef> loadedSections;
for (const object::SectionRef &lSection: Object.sections()) {
auto sName = lSection.getName();
if (sName)
loadedSections[*sName] = lSection;
if (sName) {
bool inserted = loadedSections.insert(std::make_pair(*sName, lSection)).second;
assert(inserted); (void)inserted;
}
}
auto getLoadAddress = [&] (const StringRef &sName) -> uint64_t {
auto search = loadedSections.find(sName);
Expand Down
18 changes: 9 additions & 9 deletions src/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,21 +860,21 @@ static void jl_dump_asm_internal(
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TheTriple.str()));
assert(MRI && "Unable to create target register info!");

std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#if JL_LLVM_VERSION >= 130000
MCSubtargetInfo *MSTI = TheTarget->createMCSubtargetInfo(TheTriple.str(), cpu, features);
assert(MSTI && "Unable to create subtarget info!");
std::unique_ptr<llvm::MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TheTriple.str(), cpu, features));
assert(STI && "Unable to create subtarget info!");

MCContext Ctx(TheTriple, MAI.get(), MRI.get(), MSTI, &SrcMgr);
MOFI->initMCObjectFileInfo(Ctx, /* PIC */ false, /* LargeCodeModel */ false);
#if JL_LLVM_VERSION >= 130000
MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr);
std::unique_ptr<MCObjectFileInfo> MOFI(
TheTarget->createMCObjectFileInfo(Ctx, /*PIC=*/false, /*LargeCodeModel=*/ false));
Ctx.setObjectFileInfo(MOFI.get());
#else
std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
MOFI->InitMCObjectFileInfo(TheTriple, /* PIC */ false, Ctx);
#endif

// Set up Subtarget and Disassembler
std::unique_ptr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TheTriple.str(), cpu, features));
std::unique_ptr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI, Ctx));
if (!DisAsm) {
rstream << "ERROR: no disassembler for target " << TheTriple.str();
Expand Down
2 changes: 1 addition & 1 deletion src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ static void jl_add_to_ee(std::unique_ptr<Module> m)
ConstantAggregateZero::get(atype), "__catchjmp") };
gvs[0]->setSection(".text");
gvs[1]->setSection(".text");
appendToUsed(*m, makeArrayRef((GlobalValue**)gvs, 2));
appendToCompilerUsed(*m, makeArrayRef((GlobalValue**)gvs, 2));
#endif
jl_jit_share_data(*m);
assert(jl_ExecutionEngine);
Expand Down
12 changes: 7 additions & 5 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ std::vector<Value*> LateLowerGCFrame::MaybeExtractVector(State &S, Value *BaseVe
std::vector<Value*> V{Numbers.size()};
Value *V_rnull = ConstantPointerNull::get(cast<PointerType>(T_prjlvalue));
for (unsigned i = 0; i < V.size(); ++i) {
if (Numbers[i] >= 0)
if (Numbers[i] >= 0) // ignores undef and poison values
V[i] = GetPtrForNumber(S, Numbers[i], InsertBefore);
else
V[i] = V_rnull;
Expand Down Expand Up @@ -860,8 +860,9 @@ std::vector<int> LateLowerGCFrame::NumberAllBase(State &S, Value *CurrentV) {
std::vector<int> Numbers2 = NumberAll(S, SVI->getOperand(1));
auto Mask = SVI->getShuffleMask();
for (auto idx : Mask) {
assert(idx != -1 && "Undef tracked value is invalid");
if ((unsigned)idx < Numbers1.size()) {
if (idx == -1) {
Numbers.push_back(-1);
} else if ((unsigned)idx < Numbers1.size()) {
Numbers.push_back(Numbers1.at(idx));
} else {
Numbers.push_back(Numbers2.at(idx - Numbers1.size()));
Expand Down Expand Up @@ -966,8 +967,9 @@ std::vector<int> LateLowerGCFrame::NumberAll(State &S, Value *V) {
Number = Numbers[CurrentV.second]; // only needed a subset of the values
Numbers.resize(tracked.count, Number);
}
else
else {
assert(!isa<PointerType>(V->getType()));
}
}
if (CurrentV.first != V) {
if (isa<PointerType>(V->getType())) {
Expand Down Expand Up @@ -2296,7 +2298,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) {
// Create a call to the `julia.gc_alloc_bytes` intrinsic, which is like
// `julia.gc_alloc_obj` except it doesn't set the tag.
auto allocBytesIntrinsic = getOrDeclare(jl_intrinsics::GCAllocBytes);
auto ptlsLoad = get_current_ptls_from_task(builder, CI->getArgOperand(0));
auto ptlsLoad = get_current_ptls_from_task(builder, CI->getArgOperand(0), tbaa_gcframe);
auto ptls = builder.CreateBitCast(ptlsLoad, Type::getInt8PtrTy(builder.getContext()));
auto newI = builder.CreateCall(
allocBytesIntrinsic,
Expand Down
Loading