Skip to content

Commit

Permalink
Import of diff from JuliaGPU/julia.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Oct 20, 2016
1 parent d47993d commit 87862c6
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 31 deletions.
21 changes: 17 additions & 4 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,15 @@ function uncompressed_ast(m::Method, s::CodeInfo)
return s
end

# this type mirrors jl_cghooks_t (documented in julia.h)
immutable CodegenHooks
module_setup::Any
module_activation::Any

CodegenHooks(;module_setup=nothing, module_activation=nothing) =
new(module_setup, module_activation)
end

# this type mirrors jl_cgparams_t (documented in julia.h)
immutable CodegenParams
cached::Cint
Expand All @@ -504,14 +513,18 @@ immutable CodegenParams
static_alloc::Cint
dynamic_alloc::Cint

hooks::CodegenHooks

CodegenParams(;cached::Bool=true,
runtime::Int=1, exceptions::Int=1,
track_allocations::Int=1, code_coverage::Int=1,
static_alloc::Int=1, dynamic_alloc::Int=1) =
static_alloc::Int=1, dynamic_alloc::Int=1,
hooks::CodegenHooks=CodegenHooks()) =
new(Cint(cached),
Cint(runtime), Cint(exceptions),
Cint(track_allocations), Cint(code_coverage),
Cint(static_alloc), Cint(dynamic_alloc))
Cint(static_alloc), Cint(dynamic_alloc),
hooks)
end

# Printing code representations in IR and assembly
Expand All @@ -538,9 +551,9 @@ function _dump_function(linfo::Core.MethodInstance, native::Bool, wrapper::Bool,
throw(ArgumentError("'syntax' must be either :intel or :att"))
end
if native
llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool, CodegenParams), linfo, wrapper, params)
llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool, CodegenParams, CodegenHooks), linfo, wrapper, params, params.hooks)
else
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool, Bool, CodegenParams), linfo, wrapper, optimize, params)
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool, Bool, CodegenParams, CodegenHooks), linfo, wrapper, optimize, params, params.hooks)
end
if llvmf == C_NULL
error("could not compile the specified method")
Expand Down
2 changes: 1 addition & 1 deletion deps/Versions.make
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
LLVM_VER = 3.7.1
LLVM_VER = 3.9.0
LLVM_LIB_SUFFIX =
PCRE_VER = 10.22
DSFMT_VER = 2.2.3
Expand Down
14 changes: 13 additions & 1 deletion deps/llvm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ endif # LLVM_VER != svn
LLVM_CXXFLAGS := $(CXXFLAGS)
LLVM_CPPFLAGS := $(CPPFLAGS)
LLVM_LDFLAGS := $(LDFLAGS)
LLVM_TARGETS := host
ifeq ($(LLVM_USE_CMAKE),1)
LLVM_TARGETS := host;NVPTX
else
LLVM_TARGETS := host,nvptx
endif
LLVM_TARGET_FLAGS := --enable-targets=$(LLVM_TARGETS)
LLVM_CMAKE += -DLLVM_TARGETS_TO_BUILD:STRING="$(LLVM_TARGETS)" -DCMAKE_BUILD_TYPE="$(LLVM_CMAKE_BUILDTYPE)"
LLVM_CMAKE += -DLLVM_TOOLS_INSTALL_DIR=$(shell $(JULIAHOME)/contrib/relative_path.sh $(build_prefix) $(build_depsbindir))
Expand Down Expand Up @@ -466,6 +470,14 @@ $(eval $(call LLVM_PATCH,llvm-r282182)) # Remove for 4.0
$(eval $(call LLVM_PATCH,llvm-arm-fix-prel31))
endif # LLVM_VER

$(eval $(call LLVM_PATCH,llvm-asan))
ifeq ($(LLVM_VER_SHORT),3.9)
$(eval $(call LLVM_PATCH,llvm-D9168_argument_alignment))
endif
ifeq ($(BUILD_LLVM_CLANG),1)
$(eval $(call LLVM_PATCH,compiler-rt-asan))
endif

