|
86 | 86 | #include <llvm/ExecutionEngine/ExecutionEngine.h> |
87 | 87 |
|
88 | 88 | using namespace llvm; |
89 | | -namespace llvm { |
90 | | - extern bool annotateSimdLoop(BasicBlock *latch); |
91 | | -} |
92 | 89 |
|
93 | 90 | #if defined(_OS_WINDOWS_) && !defined(NOMINMAX) |
94 | 91 | #define NOMINMAX |
@@ -296,8 +293,7 @@ static Function *jlegal_func; |
296 | 293 | static Function *jl_alloc_obj_func; |
297 | 294 | static Function *jl_newbits_func; |
298 | 295 | static Function *jl_typeof_func; |
299 | | -static Function *jl_simdloop_marker_func; |
300 | | -static Function *jl_simdivdep_marker_func; |
| 296 | +static Function *jl_loopinfo_marker_func; |
301 | 297 | static Function *jl_write_barrier_func; |
302 | 298 | static Function *jlisa_func; |
303 | 299 | static Function *jlsubtype_func; |
@@ -4100,14 +4096,43 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval) |
4100 | 4096 | ctx.builder.CreateCall(prepare_call(jlcopyast_func), |
4101 | 4097 | maybe_decay_untracked(boxed(ctx, ast))), true, jl_expr_type); |
4102 | 4098 | } |
4103 | | - else if (head == simdloop_sym) { |
4104 | | - jl_value_t *ivdep = args[0]; |
4105 | | - assert(jl_expr_nargs(ex) == 1 && jl_is_bool(ivdep)); |
4106 | | - if (ivdep == jl_false) { |
4107 | | - ctx.builder.CreateCall(prepare_call(jl_simdloop_marker_func)); |
4108 | | - } else { |
4109 | | - ctx.builder.CreateCall(prepare_call(jl_simdivdep_marker_func)); |
| 4099 | + else if (head == loopinfo_sym) { |
| 4100 | + // parse Expr(:loopinfo, "julia.simdloop", ("llvm.loop.vectorize.width", 4)) |
| 4101 | + SmallVector<Metadata *, 8> MDs; |
| 4102 | + for (int i = 0, ie = jl_expr_nargs(ex); i < ie; ++i) { |
| 4103 | + jl_value_t *arg = args[i]; |
| 4104 | + Metadata *MD; |
| 4105 | + if (arg == jl_nothing) |
| 4106 | + continue; |
| 4107 | + if (jl_is_symbol(arg)) { |
| 4108 | + MD = MDString::get(jl_LLVMContext, jl_symbol_name((jl_sym_t*)arg)); |
| 4109 | + } else if (jl_is_tuple(arg)) { |
| 4110 | + // TODO: are there loopinfo with more than one field? |
| 4111 | + if (jl_nfields(arg) != 2) |
| 4112 | + jl_error("loopinfo: only accept 2-arg tuple"); |
| 4113 | + jl_value_t* name = jl_fieldref(arg, 0); |
| 4114 | + jl_value_t* value = jl_fieldref(arg, 1); |
| 4115 | + if (!jl_is_symbol(name)) |
| 4116 | + jl_error("loopinfo: name needs to be a symbol"); |
| 4117 | + Metadata *MDVal; |
| 4118 | + if(jl_is_bool(value)) |
| 4119 | + MDVal = ConstantAsMetadata::get(ConstantInt::get(T_int1, jl_unbox_bool(value))); |
| 4120 | + if(jl_is_long(value)) |
| 4121 | + MDVal = ConstantAsMetadata::get(ConstantInt::get(T_int64, jl_unbox_long(value))); |
| 4122 | + if(!MDVal) |
| 4123 | + jl_error("loopinfo: value can only be a bool or a long"); |
| 4124 | + MD = MDNode::get(jl_LLVMContext, |
| 4125 | + { MDString::get(jl_LLVMContext, jl_symbol_name((jl_sym_t*)name)), MDVal }); |
| 4126 | + } |
| 4127 | + if (MD) |
| 4128 | + MDs.push_back(MD); |
| 4129 | + else |
| 4130 | + jl_error("loopinfo: argument needs to be either a symbol or a tuple of type (Symbol, Union{Int, Bool}"); |
4110 | 4131 | } |
| 4132 | + |
| 4133 | + MDNode* MD = MDNode::get(jl_LLVMContext, MDs); |
| 4134 | + CallInst *I = ctx.builder.CreateCall(prepare_call(jl_loopinfo_marker_func)); |
| 4135 | + I->setMetadata("julia.loopinfo", MD); |
4111 | 4136 | return jl_cgval_t(); |
4112 | 4137 | } |
4113 | 4138 | else if (head == goto_ifnot_sym) { |
@@ -7356,19 +7381,12 @@ static void init_julia_llvm_env(Module *m) |
7356 | 7381 | add_return_attr(jl_newbits_func, Attribute::NonNull); |
7357 | 7382 | add_named_global(jl_newbits_func, (void*)jl_new_bits); |
7358 | 7383 |
|
7359 | | - jl_simdloop_marker_func = Function::Create(FunctionType::get(T_void, {}, false), |
7360 | | - Function::ExternalLinkage, |
7361 | | - "julia.simdloop_marker"); |
7362 | | - jl_simdloop_marker_func->addFnAttr(Attribute::NoUnwind); |
7363 | | - jl_simdloop_marker_func->addFnAttr(Attribute::NoRecurse); |
7364 | | - jl_simdloop_marker_func->addFnAttr(Attribute::InaccessibleMemOnly); |
7365 | | - |
7366 | | - jl_simdivdep_marker_func = Function::Create(FunctionType::get(T_void, {}, false), |
| 7384 | + jl_loopinfo_marker_func = Function::Create(FunctionType::get(T_void, {}, false), |
7367 | 7385 | Function::ExternalLinkage, |
7368 | | - "julia.simdivdep_marker"); |
7369 | | - jl_simdivdep_marker_func->addFnAttr(Attribute::NoUnwind); |
7370 | | - jl_simdivdep_marker_func->addFnAttr(Attribute::NoRecurse); |
7371 | | - jl_simdivdep_marker_func->addFnAttr(Attribute::InaccessibleMemOnly); |
| 7386 | + "julia.loopinfo_marker"); |
| 7387 | + jl_loopinfo_marker_func->addFnAttr(Attribute::NoUnwind); |
| 7388 | + jl_loopinfo_marker_func->addFnAttr(Attribute::NoRecurse); |
| 7389 | + jl_loopinfo_marker_func->addFnAttr(Attribute::InaccessibleMemOnly); |
7372 | 7390 |
|
7373 | 7391 | jl_typeof_func = Function::Create(FunctionType::get(T_prjlvalue, {T_prjlvalue}, false), |
7374 | 7392 | Function::ExternalLinkage, |
|
0 commit comments