From fde058518d4741f2db2aca3e01f0513fd151961f Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 28 Nov 2019 16:26:35 +0300 Subject: [PATCH] Use range metadata (#17956) --- mono/mini/decompose.c | 7 ++++--- mono/mini/mini-llvm-cpp.cpp | 12 ++++++++++++ mono/mini/mini-llvm-cpp.h | 3 +++ mono/mini/mini-llvm.c | 3 +++ mono/mini/mini.h | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index 8df66345a32..43052c39d86 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -1542,8 +1542,8 @@ mono_decompose_array_access_opts (MonoCompile *cfg) ins->opcode = OP_MOVE; break; case OP_LDLEN: - NEW_LOAD_MEMBASE_FLAGS (cfg, dest, OP_LOADI4_MEMBASE, ins->dreg, ins->sreg1, - ins->inst_imm, ins->flags); + NEW_LOAD_MEMBASE_FLAGS (cfg, dest, OP_LOADI4_MEMBASE, + ins->dreg, ins->sreg1, ins->inst_imm, ins->flags | MONO_INST_LDLEN); MONO_ADD_INS (cfg->cbb, dest); break; case OP_BOUNDS_CHECK: @@ -1586,7 +1586,8 @@ mono_decompose_array_access_opts (MonoCompile *cfg) break; case OP_STRLEN: MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, ins->dreg, - ins->sreg1, MONO_STRUCT_OFFSET (MonoString, length), ins->flags | MONO_INST_INVARIANT_LOAD); + ins->sreg1, MONO_STRUCT_OFFSET (MonoString, length), + ins->flags | MONO_INST_INVARIANT_LOAD | MONO_INST_LDLEN); break; default: break; diff --git a/mono/mini/mini-llvm-cpp.cpp b/mono/mini/mini-llvm-cpp.cpp index 3c95c3e5c79..4941545505e 100644 --- a/mono/mini/mini-llvm-cpp.cpp +++ b/mono/mini/mini-llvm-cpp.cpp @@ -230,6 +230,18 @@ mono_llvm_add_string_metadata (LLVMValueRef insref, const char* label, const cha } void +mono_llvm_add_range_metadata_i32 (LLVMValueRef insref, uint64_t min_value, uint64_t max_value) +{ + auto ins = unwrap (insref); + auto &ctx = ins->getContext (); + IntegerType *Int32Ty = Type::getInt32Ty (ctx); + Metadata *range_md [] = { + ConstantAsMetadata::get (ConstantInt::get(Int32Ty, min_value)), + ConstantAsMetadata::get (ConstantInt::get(Int32Ty, max_value))}; + ins->setMetadata (LLVMContext::MD_range, MDNode::get (ctx, range_md)); +} + +void mono_llvm_set_implicit_branch (LLVMBuilderRef builder, LLVMValueRef branch) { auto b = unwrap (builder); diff --git a/mono/mini/mini-llvm-cpp.h b/mono/mini/mini-llvm-cpp.h index ef56a6f3790..9f0195df017 100644 --- a/mono/mini/mini-llvm-cpp.h +++ b/mono/mini/mini-llvm-cpp.h @@ -99,6 +99,9 @@ void mono_llvm_add_string_metadata (LLVMValueRef insref, const char* label, const char* text); void +mono_llvm_add_range_metadata_i32 (LLVMValueRef insref, uint64_t min_value, uint64_t max_value); + +void mono_llvm_set_implicit_branch (LLVMBuilderRef builder, LLVMValueRef branch); void diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 7edd0cd2197..3b50d11f0f8 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -5781,6 +5781,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) addr = convert (ctx, addr, LLVMPointerType (t, 0)); values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, base, dname, is_faulting, is_volatile, LLVM_BARRIER_NONE); + + if ((ins->flags & MONO_INST_LDLEN) != 0) + mono_llvm_add_range_metadata_i32 (values [ins->dreg], 0, 2147483648 /* int.MaxValue + 1 */); if (!(is_faulting || is_volatile) && (ins->flags & MONO_INST_INVARIANT_LOAD)) { /* diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 17f86bff8c5..c06a8cae323 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -867,6 +867,7 @@ enum { MONO_INST_GC_CALLSITE = 128, /* On comparisons, mark the branch following the condition as likely to be taken */ MONO_INST_LIKELY = 128, + MONO_INST_LDLEN = 128, /* means LOAD is actually OP_LDLEN */ }; #define inst_c0 data.op[0].const_val -- 2.11.4.GIT