Skip to content

Commit

Permalink
add per-module optimization level macro
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Feb 26, 2020
1 parent c2cd601 commit 657c934
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 2 deletions.
4 changes: 4 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ macro specialize(vars...)
return Expr(:meta, :specialize, vars...)
end

macro optlevel(n::Int)
return Expr(:meta, :optlevel, n)
end

macro _pure_meta()
return Expr(:meta, :pure)
end
Expand Down
2 changes: 2 additions & 0 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jl_sym_t *throw_undef_if_not_sym; jl_sym_t *getfield_undefref_sym;
jl_sym_t *gc_preserve_begin_sym; jl_sym_t *gc_preserve_end_sym;
jl_sym_t *coverageeffect_sym; jl_sym_t *escape_sym;
jl_sym_t *aliasscope_sym; jl_sym_t *popaliasscope_sym;
jl_sym_t *optlevel_sym;

static uint8_t flisp_system_image[] = {
#include <julia_flisp.boot.inc>
Expand Down Expand Up @@ -380,6 +381,7 @@ void jl_init_frontend(void)
isdefined_sym = jl_symbol("isdefined");
nospecialize_sym = jl_symbol("nospecialize");
specialize_sym = jl_symbol("specialize");
optlevel_sym = jl_symbol("optlevel");
macrocall_sym = jl_symbol("macrocall");
escape_sym = jl_symbol("escape");
hygienicscope_sym = jl_symbol("hygienic-scope");
Expand Down
8 changes: 7 additions & 1 deletion src/debuginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const D
{
ncode_in_flight[mangle(name, DL)] = codeinst;
}

jl_code_instance_t *jl_get_code_in_flight(StringRef name)
{
StringMap<jl_code_instance_t*>::iterator linfo_it = ncode_in_flight.find(name);
if (linfo_it != ncode_in_flight.end())
return linfo_it->second;
return NULL;
}

#ifdef _OS_WINDOWS_
#if defined(_CPU_X86_64_)
Expand Down
2 changes: 2 additions & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
write_uint64(s->s, m->build_id);
write_int32(s->s, m->counter);
write_int32(s->s, m->nospecialize);
write_int32(s->s, m->optlevel);
}

static int is_ast_node(jl_value_t *v)
Expand Down Expand Up @@ -1895,6 +1896,7 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) JL_GC_DIS
m->build_id = read_uint64(s->s);
m->counter = read_int32(s->s);
m->nospecialize = read_int32(s->s);
m->optlevel = read_int32(s->s);
m->primary_world = jl_world_counter;
return (jl_value_t*)m;
}
Expand Down
6 changes: 6 additions & 0 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,12 @@ static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, size_t ip,
if (jl_expr_nargs(stmt) == 1 && jl_exprarg(stmt, 0) == (jl_value_t*)specialize_sym) {
jl_set_module_nospecialize(s->module, 0);
}
if (jl_expr_nargs(stmt) == 2 && jl_exprarg(stmt, 0) == (jl_value_t*)optlevel_sym) {
if (jl_is_long(jl_exprarg(stmt, 1))) {
int n = jl_unbox_long(jl_exprarg(stmt, 1));
jl_set_module_optlevel(s->module, n);
}
}
}
else {
eval_stmt_value(stmt, s);
Expand Down
35 changes: 34 additions & 1 deletion src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,39 @@ void JuliaOJIT::DebugObjectRegistrar::operator()(RTDyldObjHandleT H,
static_cast<const RuntimeDyld::LoadedObjectInfo*>(&LOS));
}

jl_code_instance_t *jl_get_code_in_flight(StringRef name);

