Skip to content

Commit c6a6535

Browse files
committed
separate julia compile stages
this saves a bit of replaced code from getting put in the system image and allows us to serialize the .o file emission while keeping the rest of the build parallel this isn't essential on systems with sufficient memory, but CI is typically sufficiently constrained that this is highly beneficial
1 parent 893f7e3 commit c6a6535

File tree

7 files changed

+74
-37
lines changed

7 files changed

+74
-37
lines changed

.travis.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ notifications:
5656
- http://julia.mit.edu:8000/travis-hook
5757
before_install:
5858
- make check-whitespace
59-
- JULIA_SYSIMG_BUILD_FLAGS="--output-ji ../usr/lib/julia/sys.ji"
6059
- if [ `uname` = "Linux" ]; then
6160
contrib/travis_fastfail.sh || exit 1;
6261
mkdir -p $HOME/bin;
@@ -86,15 +85,19 @@ before_install:
8685
export LDFLAGS="-L$(brew --prefix openblas-julia)/lib -L$(brew --prefix suite-sparse-julia)/lib";
8786
export DYLD_FALLBACK_LIBRARY_PATH="/usr/local/lib:/lib:/usr/lib:$(brew --prefix openblas-julia)/lib:$(brew --prefix suite-sparse-julia)/lib:$(brew --prefix arpack-julia)/lib";
8887
make $BUILDOPTS -C contrib -f repackage_system_suitesparse4.make;
89-
JULIA_SYSIMG_BUILD_FLAGS="$JULIA_SYSIMG_BUILD_FLAGS --compile=all";
90-
COMPILE_MODE="--compile=min";
88+
COMPILE_MODE="--compile=min --sysimage=/tmp/julia/lib/julia/sys-all.dylib";
9189
TESTSTORUN="core ccall mmap llvmcall threads"; fi # TODO: turn this back to "all" once it's fast enough to not time out
9290
- git clone -q git://git.kitenet.net/moreutils
9391
script:
9492
- make -C moreutils mispipe
9593
- make $BUILDOPTS -C base version_git.jl.phony
9694
- moreutils/mispipe "make $BUILDOPTS NO_GIT=1 -C deps" bar > deps.log || cat deps.log
97-
- make $BUILDOPTS NO_GIT=1 JULIA_SYSIMG_BUILD_FLAGS="$JULIA_SYSIMG_BUILD_FLAGS" prefix=/tmp/julia install | moreutils/ts -s "%.s"
95+
- make $BUILDOPTS NO_GIT=1 release julia-ui-debug | moreutils/ts -s "%.s"
96+
- if [ `uname` = "Darwin" ]; then
97+
make $BUILDOPTS NO_GIT=1 julia-sysimg-all-release | moreutils/ts -s "%.s";
98+
make $BUILDOPTS NO_GIT=1 julia-sysimg-all-debug | moreutils/ts -s "%.s"
99+
fi
100+
- make $BUILDOPTS NO_GIT=1 prefix=/tmp/julia install | moreutils/ts -s "%.s" # due to limited memory, link julia-sysimg-debug in a separate step
98101
- make $BUILDOPTS NO_GIT=1 build-stats
99102
- du -sk /tmp/julia/*
100103
- if [ `uname` = "Darwin" ]; then
@@ -103,8 +106,6 @@ script:
103106
done;
104107
fi
105108
- cd .. && mv julia julia2
106-
- cp /tmp/julia/lib/julia/sys.ji local.ji && /tmp/julia/bin/julia -J local.ji -e 'true' &&
107-
/tmp/julia/bin/julia-debug -J local.ji -e 'true' && rm local.ji
108109
- /tmp/julia/bin/julia -e 'versioninfo()'
109110
- export JULIA_CPU_CORES=2 && export JULIA_TEST_MAXRSS_MB=600 && cd /tmp/julia/share/julia/test &&
110111
/tmp/julia/bin/julia --check-bounds=yes $COMPILE_MODE runtests.jl $TESTSTORUN &&

Makefile

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,23 @@ julia-src-release julia-src-debug : julia-src-% : julia-deps julia_flisp.boot.in
9292
julia-ui-release julia-ui-debug : julia-ui-% : julia-src-%
9393
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/ui julia-$*
9494

95-
julia-inference : julia-base julia-ui-$(JULIA_BUILD_MODE) $(build_prefix)/.examples
96-
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/inference.ji JULIA_BUILD_MODE=$(JULIA_BUILD_MODE)
95+
julia-sysimg : julia-base julia-ui-$(JULIA_BUILD_MODE) $(build_prefix)/.examples
96+
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys.ji JULIA_BUILD_MODE=$(JULIA_BUILD_MODE)
97+
julia-sysimg-all : julia-sysimg
98+
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys-all.ji JULIA_BUILD_MODE=$(JULIA_BUILD_MODE)
9799

98-
julia-sysimg-release : julia-inference julia-ui-release
100+
julia-sysimg-release : julia-sysimg julia-ui-release
99101
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys.$(SHLIB_EXT) JULIA_BUILD_MODE=release
100-
101-
julia-sysimg-debug : julia-inference julia-ui-debug
102+
julia-sysimg-all-release : julia-sysimg-all julia-ui-release
103+
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys-all.$(SHLIB_EXT) JULIA_BUILD_MODE=release
104+
julia-sysimg-debug : julia-sysimg julia-ui-debug
102105
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys-debug.$(SHLIB_EXT) JULIA_BUILD_MODE=debug
106+
julia-sysimg-all-debug : julia-sysimg-all julia-ui-debug
107+
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT) $(build_private_libdir)/sys-all-debug.$(SHLIB_EXT) JULIA_BUILD_MODE=debug
103108

104109
julia-debug julia-release : julia-% : julia-ui-% julia-sysimg-% julia-symlink julia-libccalltest
105-
106-
debug release : % : julia-%
110+
julia-all-debug julia-all-release : julia-all-% : julia-ui-% julia-sysimg-all-% julia-symlink julia-libccalltest
111+
debug release all-debug all-release : % : julia-%
107112

108113
julia-genstdlib: julia-sysimg-$(JULIA_BUILD_MODE)
109114
@$(call PRINT_JULIA, $(JULIA_EXECUTABLE) $(call cygpath_w, $(JULIAHOME)/doc/genstdlib.jl))
@@ -212,21 +217,33 @@ BASE_SRCS := $(shell find $(JULIAHOME)/base -name \*.jl)
212217

213218
$(build_private_libdir)/inference.ji: $(CORE_SRCS) | $(build_private_libdir)
214219
@$(call PRINT_JULIA, cd $(JULIAHOME)/base && \
215-
$(call spawn,$(JULIA_EXECUTABLE)) -C $(JULIA_CPU_TARGET) --output-ji $(call cygpath_w,$@) -f \
220+
$(call spawn,$(JULIA_EXECUTABLE)) -O0 -C $(JULIA_CPU_TARGET) --output-ji $(call cygpath_w,$@) -f \
216221
coreimg.jl)
217222

223+
$(build_private_libdir)/sys.ji: $(build_private_libdir)/inference.ji $(JULIAHOME)/VERSION $(BASE_SRCS)
224+
@$(call PRINT_JULIA, cd $(JULIAHOME)/base && \
225+
$(call spawn,$(JULIA_EXECUTABLE)) -O0 -C $(JULIA_CPU_TARGET) --output-ji $(call cygpath_w,$@) $(JULIA_SYSIMG_BUILD_FLAGS) -f \
226+
-J $(call cygpath_w,$<) sysimg.jl $(RELBUILDROOT) \
227+
|| { echo '*** This error is usually fixed by running `make clean`. If the error persists$$(COMMA) try `make cleanall`. ***' && false; } )
228+
229+
$(build_private_libdir)/sys-all.ji: $(build_private_libdir)/sys.ji
230+
@$(call PRINT_JULIA, cd $(JULIAHOME)/base && \
231+
$(call spawn,$(JULIA_EXECUTABLE)) -O0 -C $(JULIA_CPU_TARGET) --output-ji $(call cygpath_w,$@) --compile=all -f \
232+
-J $(call cygpath_w,$<) -e nothing)
233+
218234
RELBUILDROOT := $(shell $(JULIAHOME)/contrib/relative_path.sh "$(JULIAHOME)/base" "$(BUILDROOT)/base/")
219235
COMMA:=,
220236
define sysimg_builder
221-
$$(build_private_libdir)/sys$1.o: $$(build_private_libdir)/inference.ji $$(JULIAHOME)/VERSION $$(BASE_SRCS)
237+
$$(build_private_libdir)/sys$1$2.bc $$(build_private_libdir)/sys$1$2.o: $$(build_private_libdir)/sys$1$2.% : $$(build_private_libdir)/sys$1.ji
222238
@$$(call PRINT_JULIA, cd $$(JULIAHOME)/base && \
223-
$$(call spawn,$3) $2 -C $$(JULIA_CPU_TARGET) --output-o $$(call cygpath_w,$$@) $$(JULIA_SYSIMG_BUILD_FLAGS) -f \
224-
-J $$(call cygpath_w,$$<) sysimg.jl $$(RELBUILDROOT) \
225-
|| { echo '*** This error is usually fixed by running `make clean`. If the error persists$$(COMMA) try `make cleanall`. ***' && false; } )
226-
.SECONDARY: $(build_private_libdir)/sys$1.o
239+
$$(call spawn,$4) $3 -C $$(JULIA_CPU_TARGET) --output-$$* $$(call cygpath_w,$$@) $$(JULIA_SYSIMG_BUILD_FLAGS) -f \
240+
-J $$(call cygpath_w,$$<) -e nothing)
241+
.SECONDARY: $(build_private_libdir)/sys$1$2.o $(build_private_libdir)/sys$1$2.bc
227242
endef
228-
$(eval $(call sysimg_builder,,-O3,$(JULIA_EXECUTABLE_release)))
229-
$(eval $(call sysimg_builder,-debug,-O0,$(JULIA_EXECUTABLE_debug)))
243+
$(eval $(call sysimg_builder,,,-O3,$(JULIA_EXECUTABLE_release)))
244+
$(eval $(call sysimg_builder,,-debug,-O0,$(JULIA_EXECUTABLE_debug)))
245+
$(eval $(call sysimg_builder,-all,,--compile=all -O3,$(JULIA_EXECUTABLE_release)))
246+
$(eval $(call sysimg_builder,-all,-debug,--compile=all -O0,$(JULIA_EXECUTABLE_debug)))
230247

231248
$(build_bindir)/stringreplace: $(JULIAHOME)/contrib/stringreplace.c | $(build_bindir)
232249
@$(call PRINT_CC, $(HOSTCC) -o $(build_bindir)/stringreplace $(JULIAHOME)/contrib/stringreplace.c)
@@ -365,7 +382,8 @@ endif
365382
endif
366383
$(INSTALL_F) $(addprefix $(JULIAHOME)/,src/julia.h src/julia_threads.h src/julia_version.h src/support/*.h) $(DESTDIR)$(includedir)/julia
367384
# Copy system image
368-
-$(INSTALL_F) $(build_private_libdir)/sys.ji $(DESTDIR)$(private_libdir)
385+
-$(INSTALL_M) $(build_private_libdir)/sys-all.$(SHLIB_EXT) $(DESTDIR)$(private_libdir)
386+
-$(INSTALL_M) $(build_private_libdir)/sys-all-debug.$(SHLIB_EXT) $(DESTDIR)$(private_libdir)
369387
$(INSTALL_M) $(build_private_libdir)/sys.$(SHLIB_EXT) $(DESTDIR)$(private_libdir)
370388
$(INSTALL_M) $(build_private_libdir)/sys-debug.$(SHLIB_EXT) $(DESTDIR)$(private_libdir)
371389
# Copy in system image build script
@@ -640,7 +658,7 @@ LLVM_SIZE := $(build_bindir)/llvm-size$(EXE)
640658
endif
641659
build-stats:
642660
@echo $(JULCOLOR)' ==> ./julia binary sizes'$(ENDCOLOR)
643-
$(call spawn,$(LLVM_SIZE) -A $(build_private_libdir)/sys.$(SHLIB_EXT) $(build_shlibdir)/libjulia.$(SHLIB_EXT) $(build_bindir)/julia$(EXE))
661+
$(call spawn,$(LLVM_SIZE) -A $(build_private_libdir)/sys*.$(SHLIB_EXT) $(build_shlibdir)/libjulia.$(SHLIB_EXT) $(build_bindir)/julia$(EXE))
644662
@echo $(JULCOLOR)' ==> ./julia launch speedtest'$(ENDCOLOR)
645663
@time $(call spawn,$(build_bindir)/julia$(EXE) -e '')
646664
@time $(call spawn,$(build_bindir)/julia$(EXE) -e '')

appveyor.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,4 @@ build_script:
5252

5353
test_script:
5454
- usr\bin\julia -e "versioninfo()"
55-
- copy usr\lib\julia\sys.ji local.ji && usr\bin\julia -J local.ji -e "true" && del local.ji
5655
- cd test && ..\usr\bin\julia runtests.jl all && ..\usr\bin\julia runtests.jl libgit2-online pkg

contrib/windows/msys_build.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ for lib in SUITESPARSE ARPACK BLAS LAPACK FFTW \
164164
done
165165
echo 'override LIBLAPACK = $(LIBBLAS)' >> Make.user
166166
echo 'override LIBLAPACKNAME = $(LIBBLASNAME)' >> Make.user
167-
echo 'JULIA_SYSIMG_BUILD_FLAGS=--output-ji ../usr/lib/julia/sys.ji' >> Make.user
168167

169168
# Remaining dependencies:
170169
# libuv since its static lib is no longer included in the binaries

src/codegen.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ static Value *global_binding_pointer(jl_module_t *m, jl_sym_t *s,
591591
static jl_cgval_t emit_checked_var(Value *bp, jl_sym_t *name, jl_codectx_t *ctx, bool isvol=false);
592592
static Value *emit_condition(jl_value_t *cond, const std::string &msg, jl_codectx_t *ctx);
593593
static void allocate_gc_frame(BasicBlock *b0, jl_codectx_t *ctx);
594-
static void jl_finalize_module(std::unique_ptr<Module> m);
594+
static void jl_finalize_module(std::unique_ptr<Module> m, bool shadow);
595595
static GlobalVariable *prepare_global(GlobalVariable *G, Module *M = jl_builderModule);
596596

597597

@@ -836,7 +836,8 @@ static void to_function(jl_lambda_info_t *li)
836836
}
837837
// record that this function name came from this linfo,
838838
// so we can build a reverse mapping for debug-info.
839-
if (li->def != NULL) {
839+
bool toplevel = li->def == NULL;
840+
if (!toplevel) {
840841
const DataLayout &DL =
841842
#ifdef LLVM35
842843
m->getDataLayout();
@@ -850,10 +851,12 @@ static void to_function(jl_lambda_info_t *li)
850851
}
851852

852853
// success. add the result to the execution engine now
853-
jl_finalize_module(std::move(m));
854-
li->functionID = jl_assign_functionID(f, 0);
855-
if (specf)
856-
li->specFunctionID = jl_assign_functionID(specf, 1);
854+
jl_finalize_module(std::move(m), !toplevel);
855+
if (!toplevel) {
856+
li->functionID = jl_assign_functionID(f, 0);
857+
if (specf)
858+
li->specFunctionID = jl_assign_functionID(specf, 1);
859+
}
857860
// mark the pointer calling convention
858861
li->jlcall_api = (f->getFunctionType() == jl_func_sig ? 0 : 1);
859862

@@ -927,7 +930,7 @@ static void jl_setup_module(Module *m)
927930
// this takes ownership of a module after code emission is complete
928931
// and will add it to the execution engine when required (by jl_finalize_function)
929932
static void finalize_gc_frame(Module *m);
930-
static void jl_finalize_module(std::unique_ptr<Module> uniquem)
933+
static void jl_finalize_module(std::unique_ptr<Module> uniquem, bool shadow)
931934
{
932935
Module *m = uniquem.release(); // unique_ptr won't be able track what we do with this (the invariant is recovered by jl_finalize_function)
933936
finalize_gc_frame(m);
@@ -943,7 +946,11 @@ static void jl_finalize_module(std::unique_ptr<Module> uniquem)
943946
module_for_fname[F->getName()] = m;
944947
}
945948
#endif
946-
jl_add_to_shadow(m);
949+
#if defined(USE_ORCJIT) || defined(USE_MCJIT)
950+
// in the newer JITs, the shadow module is separate from the execution module
951+
if (shadow)
952+
#endif
953+
jl_add_to_shadow(m);
947954
}
948955

949956
// this ensures that llvmf has been emitted to the execution engine,
@@ -3762,7 +3769,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
37623769
else
37633770
builder.CreateRet(r);
37643771

3765-
jl_finalize_module(std::unique_ptr<Module>(M));
3772+
jl_finalize_module(std::unique_ptr<Module>(M), true);
37663773

37673774
return cw_proto;
37683775
}

src/debuginfo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,14 @@ class JuliaJITEventListener: public JITEventListener
247247
int8_t gc_state = jl_gc_safe_enter();
248248
uv_rwlock_wrlock(&threadsafe);
249249
jl_gc_safe_leave(gc_state);
250-
StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(F.getName());
250+
StringRef sName = F.getName();
251+
StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName);
251252
jl_lambda_info_t *linfo = NULL;
252253
if (linfo_it != linfo_in_flight.end()) {
253254
linfo = linfo_it->second;
254255
linfo_in_flight.erase(linfo_it);
256+
if (((Function*)linfo->functionObjectsDecls.functionObject)->getName().equals(sName))
257+
linfo->fptr = (jl_fptr_t)(uintptr_t)Code;
255258
}
256259
#if defined(_OS_WINDOWS_)
257260
create_PRUNTIME_FUNCTION((uint8_t*)Code, Size, F.getName(), (uint8_t*)Code, Size, NULL);
@@ -450,6 +453,8 @@ class JuliaJITEventListener: public JITEventListener
450453
if (linfo->compile_traced)
451454
triggered_linfos.push_back(linfo);
452455
linfo_in_flight.erase(linfo_it);
456+
if (((Function*)linfo->functionObjectsDecls.functionObject)->getName().equals(sName))
457+
linfo->fptr = (jl_fptr_t)(uintptr_t)Addr;
453458
}
454459
if (linfo)
455460
linfomap[Addr] = std::make_pair(Size, linfo);
@@ -522,6 +527,8 @@ class JuliaJITEventListener: public JITEventListener
522527
if (linfo_it != linfo_in_flight.end()) {
523528
linfo = linfo_it->second;
524529
linfo_in_flight.erase(linfo_it);
530+
if (((Function*)linfo->functionObjectsDecls.functionObject)->getName().equals(sName))
531+
linfo->fptr = (jl_fptr_t)(uintptr_t)Addr;
525532
}
526533
if (linfo)
527534
linfomap[Addr] = std::make_pair(Size, linfo);

src/gf.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,8 @@ static void _compile_all_deq(jl_array_t *found)
12141214
jl_lambda_info_t *linfo = NULL;
12151215
JL_GC_PUSH1(&linfo);
12161216
for (found_i = 0; found_i < found_l; found_i++) {
1217-
jl_printf(JL_STDERR, " %zd / %zd\r", found_i + 1, found_l);
1217+
if (found_i % (found_l / 300) == 0 || found_i == found_l - 1) // show 300 progress steps, to show progress without overwhelming log files
1218+
jl_printf(JL_STDERR, " %zd / %zd\r", found_i + 1, found_l);
12181219
jl_typemap_entry_t *ml = (jl_typemap_entry_t*)jl_cellref(found, found_i);
12191220
if (ml->func.value == NULL)
12201221
continue; // XXX: how does this happen
@@ -1223,7 +1224,10 @@ static void _compile_all_deq(jl_array_t *found)
12231224
if (jl_is_method(ml->func.value)) {
12241225
// type infer a copy of the template, to avoid modifying the template itself
12251226
templ = ml->func.method->lambda_template;
1226-
linfo = jl_get_specialized(ml->func.method, ml->sig, jl_emptysvec);
1227+
if (templ->unspecialized_ducttape)
1228+
linfo = templ->unspecialized_ducttape; // TODO: switch to using the ->tfunc field to store/retrieve this
1229+
else
1230+
linfo = jl_get_specialized(ml->func.method, ml->sig, jl_emptysvec);
12271231
}
12281232
else if (jl_is_lambda_info(ml->func.value)) {
12291233
templ = ml->func.linfo;
@@ -1261,6 +1265,8 @@ static void _compile_all_deq(jl_array_t *found)
12611265
templ->functionID = linfo->functionID;
12621266
templ->specFunctionID = linfo->specFunctionID;
12631267
templ->jlcall_api = linfo->jlcall_api;
1268+
templ->unspecialized_ducttape = linfo;
1269+
jl_gc_wb(templ, linfo);
12641270
}
12651271
}
12661272
}

0 commit comments

Comments
 (0)