Skip to content

Commit

Permalink
Add a codegen parameters struct as a means to influence code generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Nov 4, 2016
1 parent 96f6ccc commit 7a11af5
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 29 deletions.
35 changes: 30 additions & 5 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,31 @@ function uncompressed_ast(m::Method, s::CodeInfo)
return s
end

# this type mirrors jl_cgparams_t (documented in julia.h)
immutable CodegenParams
cached::Cint

runtime::Cint
exceptions::Cint
track_allocations::Cint
code_coverage::Cint
static_alloc::Cint
dynamic_alloc::Cint

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

# Printing code representations in IR and assembly
function _dump_function(f::ANY, t::ANY, native::Bool, wrapper::Bool, strip_ir_metadata::Bool, dump_module::Bool, syntax::Symbol=:att)
function _dump_function(f::ANY, t::ANY, native::Bool, wrapper::Bool,
strip_ir_metadata::Bool, dump_module::Bool, syntax::Symbol=:att,
optimize::Bool=true, params::CodegenParams=CodegenParams())
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
if isa(f, Core.Builtin)
throw(ArgumentError("argument is not a generic function"))
Expand All @@ -509,17 +532,19 @@ function _dump_function(f::ANY, t::ANY, native::Bool, wrapper::Bool, strip_ir_me
meth = func_for_method_checked(meth, tt)
linfo = ccall(:jl_specializations_get_linfo, Ref{Core.MethodInstance}, (Any, Any, Any), meth, tt, env)
# get the code for it
return _dump_function(linfo, native, wrapper, strip_ir_metadata, dump_module, syntax)
return _dump_function(linfo, native, wrapper, strip_ir_metadata, dump_module, syntax, optimize, params)
end

function _dump_function(linfo::Core.MethodInstance, native::Bool, wrapper::Bool, strip_ir_metadata::Bool, dump_module::Bool, syntax::Symbol=:att)
function _dump_function(linfo::Core.MethodInstance, native::Bool, wrapper::Bool,
strip_ir_metadata::Bool, dump_module::Bool, syntax::Symbol=:att,
optimize::Bool=true, params::CodegenParams=CodegenParams())
if syntax != :att && syntax != :intel
throw(ArgumentError("'syntax' must be either :intel or :att"))
end
if native
llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool), linfo, wrapper)
llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool, CodegenParams), linfo, wrapper, params)
else
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool), linfo, wrapper)
llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool, Bool, CodegenParams), linfo, wrapper, optimize, params)
end
if llvmf == C_NULL
error("could not compile the specified method")
Expand Down
2 changes: 1 addition & 1 deletion src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ STATIC_INLINE jl_value_t *jl_call_staged(jl_svec_t *sparam_vals, jl_method_insta
fptr.fptr = generator->fptr;
fptr.jlcall_api = generator->jlcall_api;
if (__unlikely(fptr.fptr == NULL || fptr.jlcall_api == 0)) {
void *F = jl_compile_linfo(generator, (jl_code_info_t*)generator->inferred).functionObject;
void *F = jl_compile_linfo(generator, (jl_code_info_t*)generator->inferred, &jl_default_cgparams).functionObject;
fptr = jl_generate_fptr(generator, F);
}
assert(jl_svec_len(generator->def->sparam_syms) == jl_svec_len(sparam_vals));
Expand Down
16 changes: 16 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ static Value *prepare_call(Value *Callee)
}


// --- language feature checks ---

// branch on whether a language feature is enabled or not
#define JL_FEAT_TEST(ctx, feature) ((ctx)->params->feature)

// require a language feature to be enabled
#define JL_FEAT_REQUIRE(ctx, feature) \
if (!JL_FEAT_TEST(ctx, feature)) \
jl_errorf("%s for %s:%d requires the " #feature " language feature, which is disabled", \
__FUNCTION__, (ctx)->file.str().c_str(), *(ctx)->line);


// --- string constants ---
static StringMap<GlobalVariable*> stringConstants;
static Value *stringConstPtr(IRBuilder<> &builder, const std::string &txt)
Expand Down Expand Up @@ -660,6 +672,7 @@ static void error_unless(Value *cond, const std::string &msg, jl_codectx_t *ctx)
static void raise_exception(Value *exc, jl_codectx_t *ctx,
BasicBlock *contBB=nullptr)
{
JL_FEAT_REQUIRE(ctx, runtime);
#if JL_LLVM_VERSION >= 30700
builder.CreateCall(prepare_call(jlthrow_func), { exc });
#else
Expand Down Expand Up @@ -1566,6 +1579,9 @@ static void emit_cpointercheck(const jl_cgval_t &x, const std::string &msg, jl_c
// allocation for known size object
static Value *emit_allocobj(jl_codectx_t *ctx, size_t static_size, Value *jt)
{
JL_FEAT_REQUIRE(ctx, dynamic_alloc);
JL_FEAT_REQUIRE(ctx, runtime);

int osize;
int offset = jl_gc_classify_pools(static_size, &osize);
Value *ptls_ptr = emit_bitcast(ctx->ptlsStates, T_pint8);
Expand Down
Loading

0 comments on commit 7a11af5

Please sign in to comment.