Skip to content

Commit

Permalink
[mono][interp] Completely remove short branches
Browse files Browse the repository at this point in the history
They don't seem to have any benefit at the expense of a lot of code and added complexity.
  • Loading branch information
BrzVlad committed Jul 23, 2024
1 parent 189a250 commit 057e2bd
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 364 deletions.
6 changes: 1 addition & 5 deletions src/mono/browser/runtime/jiterpreter-trace-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2745,8 +2745,7 @@ function append_call_handler_store_ret_ip (
builder: WasmBuilder, ip: MintOpcodePtr,
frame: NativePointer, opcode: MintOpcode
) {
const shortOffset = (opcode === MintOpcode.MINT_CALL_HANDLER_S),
retIp = shortOffset ? <any>ip + (3 * 2) : <any>ip + (4 * 2),
const retIp = <any>ip + (4 * 2),
clauseIndex = getU16(retIp - 2),
clauseDataOffset = get_imethod_clause_data_offset(frame, clauseIndex);

Expand All @@ -2773,9 +2772,6 @@ function getBranchDisplacement (
case MintOpArgType.MintOpBranch:
result = getI32_unaligned(payloadAddress);
break;
case MintOpArgType.MintOpShortBranch:
result = getI16(payloadAddress);
break;
case MintOpArgType.MintOpShortAndBranch:
result = getI32_unaligned(payloadAddress + 2);
break;
Expand Down
239 changes: 5 additions & 234 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4474,27 +4474,13 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
#define BACK_BRANCH_PROFILE(offset)
#endif

MINT_IN_CASE(MINT_BR_S) {
short br_offset = (short) *(ip + 1);
BACK_BRANCH_PROFILE (br_offset);
ip += br_offset;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BR) {
gint32 br_offset = (gint32) READ32(ip + 1);
BACK_BRANCH_PROFILE (br_offset);
ip += br_offset;
MINT_IN_BREAK;
}

#define ZEROP_S(datatype, op) \
if (LOCAL_VAR (ip [1], datatype) op 0) { \
gint16 br_offset = (gint16) ip [2]; \
BACK_BRANCH_PROFILE (br_offset); \
ip += br_offset; \
} else \
ip += 3;

#define ZEROP(datatype, op) \
if (LOCAL_VAR (ip [1], datatype) op 0) { \
gint32 br_offset = (gint32)READ32(ip + 2); \
Expand All @@ -4503,39 +4489,18 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
} else \
ip += 4;

MINT_IN_CASE(MINT_BRFALSE_I4_S)
ZEROP_S(gint32, ==);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRFALSE_I8_S)
ZEROP_S(gint64, ==);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRFALSE_I4)
ZEROP(gint32, ==);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRFALSE_I8)
ZEROP(gint64, ==);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRTRUE_I4_S)
ZEROP_S(gint32, !=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRTRUE_I8_S)
ZEROP_S(gint64, !=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRTRUE_I4)
ZEROP(gint32, !=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BRTRUE_I8)
ZEROP(gint64, !=);
MINT_IN_BREAK;
#define CONDBR_S(cond) \
if (cond) { \
gint16 br_offset = (gint16) ip [3]; \
BACK_BRANCH_PROFILE (br_offset); \
ip += br_offset; \
} else \
ip += 4;
#define BRELOP_S(datatype, op) \
CONDBR_S(LOCAL_VAR (ip [1], datatype) op LOCAL_VAR (ip [2], datatype))