ifeq ($(LLVM_VER),3.7.1)
ifeq ($(BUILD_LLDB),1)
$(eval $(call LLVM_PATCH,lldb-3.7.1))
Expand Down
13 changes: 13 additions & 0 deletions deps/patches/compiler-rt-asan.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Index: lib/asan/asan_mapping.h
===================================================================
--- a/projects/compiler-rt/lib/asan/asan_mapping.h (revision 256758)
+++ b/projects/compiler-rt/lib/asan/asan_mapping.h (working copy)
@@ -146,7 +146,7 @@
# elif SANITIZER_IOS
# define SHADOW_OFFSET kIosShadowOffset64
# else
-# define SHADOW_OFFSET kDefaultShort64bitShadowOffset
+# define SHADOW_OFFSET kDefaultShadowOffset64
# endif
# endif
#endif
98 changes: 98 additions & 0 deletions deps/patches/llvm-D9168_argument_alignment.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
Index: lib/Target/NVPTX/NVPTXISelLowering.h
===================================================================
--- a/lib/Target/NVPTX/NVPTXISelLowering.h
+++ b/lib/Target/NVPTX/NVPTXISelLowering.h
@@ -539,7 +539,8 @@
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;

unsigned getArgumentAlignment(SDValue Callee, const ImmutableCallSite *CS,
- Type *Ty, unsigned Idx) const;
+ Type *Ty, unsigned Idx,
+ const DataLayout &DL) const;
};
} // namespace llvm

Index: lib/Target/NVPTX/NVPTXISelLowering.cpp
===================================================================
--- a/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -1024,11 +1024,15 @@
return O.str();
}

-unsigned
-NVPTXTargetLowering::getArgumentAlignment(SDValue Callee,
- const ImmutableCallSite *CS,
- Type *Ty,
- unsigned Idx) const {
+unsigned NVPTXTargetLowering::getArgumentAlignment(SDValue Callee,
+ const ImmutableCallSite *CS,
+ Type *Ty, unsigned Idx,
+ const DataLayout &DL) const {
+ if (!CS) {
+ // CallSite is zero, fallback to ABI type alignment
+ return DL.getABITypeAlignment(Ty);
+ }
+
unsigned Align = 0;
const Value *DirectCallee = CS->getCalledFunction();

@@ -1046,7 +1050,7 @@

const Value *CalleeV = cast<CallInst>(CalleeI)->getCalledValue();
// Ignore any bitcast instructions
- while(isa<ConstantExpr>(CalleeV)) {
+ while (isa<ConstantExpr>(CalleeV)) {
const ConstantExpr *CE = cast<ConstantExpr>(CalleeV);
if (!CE->isCast())
break;
@@ -1069,7 +1073,6 @@

// Call is indirect or alignment information is not available, fall back to
// the ABI type alignment
- auto &DL = CS->getCaller()->getParent()->getDataLayout();
return DL.getABITypeAlignment(Ty);
}

@@ -1126,7 +1129,8 @@
ComputePTXValueVTs(*this, DAG.getDataLayout(), Ty, vtparts, &Offsets,
0);

- unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1);
+ unsigned align =
+ getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL);
// declare .param .align <align> .b8 .param<n>[<size>];
unsigned sz = DL.getTypeAllocSize(Ty);
SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue);
@@ -1166,7 +1170,8 @@
}
if (Ty->isVectorTy()) {
EVT ObjectVT = getValueType(DL, Ty);
- unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1);
+ unsigned align =
+ getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL);
// declare .param .align <align> .b8 .param<n>[<size>];
unsigned sz = DL.getTypeAllocSize(Ty);
SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue);
@@ -1426,7 +1431,7 @@
DeclareRetOps);
InFlag = Chain.getValue(1);
} else {
- retAlignment = getArgumentAlignment(Callee, CS, retTy, 0);
+ retAlignment = getArgumentAlignment(Callee, CS, retTy, 0, DL);
SDVTList DeclareRetVTs = DAG.getVTList(MVT::Other, MVT::Glue);
SDValue DeclareRetOps[] = { Chain,
DAG.getConstant(retAlignment, dl, MVT::i32),
@@ -1633,9 +1638,10 @@
} else {
SmallVector<EVT, 16> VTs;
SmallVector<uint64_t, 16> Offsets;
- ComputePTXValueVTs(*this, DAG.getDataLayout(), retTy, VTs, &Offsets, 0);
+ auto &DL = DAG.getDataLayout();
+ ComputePTXValueVTs(*this, DL, retTy, VTs, &Offsets, 0);
assert(VTs.size() == Ins.size() && "Bad value decomposition");
- unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0);
+ unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0, DL);
for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
unsigned sz = VTs[i].getSizeInBits();
unsigned AlignI = GreatestCommonDivisor64(RetAlign, Offsets[i]);
13 changes: 13 additions & 0 deletions deps/patches/llvm-asan.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 43d1b37..3efe3d6 100644
--- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -404,7 +404,7 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize,
if (IsKasan)
Mapping.Offset = kLinuxKasan_ShadowOffset64;
else
- Mapping.Offset = kSmallX86_64ShadowOffset;
+ Mapping.Offset = kDefaultShadowOffset64;
} else if (IsWindows && IsX86_64) {
Mapping.Offset = kWindowsShadowOffset64;
} else if (IsMIPS64)
15 changes: 15 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ static inline bool _feat_test(jl_codectx_t* ctx, const char *caller, int featval
}


