From 9628d4056f9d930207544df93ab8198ad7998157 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 29 Oct 2020 12:02:42 +0000 Subject: [PATCH] [interp] Fold "ldstr".Length to a constant A similar optimization for RyuJIT was quite profitable judging by the jit-diff: https://github.com/dotnet/runtime/pull/1378 Example: ```csharp static int Test() { return "hello".Length; } ``` Current `MONO_VERBOSE_METHOD=Test` output: ``` IR_0000: ldstr 0 IR_0002: strlen IR_0003: ret ``` New output: ``` IR_0000: ldc.i4.5 IR_0001: ret ``` --- mono/mini/interp/transform.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index 2711262fbbb6..029ad4dc63eb 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -1629,8 +1629,19 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas if (tm [0] == 'g') { if (strcmp (tm, "get_Chars") == 0) *op = MINT_GETCHR; - else if (strcmp (tm, "get_Length") == 0) + else if (strcmp(tm, "get_Length") == 0) { + // try to fold "ldstr".get_Length into a constant + if (td->last_ins && td->last_ins->opcode == MINT_LDSTR && interp_ip_in_cbb(td, td->ip - td->il_code)) { + MonoString* str = (MonoString*)td->data_items[td->last_ins->data[0]]; + g_assert(str && str->length >= 0); + interp_clear_ins(td->last_ins); + interp_get_ldc_i4_from_const(td, NULL, str->length); + SET_SIMPLE_TYPE(td->sp - 1, STACK_TYPE_I4); + td->ip += 5; + return TRUE; + } *op = MINT_STRLEN; + } } } else if (type_index >= 0) { return interp_handle_magic_type_intrinsics (td, target_method, csignature, type_index);