#define CONDBR(cond) \
if (cond) { \
Expand All @@ -4548,24 +4513,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
#define BRELOP(datatype, op) \
CONDBR(LOCAL_VAR (ip [1], datatype) op LOCAL_VAR (ip [2], datatype))

MINT_IN_CASE(MINT_BEQ_I4_S)
BRELOP_S(gint32, ==)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BEQ_I8_S)
BRELOP_S(gint64, ==)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BEQ_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(!isunordered (f1, f2) && f1 == f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BEQ_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(!mono_isunordered (d1, d2) && d1 == d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BEQ_I4)
BRELOP(gint32, ==)
MINT_IN_BREAK;
Expand All @@ -4584,24 +4531,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(!mono_isunordered (d1, d2) && d1 == d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGE_I4_S)
BRELOP_S(gint32, >=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGE_I8_S)
BRELOP_S(gint64, >=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGE_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(!isunordered (f1, f2) && f1 >= f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGE_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(!mono_isunordered (d1, d2) && d1 >= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGE_I4)
BRELOP(gint32, >=)
MINT_IN_BREAK;
Expand All @@ -4620,24 +4549,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(!mono_isunordered (d1, d2) && d1 >= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_I4_S)
BRELOP_S(gint32, >)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGT_I8_S)
BRELOP_S(gint64, >)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGT_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(!isunordered (f1, f2) && f1 > f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(!mono_isunordered (d1, d2) && d1 > d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_I4)
BRELOP(gint32, >)
MINT_IN_BREAK;
Expand All @@ -4656,24 +4567,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(!mono_isunordered (d1, d2) && d1 > d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_I4_S)
BRELOP_S(gint32, <)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLT_I8_S)
BRELOP_S(gint64, <)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLT_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(!isunordered (f1, f2) && f1 < f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(!mono_isunordered (d1, d2) && d1 < d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_I4)
BRELOP(gint32, <)
MINT_IN_BREAK;
Expand All @@ -4692,24 +4585,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(!mono_isunordered (d1, d2) && d1 < d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_I4_S)
BRELOP_S(gint32, <=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLE_I8_S)
BRELOP_S(gint64, <=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLE_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(!isunordered (f1, f2) && f1 <= f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(!mono_isunordered (d1, d2) && d1 <= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_I4)
BRELOP(gint32, <=)
MINT_IN_BREAK;
Expand All @@ -4728,24 +4603,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(!mono_isunordered (d1, d2) && d1 <= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BNE_UN_I4_S)
BRELOP_S(gint32, !=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BNE_UN_I8_S)
BRELOP_S(gint64, !=)
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BNE_UN_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(isunordered (f1, f2) || f1 != f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BNE_UN_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(mono_isunordered (d1, d2) || d1 != d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BNE_UN_I4)
BRELOP(gint32, !=)
MINT_IN_BREAK;
Expand All @@ -4765,14 +4622,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
MINT_IN_BREAK;
}

#define BRELOP_S_CAST(datatype, op) \
if (LOCAL_VAR (ip [1], datatype) op LOCAL_VAR (ip [2], datatype)) { \
gint16 br_offset = (gint16) ip [3]; \
BACK_BRANCH_PROFILE (br_offset); \
ip += br_offset; \
} else \
ip += 4;

#define BRELOP_CAST(datatype, op) \
if (LOCAL_VAR (ip [1], datatype) op LOCAL_VAR (ip [2], datatype)) { \
gint32 br_offset = (gint32)READ32(ip + 3); \
Expand All @@ -4781,24 +4630,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
} else \
ip += 5;

MINT_IN_CASE(MINT_BGE_UN_I4_S)
BRELOP_S_CAST(guint32, >=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGE_UN_I8_S)
BRELOP_S_CAST(guint64, >=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGE_UN_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(isunordered (f1, f2) || f1 >= f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGE_UN_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(mono_isunordered (d1, d2) || d1 >= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGE_UN_I4)
BRELOP_CAST(guint32, >=);
MINT_IN_BREAK;
Expand All @@ -4817,24 +4648,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(mono_isunordered (d1, d2) || d1 >= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_UN_I4_S)
BRELOP_S_CAST(guint32, >);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGT_UN_I8_S)
BRELOP_S_CAST(guint64, >);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BGT_UN_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(isunordered (f1, f2) || f1 > f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_UN_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(mono_isunordered (d1, d2) || d1 > d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BGT_UN_I4)
BRELOP_CAST(guint32, >);
MINT_IN_BREAK;
Expand All @@ -4853,24 +4666,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(mono_isunordered (d1, d2) || d1 > d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_UN_I4_S)
BRELOP_S_CAST(guint32, <=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLE_UN_I8_S)
BRELOP_S_CAST(guint64, <=);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLE_UN_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(isunordered (f1, f2) || f1 <= f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_UN_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(mono_isunordered (d1, d2) || d1 <= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLE_UN_I4)
BRELOP_CAST(guint32, <=);
MINT_IN_BREAK;
Expand All @@ -4889,24 +4684,6 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
CONDBR(mono_isunordered (d1, d2) || d1 <= d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_UN_I4_S)
BRELOP_S_CAST(guint32, <);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLT_UN_I8_S)
BRELOP_S_CAST(guint64, <);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BLT_UN_R4_S) {
float f1 = LOCAL_VAR (ip [1], float);
float f2 = LOCAL_VAR (ip [2], float);
CONDBR_S(isunordered (f1, f2) || f1 < f2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_UN_R8_S) {
double d1 = LOCAL_VAR (ip [1], double);
double d2 = LOCAL_VAR (ip [2], double);
CONDBR_S(mono_isunordered (d1, d2) || d1 < d2)
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_BLT_UN_I4)
BRELOP_CAST(guint32, <);
MINT_IN_BREAK;
Expand Down Expand Up @@ -7128,31 +6905,25 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
ip = ret_ip;
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_CALL_HANDLER)
MINT_IN_CASE(MINT_CALL_HANDLER_S) {
gboolean short_offset = *ip == MINT_CALL_HANDLER_S;
const guint16 *ret_ip = short_offset ? (ip + 3) : (ip + 4);
MINT_IN_CASE(MINT_CALL_HANDLER) {
const guint16 *ret_ip = ip + 4;
guint16 clause_index = *(ret_ip - 1);

*(const guint16**)(locals + frame->imethod->clause_data_offsets [clause_index]) = ret_ip;

// jump to clause
ip += short_offset ? (gint16)*(ip + 1) : (gint32)READ32 (ip + 1);
ip += (gint32)READ32 (ip + 1);
MINT_IN_BREAK;
}

MINT_IN_CASE(MINT_LEAVE_CHECK)
MINT_IN_CASE(MINT_LEAVE_S_CHECK) {
int leave_opcode = *ip;

MINT_IN_CASE(MINT_LEAVE_CHECK) {
if (frame->imethod->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE) {
MonoException *abort_exc = mono_interp_leave (frame);
if (abort_exc)
THROW_EX (abort_exc, ip);
}

gboolean const short_offset = leave_opcode == MINT_LEAVE_S_CHECK;
ip += short_offset ? (gint16)*(ip + 1) : (gint32)READ32 (ip + 1);
ip += (gint32)READ32 (ip + 1);
MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_ICALL) {
Expand Down
Loading

0 comments on commit 057e2bd

Please sign in to comment.