// --- hook checks ---

#define JL_HOOK_TEST(params,hook) \
((params)->hooks.hook != jl_nothing)

// NOTE: this is just a throwing version of jl_call1...
#define JL_HOOK_CALL1(params,hook,arg1) \
jl_value_t **argv; \
JL_GC_PUSHARGS(argv, 2); \
argv[0] = (params)->hooks.hook; \
argv[1] = arg1; \
jl_apply(argv, 2); \
JL_GC_POP();


// --- string constants ---
static StringMap<GlobalVariable*> stringConstants;
static Value *stringConstPtr(IRBuilder<> &builder, const std::string &txt)
Expand Down
60 changes: 36 additions & 24 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,25 +923,30 @@ jl_llvm_functions_t jl_compile_linfo(jl_method_instance_t *li, jl_code_info_t *s
f = (Function*)decls.functionObject;
specf = (Function*)decls.specFunctionObject;

// Step 4. Prepare debug info to receive this function
// record that this function name came from this linfo,
// so we can build a reverse mapping for debug-info.
bool toplevel = li->def == NULL;
if (!toplevel) {
const DataLayout &DL =
#if JL_LLVM_VERSION >= 30500
m->getDataLayout();
#else
*jl_data_layout;
#endif
// but don't remember toplevel thunks because
// they may not be rooted in the gc for the life of the program,
// and the runtime doesn't notify us when the code becomes unreachable :(
jl_add_linfo_in_flight((specf ? specf : f)->getName(), li, DL);
}

// Step 5. Add the result to the execution engine now
jl_finalize_module(m.release(), !toplevel);
if (JL_HOOK_TEST(params, module_activation)) {
JL_HOOK_CALL1(params, module_activation, jl_box_voidpointer(wrap(m.release())));
} else {
// Step 4. Prepare debug info to receive this function
// record that this function name came from this linfo,
// so we can build a reverse mapping for debug-info.
bool toplevel = li->def == NULL;
if (!toplevel) {
const DataLayout &DL =
#if JL_LLVM_VERSION >= 30500
m->getDataLayout();
#else
*jl_data_layout;
#endif
// but don't remember toplevel thunks because
// they may not be rooted in the gc for the life of the program,
// and the runtime doesn't notify us when the code becomes unreachable :(
jl_add_linfo_in_flight((specf ? specf : f)->getName(), li, DL);
}

// Step 5. Add the result to the execution engine now
jl_finalize_module(m.release(), !toplevel);
}

if (li->jlcall_api != 2) {
// if not inlineable, code won't be needed again
Expand Down Expand Up @@ -988,8 +993,13 @@ static Value *getModuleFlag(Module *m, StringRef Key)
#define getModuleFlag(m,str) m->getModuleFlag(str)
#endif

static void jl_setup_module(Module *m)
static void jl_setup_module(Module *m, jl_cgparams_t *params = &jl_default_cgparams)
{
if (JL_HOOK_TEST(params, module_setup)) {
JL_HOOK_CALL1(params, module_setup, jl_box_voidpointer(wrap(m)));
return;
}

// 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.
Expand Down Expand Up @@ -1256,8 +1266,9 @@ void jl_extern_c(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name)
// this is paired with jl_dump_function_ir and jl_dump_function_asm in particular ways:
// misuse will leak memory or cause read-after-free
extern "C" JL_DLLEXPORT
void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optimize, jl_cgparams_t params)
void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optimize, jl_cgparams_t params, jl_cghooks_t _hooks)
{
params.hooks = _hooks; // ccall doesn't know how to pass the nested jl_cghooks_t
// `source` is `NULL` for generated functions.
// The `isstaged` check can be removed if that is not the case anymore.
if (linfo->def && linfo->def->source == NULL && !linfo->def->isstaged) {
Expand Down Expand Up @@ -1338,8 +1349,9 @@ void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optim


extern "C" JL_DLLEXPORT
void *jl_get_llvmf_decl(jl_method_instance_t *linfo, bool getwrapper, jl_cgparams_t params)
void *jl_get_llvmf_decl(jl_method_instance_t *linfo, bool getwrapper, jl_cgparams_t params, jl_cghooks_t _hooks)
{
params.hooks = _hooks; // ccall doesn't know how to pass the nested jl_cghooks_t
// `source` is `NULL` for generated functions.
// The `isstaged` check can be removed if that is not the case anymore.
if (linfo->def && linfo->def->source == NULL && !linfo->def->isstaged) {
Expand Down Expand Up @@ -1397,9 +1409,9 @@ void *jl_get_llvmf(jl_tupletype_t *tt, bool getwrapper, bool getdeclarations)
}
void *f;
if (getdeclarations)
f = jl_get_llvmf_decl(linfo, getwrapper, jl_default_cgparams);
f = jl_get_llvmf_decl(linfo, getwrapper, jl_default_cgparams, jl_no_cghooks);
else
f = jl_get_llvmf_defn(linfo, getwrapper, true, jl_default_cgparams);
f = jl_get_llvmf_defn(linfo, getwrapper, true, jl_default_cgparams, jl_no_cghooks);
JL_GC_POP();
return f;
}
Expand Down Expand Up @@ -4207,7 +4219,7 @@ static std::unique_ptr<Module> emit_function(jl_method_instance_t *lam, jl_code_

ctx.sret = false;
Module *M = new Module(ctx.name, jl_LLVMContext);
jl_setup_module(M);
jl_setup_module(M, params);
if (specsig) { // assumes !va and !needsparams
std::vector<Type*> fsig(0);
Type *rt;
Expand Down
4 changes: 3 additions & 1 deletion src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ JL_DLLEXPORT jl_value_t *jl_emptytuple=NULL;
jl_svec_t *jl_emptysvec;
jl_value_t *jl_nothing;

jl_cghooks_t jl_no_cghooks;
jl_cgparams_t jl_default_cgparams;

// --- type properties and predicates ---
Expand Down Expand Up @@ -3531,7 +3532,8 @@ void jl_init_types(void)
jl_type_type_mt = jl_new_method_table(jl_type_type->name->name, ptls->current_module);
jl_type_type->name->mt = jl_type_type_mt;

jl_default_cgparams = (jl_cgparams_t){1, 1, 1, 1, 1, 1, 1};
jl_no_cghooks = (jl_cghooks_t){jl_nothing, jl_nothing};
jl_default_cgparams = (jl_cgparams_t){1, 1, 1, 1, 1, 1, 1, jl_no_cghooks};

// initialize them. lots of cycles.
jl_datatype_type->name = jl_new_typename(jl_symbol("DataType"));
Expand Down
15 changes: 15 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,19 @@ typedef struct {

// codegen interface ----------------------------------------------------------

typedef struct {
// module setup: prepare a module for code emission (data layout, DWARF version, ...)
// parameters: LLVMModuleRef as Ptr{Void}
// return value: none
jl_value_t *module_setup;

// module activation: registers debug info, adds module to JIT
// parameters: LLVMModuleRef as Ptr{Void}
// return value: none
jl_value_t *module_activation;
} jl_cghooks_t;
extern JL_DLLEXPORT jl_cghooks_t jl_no_cghooks;

typedef struct {
int cached; // can the compiler consult/mutate the compilation cache?

Expand All @@ -1767,6 +1780,8 @@ typedef struct {
int code_coverage; // can we measure coverage (fallback: don't)?
int static_alloc; // is the compiler allowed to allocate statically?
int dynamic_alloc; // is the compiler allowed to allocate dynamically (requires runtime)?

jl_cghooks_t hooks;
} jl_cgparams_t;
extern JL_DLLEXPORT jl_cgparams_t jl_default_cgparams;

Expand Down

0 comments on commit 87862c6

Please sign in to comment.