diff --git a/src/codegen.cpp b/src/codegen.cpp index fc77446948b61..3ea8410470d7c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -64,6 +64,7 @@ #include // for llvmcall #include // for llvmcall inlining #include // for llvmcall validation +#include // C API #include @@ -7145,3 +7146,15 @@ extern "C" void jl_dump_llvm_type(void *v) #endif putchar('\n'); } + +extern void jl_write_bitcode_func(void *F, char *fname) { + std::error_code EC; + raw_fd_ostream OS(fname, EC, sys::fs::F_None); + llvm::WriteBitcodeToFile(((llvm::Function*)F)->getParent(), OS); +} + +extern void jl_write_bitcode_module(void *M, char *fname) { + std::error_code EC; + raw_fd_ostream OS(fname, EC, sys::fs::F_None); + llvm::WriteBitcodeToFile((llvm::Module*)M, OS); +} diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index 20447cced1874..d6db8c7ab68c6 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "llvm/Analysis/CFG.h" #include #include @@ -248,7 +249,7 @@ struct State { std::map ReversePtrNumbering; // Neighbors in the coloring interference graph. I.e. for each value, the // indices of other values that are used simultaneously at some safe point. - std::vector> Neighbors; + std::vector> Neighbors; // The result of the local analysis std::map BBStates; @@ -823,17 +824,19 @@ void LateLowerGCFrame::ComputeLiveSets(Function &F, State &S) { } // Compute the interference graph for (int i = 0; i <= S.MaxPtrNumber; ++i) { - std::vector Neighbors; + SetVector Neighbors; + BitVector NeighborBits(S.MaxPtrNumber); for (auto it : S.SafepointNumbering) { const BitVector &LS = S.LiveSets[it.second]; if ((unsigned)i >= LS.size() || !LS[i]) continue; - for (int Idx = LS.find_first(); Idx >= 0; Idx = LS.find_next(Idx)) { - // We explicitly let i be a neighbor of itself, to distinguish - // between being the only value live at a safepoint, vs not - // being live at any safepoint. - Neighbors.push_back(Idx); - } + NeighborBits |= LS; + } + for (int Idx = NeighborBits.find_first(); Idx >= 0; Idx = NeighborBits.find_next(Idx)) { + // We explicitly let i be a neighbor of itself, to distinguish + // between being the only value live at a safepoint, vs not + // being live at any safepoint. + Neighbors.insert(Idx); } S.Neighbors.push_back(Neighbors); } @@ -886,8 +889,8 @@ struct PEOIterator { }; std::vector Elements; std::vector> Levels; - const std::vector> &Neighbors; - PEOIterator(const std::vector> &Neighbors) : Neighbors(Neighbors) { + const std::vector> &Neighbors; + PEOIterator(const std::vector> &Neighbors) : Neighbors(Neighbors) { // Initialize State std::vector FirstLevel; for (unsigned i = 0; i < Neighbors.size(); ++i) { diff --git a/test/llvmpasses/lit.cfg b/test/llvmpasses/lit.cfg index c5b5ace6ec526..3ba90cde691c4 100644 --- a/test/llvmpasses/lit.cfg +++ b/test/llvmpasses/lit.cfg @@ -7,9 +7,10 @@ import lit.util import lit.formats config.name = 'Julia' -config.suffixes = ['.ll'] +config.suffixes = ['.ll','.jl'] config.test_source_root = os.path.dirname(__file__) -config.test_format = lit.formats.ShTest(False) +config.test_format = lit.formats.ShTest(True) -path = os.path.pathsep.join((os.path.join(os.path.dirname(__file__),"../../usr/tools"), config.environment['PATH'])) +path = os.path.pathsep.join((os.path.join(os.path.dirname(__file__),"../../usr/tools"), os.path.join(os.path.dirname(__file__),"../../usr/bin"), config.environment['PATH'])) config.environment['PATH'] = path +config.environment['HOME'] = "/tmp" diff --git a/test/llvmpasses/safepoint_stress.jl b/test/llvmpasses/safepoint_stress.jl new file mode 100644 index 0000000000000..29383f230b149 --- /dev/null +++ b/test/llvmpasses/safepoint_stress.jl @@ -0,0 +1,25 @@ +# RUN: julia --startup-file=no %s | opt -load libjulia.so -LateLowerGCFrame -S - | FileCheck %s + +println(""" +%jl_value_t = type opaque +declare %jl_value_t addrspace(10)* @alloc() +declare void @one_arg_boxed(%jl_value_t addrspace(10)*) +declare %jl_value_t*** @jl_get_ptls_states() + +define void @stress(i64 %a, i64 %b) { + %ptls = call %jl_value_t*** @jl_get_ptls_states() +""") + +# CHECK: %gcframe = alloca %jl_value_t addrspace(10)*, i32 10002 +for i = 1:10000 + println("\t%arg$i = call %jl_value_t addrspace(10)* @alloc()") +end + +for i = 1:10000 + println("\tcall void @one_arg_boxed(%jl_value_t addrspace(10)* %arg$i)") +end + +println(""" + ret void +} +""")