CompilerResultT JuliaOJIT::CompilerT::operator()(Module &M)
{
JL_TIMING(LLVM_OPT);
jit.PM.run(M);
int optlevel = -1;
jl_method_t *meth = NULL;
jl_method_instance_t *mi = NULL;
for (Module::iterator fs = M.begin(); fs != M.end(); ) {
Function &F = *fs;
if (!F.getBasicBlockList().empty()) {
jl_code_instance_t *codeinst = jl_get_code_in_flight(F.getName());
if (codeinst) {
mi = codeinst->def;
if (jl_is_method(mi->def.value)) {
meth = mi->def.method;
if (meth->module->optlevel == 0) {
optlevel = 0;
break;
}
}
else {
mi = NULL;
}
}
}
++fs;
}
if (optlevel == -1)
jit.PM.run(M);
else
jit.fastPM.run(M);

std::unique_ptr<MemoryBuffer> ObjBuffer(
new SmallVectorMemoryBuffer(std::move(jit.ObjBufferSV)));
auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
Expand Down Expand Up @@ -391,6 +419,11 @@ JuliaOJIT::JuliaOJIT(TargetMachine &TM)
if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
llvm_unreachable("Target does not support MC emission.");

addTargetPasses(&fastPM, &TM);
addOptimizationPasses(&fastPM, 0);
if (TM.addPassesToEmitMC(fastPM, Ctx, ObjStream))
llvm_unreachable("Target does not support MC emission.");

// Make sure SectionMemoryManager::getSymbolAddressInProcess can resolve
// symbols in the program as well. The nullptr argument to the function
// tells DynamicLibrary to load the program, not a library.
Expand Down
1 change: 1 addition & 0 deletions src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class JuliaOJIT {
SmallVector<char, 4096> ObjBufferSV;
raw_svector_ostream ObjStream;
legacy::PassManager PM;
legacy::PassManager fastPM;
MCContext *Ctx;
std::shared_ptr<RTDyldMemoryManager> MemMgr;
DebugObjectRegistrar registrar;
Expand Down
2 changes: 2 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ typedef struct _jl_module_t {
size_t primary_world;
uint32_t counter;
int32_t nospecialize; // global bit flags: initialization for new methods
int32_t optlevel;
uint8_t istopmod;
jl_mutex_t lock;
} jl_module_t;
Expand Down Expand Up @@ -1471,6 +1472,7 @@ extern JL_DLLEXPORT jl_module_t *jl_base_module JL_GLOBALLY_ROOTED;
extern JL_DLLEXPORT jl_module_t *jl_top_module JL_GLOBALLY_ROOTED;
JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name);
JL_DLLEXPORT void jl_set_module_nospecialize(jl_module_t *self, int on);
JL_DLLEXPORT void jl_set_module_optlevel(jl_module_t *self, int lvl);
// get binding for reading
JL_DLLEXPORT jl_binding_t *jl_get_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var);
JL_DLLEXPORT jl_binding_t *jl_get_binding_or_error(jl_module_t *m, jl_sym_t *var);
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ extern jl_sym_t *throw_undef_if_not_sym; extern jl_sym_t *getfield_undefref_sym;
extern jl_sym_t *gc_preserve_begin_sym; extern jl_sym_t *gc_preserve_end_sym;
extern jl_sym_t *failed_sym; extern jl_sym_t *done_sym; extern jl_sym_t *runnable_sym;
extern jl_sym_t *coverageeffect_sym; extern jl_sym_t *escape_sym;
extern jl_sym_t *optlevel_sym;

struct _jl_sysimg_fptrs_t;

Expand Down
6 changes: 6 additions & 0 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name)
m->primary_world = 0;
m->counter = 1;
m->nospecialize = 0;
m->optlevel = -1;
JL_MUTEX_INIT(&m->lock);
htable_new(&m->bindings, 0);
arraylist_new(&m->usings, 0);
Expand Down Expand Up @@ -72,6 +73,11 @@ JL_DLLEXPORT void jl_set_module_nospecialize(jl_module_t *self, int on)
self->nospecialize = (on ? -1 : 0);
}

JL_DLLEXPORT void jl_set_module_optlevel(jl_module_t *self, int lvl)
{
self->optlevel = lvl;
}

JL_DLLEXPORT void jl_set_istopmod(jl_module_t *self, uint8_t isprimary)
{
self->istopmod = 1;
Expand Down

0 comments on commit 657c934

Please sign in to comment.