From fb22052f361a3c1ab2ddbc72ce22af313efa8df9 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Thu, 29 Dec 2022 15:45:05 +0100 Subject: [PATCH 1/5] Expand compare + brfalse/brtrue with single conditional branch opcodes --- src/mono/mono/mini/interp/transform.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 994033b8613b1e..99c6258408c0bc 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -9828,14 +9828,23 @@ interp_super_instructions (TransformData *td) switch (def->opcode) { case MINT_CEQ_I4: replace_opcode = negate ? MINT_BNE_UN_I4 : MINT_BEQ_I4; break; case MINT_CEQ_I8: replace_opcode = negate ? MINT_BNE_UN_I8 : MINT_BEQ_I8; break; - // Add more opcodes + case MINT_CGT_I4: replace_opcode = negate ? MINT_BLE_I4 : MINT_BGT_I4; break; + case MINT_CGT_I8: replace_opcode = negate ? MINT_BLE_I8 : MINT_BGT_I8; break; + case MINT_CLT_I4: replace_opcode = negate ? MINT_BGE_I4 : MINT_BLT_I4; break; + case MINT_CLT_I8: replace_opcode = negate ? MINT_BGE_I8 : MINT_BLT_I8; break; + case MINT_CGT_UN_I4: replace_opcode = negate ? MINT_BLE_UN_I4 : MINT_BGT_UN_I4; break; + case MINT_CGT_UN_I8: replace_opcode = negate ? MINT_BLE_UN_I8 : MINT_BGT_UN_I8; break; + case MINT_CLT_UN_I4: replace_opcode = negate ? MINT_BGE_UN_I4 : MINT_BLT_UN_I4; break; + case MINT_CLT_UN_I8: replace_opcode = negate ? MINT_BGE_UN_I8 : MINT_BLT_UN_I8; break; + case MINT_CEQ0_I4: replace_opcode = negate ? MINT_BRTRUE_I4 : MINT_BRFALSE_I4; break; // If def->opcode is MINT_CEQ0_I4 ins->opcode is inverted default: break; } if (replace_opcode != -1) { ins->opcode = replace_opcode; ins->sregs [0] = def->sregs [0]; - ins->sregs [1] = def->sregs [1]; + if (def->opcode != MINT_CEQ0_I4) + ins->sregs [1] = def->sregs [1]; interp_clear_ins (def); if (td->verbose_level) { g_print ("superins: "); From e1a792b60a8f0dbfc014fe1f7ca4837f79c1862b Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Fri, 30 Dec 2022 13:15:04 +0100 Subject: [PATCH 2/5] Check if local_ref_count is 1 --- src/mono/mono/mini/interp/transform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 99c6258408c0bc..d82eb21e3ee9ca 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -9823,7 +9823,7 @@ interp_super_instructions (TransformData *td) gboolean negate = opcode == MINT_BRFALSE_I4; int cond_sreg = ins->sregs [0]; InterpInst *def = td->locals [cond_sreg].def; - if (def != NULL) { + if (def != NULL && td->local_ref_count [cond_sreg] == 1) { int replace_opcode = -1; switch (def->opcode) { case MINT_CEQ_I4: replace_opcode = negate ? MINT_BNE_UN_I4 : MINT_BEQ_I4; break; @@ -9837,6 +9837,7 @@ interp_super_instructions (TransformData *td) case MINT_CLT_UN_I4: replace_opcode = negate ? MINT_BGE_UN_I4 : MINT_BLT_UN_I4; break; case MINT_CLT_UN_I8: replace_opcode = negate ? MINT_BGE_UN_I8 : MINT_BLT_UN_I8; break; case MINT_CEQ0_I4: replace_opcode = negate ? MINT_BRTRUE_I4 : MINT_BRFALSE_I4; break; // If def->opcode is MINT_CEQ0_I4 ins->opcode is inverted + // Add more opcodes default: break; } @@ -9846,6 +9847,8 @@ interp_super_instructions (TransformData *td) if (def->opcode != MINT_CEQ0_I4) ins->sregs [1] = def->sregs [1]; interp_clear_ins (def); + local_ref_count [cond_sreg]--; + mono_interp_stats.super_instructions++; if (td->verbose_level) { g_print ("superins: "); dump_interp_inst (ins); From 516d76b46f405690d87e0bdf53b7ba7157198b16 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Fri, 30 Dec 2022 15:37:27 +0100 Subject: [PATCH 3/5] Add floating-point opcodes --- src/mono/mono/mini/interp/transform.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index d82eb21e3ee9ca..66d93d35ec4c36 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -9836,6 +9836,16 @@ interp_super_instructions (TransformData *td) case MINT_CGT_UN_I8: replace_opcode = negate ? MINT_BLE_UN_I8 : MINT_BGT_UN_I8; break; case MINT_CLT_UN_I4: replace_opcode = negate ? MINT_BGE_UN_I4 : MINT_BLT_UN_I4; break; case MINT_CLT_UN_I8: replace_opcode = negate ? MINT_BGE_UN_I8 : MINT_BLT_UN_I8; break; + case MINT_CEQ_R4: replace_opcode = negate ? MINT_BNE_UN_R4 : MINT_BEQ_R4; break; + case MINT_CEQ_R8: replace_opcode = negate ? MINT_BNE_UN_R8 : MINT_BEQ_R8; break; + case MINT_CGT_R4: replace_opcode = negate ? MINT_BLE_R4 : MINT_BGT_R4; break; + case MINT_CGT_R8: replace_opcode = negate ? MINT_BLE_R8 : MINT_BGT_R8; break; + case MINT_CLT_R4: replace_opcode = negate ? MINT_BGE_R4 : MINT_BLT_R4; break; + case MINT_CLT_R8: replace_opcode = negate ? MINT_BGE_R8 : MINT_BLT_R8; break; + case MINT_CGT_UN_R4: replace_opcode = negate ? MINT_BLE_UN_R4 : MINT_BGT_UN_R4; break; + case MINT_CGT_UN_R8: replace_opcode = negate ? MINT_BLE_UN_R8 : MINT_BGT_UN_R8; break; + case MINT_CLT_UN_R4: replace_opcode = negate ? MINT_BGE_UN_R4 : MINT_BLT_UN_R4; break; + case MINT_CLT_UN_R8: replace_opcode = negate ? MINT_BGE_UN_R8 : MINT_BLT_UN_R8; break; case MINT_CEQ0_I4: replace_opcode = negate ? MINT_BRTRUE_I4 : MINT_BRFALSE_I4; break; // If def->opcode is MINT_CEQ0_I4 ins->opcode is inverted // Add more opcodes default: From 98e9728a2fba70551c44c0da78ea6b6b9689ab95 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Fri, 30 Dec 2022 21:34:59 +0100 Subject: [PATCH 4/5] use opposed opcodes for floats followed by a brfalse --- src/mono/mono/mini/interp/transform.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 66d93d35ec4c36..0df90cff315f14 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -9838,14 +9838,14 @@ interp_super_instructions (TransformData *td) case MINT_CLT_UN_I8: replace_opcode = negate ? MINT_BGE_UN_I8 : MINT_BLT_UN_I8; break; case MINT_CEQ_R4: replace_opcode = negate ? MINT_BNE_UN_R4 : MINT_BEQ_R4; break; case MINT_CEQ_R8: replace_opcode = negate ? MINT_BNE_UN_R8 : MINT_BEQ_R8; break; - case MINT_CGT_R4: replace_opcode = negate ? MINT_BLE_R4 : MINT_BGT_R4; break; - case MINT_CGT_R8: replace_opcode = negate ? MINT_BLE_R8 : MINT_BGT_R8; break; - case MINT_CLT_R4: replace_opcode = negate ? MINT_BGE_R4 : MINT_BLT_R4; break; - case MINT_CLT_R8: replace_opcode = negate ? MINT_BGE_R8 : MINT_BLT_R8; break; - case MINT_CGT_UN_R4: replace_opcode = negate ? MINT_BLE_UN_R4 : MINT_BGT_UN_R4; break; - case MINT_CGT_UN_R8: replace_opcode = negate ? MINT_BLE_UN_R8 : MINT_BGT_UN_R8; break; - case MINT_CLT_UN_R4: replace_opcode = negate ? MINT_BGE_UN_R4 : MINT_BLT_UN_R4; break; - case MINT_CLT_UN_R8: replace_opcode = negate ? MINT_BGE_UN_R8 : MINT_BLT_UN_R8; break; + case MINT_CGT_R4: replace_opcode = negate ? MINT_BLE_UN_R4 : MINT_BGT_R4; break; + case MINT_CGT_R8: replace_opcode = negate ? MINT_BLE_UN_R8 : MINT_BGT_R8; break; + case MINT_CLT_R4: replace_opcode = negate ? MINT_BGE_UN_R4 : MINT_BLT_R4; break; + case MINT_CLT_R8: replace_opcode = negate ? MINT_BGE_UN_R8 : MINT_BLT_R8; break; + case MINT_CGT_UN_R4: replace_opcode = negate ? MINT_BLE_R4 : MINT_BGT_UN_R4; break; + case MINT_CGT_UN_R8: replace_opcode = negate ? MINT_BLE_R8 : MINT_BGT_UN_R8; break; + case MINT_CLT_UN_R4: replace_opcode = negate ? MINT_BGE_R4 : MINT_BLT_UN_R4; break; + case MINT_CLT_UN_R8: replace_opcode = negate ? MINT_BGE_R8 : MINT_BLT_UN_R8; break; case MINT_CEQ0_I4: replace_opcode = negate ? MINT_BRTRUE_I4 : MINT_BRFALSE_I4; break; // If def->opcode is MINT_CEQ0_I4 ins->opcode is inverted // Add more opcodes default: From b970dcf5fb67502dcaf786cf2f7a5f6472b06e6f Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Tue, 3 Jan 2023 10:29:39 +0100 Subject: [PATCH 5/5] use local_ref_count directly --- src/mono/mono/mini/interp/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 0df90cff315f14..a6043d1744e96c 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -9823,7 +9823,7 @@ interp_super_instructions (TransformData *td) gboolean negate = opcode == MINT_BRFALSE_I4; int cond_sreg = ins->sregs [0]; InterpInst *def = td->locals [cond_sreg].def; - if (def != NULL && td->local_ref_count [cond_sreg] == 1) { + if (def != NULL && local_ref_count [cond_sreg] == 1) { int replace_opcode = -1; switch (def->opcode) { case MINT_CEQ_I4: replace_opcode = negate ? MINT_BNE_UN_I4 : MINT_BEQ_I4; break;