Skip to content

Commit ac89819

Browse files
authored
[mono][interp] Remove short branches (#105386)
* [mono][interp] Make all branch super instructions operate on long offsets Previously they were all short branches without long counterparts. This was buggy and awkward because we tried to compute early conservatively whether a branch is short or long, at superins generation time. The conditions would always hold and we had no fallback if the branch didn't turn out to actually be short. Having a long offset for these branches should have negligible perf impact. * [mono][wasm] Fix jiterp for branch superins * [mono][interp] Don't compute native offset estimate during super ins pass We generate superins without caring if the branch is long or short since the superinstructions use a long offset now. * [mono][interp] Completely remove short branches They don't seem to have any benefit at the expense of a lot of code and added complexity.
1 parent 02de2df commit ac89819

File tree

11 files changed

+134
-527
lines changed

11 files changed

+134
-527
lines changed

src/mono/browser/runtime/jiterpreter-opcodes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const enum MintOpArgType {
4545
MintOpTwoShorts,
4646
MintOpTwoInts,
4747
MintOpShortAndInt,
48-
MintOpShortAndShortBranch,
48+
MintOpShortAndBranch,
4949
MintOpPair2,
5050
MintOpPair3,
5151
MintOpPair4

src/mono/browser/runtime/jiterpreter-tables.ts

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,16 @@ export const binopTable: { [opcode: number]: OpRec3 | OpRec4 | undefined } = {
194194
};
195195

196196
export const relopbranchTable: { [opcode: number]: [comparisonOpcode: MintOpcode, immediateOpcode: WasmOpcode | false, isSafepoint: boolean] | MintOpcode | undefined } = {
197-
[MintOpcode.MINT_BEQ_I4_S]: MintOpcode.MINT_CEQ_I4,
198-
[MintOpcode.MINT_BNE_UN_I4_S]: MintOpcode.MINT_CNE_I4,
199-
[MintOpcode.MINT_BGT_I4_S]: MintOpcode.MINT_CGT_I4,
200-
[MintOpcode.MINT_BGT_UN_I4_S]: MintOpcode.MINT_CGT_UN_I4,
201-
[MintOpcode.MINT_BLT_I4_S]: MintOpcode.MINT_CLT_I4,
202-
[MintOpcode.MINT_BLT_UN_I4_S]: MintOpcode.MINT_CLT_UN_I4,
203-
[MintOpcode.MINT_BGE_I4_S]: MintOpcode.MINT_CGE_I4,
204-
[MintOpcode.MINT_BGE_UN_I4_S]: MintOpcode.MINT_CGE_UN_I4,
205-
[MintOpcode.MINT_BLE_I4_S]: MintOpcode.MINT_CLE_I4,
206-
[MintOpcode.MINT_BLE_UN_I4_S]: MintOpcode.MINT_CLE_UN_I4,
197+
[MintOpcode.MINT_BEQ_I4]: MintOpcode.MINT_CEQ_I4,
198+
[MintOpcode.MINT_BNE_UN_I4]: MintOpcode.MINT_CNE_I4,
199+
[MintOpcode.MINT_BGT_I4]: MintOpcode.MINT_CGT_I4,
200+
[MintOpcode.MINT_BGT_UN_I4]: MintOpcode.MINT_CGT_UN_I4,
201+
[MintOpcode.MINT_BLT_I4]: MintOpcode.MINT_CLT_I4,
202+
[MintOpcode.MINT_BLT_UN_I4]: MintOpcode.MINT_CLT_UN_I4,
203+
[MintOpcode.MINT_BGE_I4]: MintOpcode.MINT_CGE_I4,
204+
[MintOpcode.MINT_BGE_UN_I4]: MintOpcode.MINT_CGE_UN_I4,
205+
[MintOpcode.MINT_BLE_I4]: MintOpcode.MINT_CLE_I4,
206+
[MintOpcode.MINT_BLE_UN_I4]: MintOpcode.MINT_CLE_UN_I4,
207207

208208
[MintOpcode.MINT_BEQ_I4_SP]: [MintOpcode.MINT_CEQ_I4, false, true],
209209
[MintOpcode.MINT_BNE_UN_I4_SP]: [MintOpcode.MINT_CNE_I4, false, true],
@@ -227,16 +227,16 @@ export const relopbranchTable: { [opcode: number]: [comparisonOpcode: MintOpcode
227227
[MintOpcode.MINT_BLE_I4_IMM_SP]: [MintOpcode.MINT_CLE_I4, WasmOpcode.i32_const, true],
228228
[MintOpcode.MINT_BLE_UN_I4_IMM_SP]: [MintOpcode.MINT_CLE_UN_I4, WasmOpcode.i32_const, true],
229229

230-
[MintOpcode.MINT_BEQ_I8_S]: MintOpcode.MINT_CEQ_I8,
231-
[MintOpcode.MINT_BNE_UN_I8_S]: MintOpcode.MINT_CNE_I8,
232-
[MintOpcode.MINT_BGT_I8_S]: MintOpcode.MINT_CGT_I8,
233-
[MintOpcode.MINT_BGT_UN_I8_S]: MintOpcode.MINT_CGT_UN_I8,
234-
[MintOpcode.MINT_BLT_I8_S]: MintOpcode.MINT_CLT_I8,
235-
[MintOpcode.MINT_BLT_UN_I8_S]: MintOpcode.MINT_CLT_UN_I8,
236-
[MintOpcode.MINT_BGE_I8_S]: MintOpcode.MINT_CGE_I8,
237-
[MintOpcode.MINT_BGE_UN_I8_S]: MintOpcode.MINT_CGE_UN_I8,
238-
[MintOpcode.MINT_BLE_I8_S]: MintOpcode.MINT_CLE_I8,
239-
[MintOpcode.MINT_BLE_UN_I8_S]: MintOpcode.MINT_CLE_UN_I8,
230+
[MintOpcode.MINT_BEQ_I8]: MintOpcode.MINT_CEQ_I8,
231+
[MintOpcode.MINT_BNE_UN_I8]: MintOpcode.MINT_CNE_I8,
232+
[MintOpcode.MINT_BGT_I8]: MintOpcode.MINT_CGT_I8,
233+
[MintOpcode.MINT_BGT_UN_I8]: MintOpcode.MINT_CGT_UN_I8,
234+
[MintOpcode.MINT_BLT_I8]: MintOpcode.MINT_CLT_I8,
235+
[MintOpcode.MINT_BLT_UN_I8]: MintOpcode.MINT_CLT_UN_I8,
236+
[MintOpcode.MINT_BGE_I8]: MintOpcode.MINT_CGE_I8,
237+
[MintOpcode.MINT_BGE_UN_I8]: MintOpcode.MINT_CGE_UN_I8,
238+
[MintOpcode.MINT_BLE_I8]: MintOpcode.MINT_CLE_I8,
239+
[MintOpcode.MINT_BLE_UN_I8]: MintOpcode.MINT_CLE_UN_I8,
240240

241241
[MintOpcode.MINT_BEQ_I8_IMM_SP]: [MintOpcode.MINT_CEQ_I8, WasmOpcode.i64_const, true],
242242
// FIXME: Missing compare opcode
@@ -250,27 +250,27 @@ export const relopbranchTable: { [opcode: number]: [comparisonOpcode: MintOpcode
250250
[MintOpcode.MINT_BLE_I8_IMM_SP]: [MintOpcode.MINT_CLE_I8, WasmOpcode.i64_const, true],
251251
[MintOpcode.MINT_BLE_UN_I8_IMM_SP]: [MintOpcode.MINT_CLE_UN_I8, WasmOpcode.i64_const, true],
252252

253-
[MintOpcode.MINT_BEQ_R4_S]: MintOpcode.MINT_CEQ_R4,
254-
[MintOpcode.MINT_BNE_UN_R4_S]: <any>JiterpSpecialOpcode.CNE_UN_R4,
255-
[MintOpcode.MINT_BGT_R4_S]: MintOpcode.MINT_CGT_R4,
256-
[MintOpcode.MINT_BGT_UN_R4_S]: MintOpcode.MINT_CGT_UN_R4,
257-
[MintOpcode.MINT_BLT_R4_S]: MintOpcode.MINT_CLT_R4,
258-
[MintOpcode.MINT_BLT_UN_R4_S]: MintOpcode.MINT_CLT_UN_R4,
259-
[MintOpcode.MINT_BGE_R4_S]: MintOpcode.MINT_CGE_R4,
260-
[MintOpcode.MINT_BGE_UN_R4_S]: <any>JiterpSpecialOpcode.CGE_UN_R4,
261-
[MintOpcode.MINT_BLE_R4_S]: MintOpcode.MINT_CLE_R4,
262-
[MintOpcode.MINT_BLE_UN_R4_S]: <any>JiterpSpecialOpcode.CLE_UN_R4,
263-
264-
[MintOpcode.MINT_BEQ_R8_S]: MintOpcode.MINT_CEQ_R8,
265-
[MintOpcode.MINT_BNE_UN_R8_S]: <any>JiterpSpecialOpcode.CNE_UN_R8,
266-
[MintOpcode.MINT_BGT_R8_S]: MintOpcode.MINT_CGT_R8,
267-
[MintOpcode.MINT_BGT_UN_R8_S]: MintOpcode.MINT_CGT_UN_R8,
268-
[MintOpcode.MINT_BLT_R8_S]: MintOpcode.MINT_CLT_R8,
269-
[MintOpcode.MINT_BLT_UN_R8_S]: MintOpcode.MINT_CLT_UN_R8,
270-
[MintOpcode.MINT_BGE_R8_S]: MintOpcode.MINT_CGE_R8,
271-
[MintOpcode.MINT_BGE_UN_R8_S]: <any>JiterpSpecialOpcode.CGE_UN_R8,
272-
[MintOpcode.MINT_BLE_R8_S]: MintOpcode.MINT_CLE_R8,
273-
[MintOpcode.MINT_BLE_UN_R8_S]: <any>JiterpSpecialOpcode.CLE_UN_R8,
253+
[MintOpcode.MINT_BEQ_R4]: MintOpcode.MINT_CEQ_R4,
254+
[MintOpcode.MINT_BNE_UN_R4]: <any>JiterpSpecialOpcode.CNE_UN_R4,
255+
[MintOpcode.MINT_BGT_R4]: MintOpcode.MINT_CGT_R4,
256+
[MintOpcode.MINT_BGT_UN_R4]: MintOpcode.MINT_CGT_UN_R4,
257+
[MintOpcode.MINT_BLT_R4]: MintOpcode.MINT_CLT_R4,
258+
[MintOpcode.MINT_BLT_UN_R4]: MintOpcode.MINT_CLT_UN_R4,
259+
[MintOpcode.MINT_BGE_R4]: MintOpcode.MINT_CGE_R4,
260+
[MintOpcode.MINT_BGE_UN_R4]: <any>JiterpSpecialOpcode.CGE_UN_R4,
261+
[MintOpcode.MINT_BLE_R4]: MintOpcode.MINT_CLE_R4,
262+
[MintOpcode.MINT_BLE_UN_R4]: <any>JiterpSpecialOpcode.CLE_UN_R4,
263+
264+
[MintOpcode.MINT_BEQ_R8]: MintOpcode.MINT_CEQ_R8,
265+
[MintOpcode.MINT_BNE_UN_R8]: <any>JiterpSpecialOpcode.CNE_UN_R8,
266+
[MintOpcode.MINT_BGT_R8]: MintOpcode.MINT_CGT_R8,
267+
[MintOpcode.MINT_BGT_UN_R8]: MintOpcode.MINT_CGT_UN_R8,
268+
[MintOpcode.MINT_BLT_R8]: MintOpcode.MINT_CLT_R8,
269+
[MintOpcode.MINT_BLT_UN_R8]: MintOpcode.MINT_CLT_UN_R8,
270+
[MintOpcode.MINT_BGE_R8]: MintOpcode.MINT_CGE_R8,
271+
[MintOpcode.MINT_BGE_UN_R8]: <any>JiterpSpecialOpcode.CGE_UN_R8,
272+
[MintOpcode.MINT_BLE_R8]: MintOpcode.MINT_CLE_R8,
273+
[MintOpcode.MINT_BLE_UN_R8]: <any>JiterpSpecialOpcode.CLE_UN_R8,
274274
};
275275

276276
export const mathIntrinsicTable: { [opcode: number]: [isUnary: boolean, isF32: boolean, opcodeOrFuncName: WasmOpcode | string] } = {

src/mono/browser/runtime/jiterpreter-trace-generator.ts

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ export function generateBackwardBranchTable (
218218

219219
switch (opcode) {
220220
case MintOpcode.MINT_CALL_HANDLER:
221-
case MintOpcode.MINT_CALL_HANDLER_S:
222221
// While this formally isn't a backward branch target, we want to record
223222
// the offset of its following instruction so that the jiterpreter knows
224223
// to generate the necessary dispatch code to enable branching back to it.
@@ -506,21 +505,15 @@ export function generateWasmBody (
506505
}
507506

508507
// Other conditional branch types are handled by the relop table.
509-
case MintOpcode.MINT_BRFALSE_I4_S:
510-
case MintOpcode.MINT_BRTRUE_I4_S:
511508
case MintOpcode.MINT_BRFALSE_I4_SP:
512509
case MintOpcode.MINT_BRTRUE_I4_SP:
513-
case MintOpcode.MINT_BRFALSE_I8_S:
514-
case MintOpcode.MINT_BRTRUE_I8_S:
515510
if (!emit_branch(builder, ip, frame, opcode))
516511
ip = abort;
517512
else
518513
isConditionallyExecuted = true;
519514
break;
520515

521-
case MintOpcode.MINT_BR_S:
522516
case MintOpcode.MINT_CALL_HANDLER:
523-
case MintOpcode.MINT_CALL_HANDLER_S:
524517
if (!emit_branch(builder, ip, frame, opcode))
525518
ip = abort;
526519
else {
@@ -1293,7 +1286,6 @@ export function generateWasmBody (
12931286
// These are generated in place of regular LEAVEs inside of the body of a catch clause.
12941287
// We can safely assume that during normal execution, catch clauses won't be running.
12951288
case MintOpcode.MINT_LEAVE_CHECK:
1296-
case MintOpcode.MINT_LEAVE_S_CHECK:
12971289
append_bailout(builder, ip, BailoutReason.LeaveCheck);
12981290
pruneOpcodes = true;
12991291
break;
@@ -2743,10 +2735,9 @@ function emit_unop (builder: WasmBuilder, ip: MintOpcodePtr, opcode: MintOpcode)
27432735

27442736
function append_call_handler_store_ret_ip (
27452737
builder: WasmBuilder, ip: MintOpcodePtr,
2746-
frame: NativePointer, opcode: MintOpcode
2738+
frame: NativePointer
27472739
) {
2748-
const shortOffset = (opcode === MintOpcode.MINT_CALL_HANDLER_S),
2749-
retIp = shortOffset ? <any>ip + (3 * 2) : <any>ip + (4 * 2),
2740+
const retIp = <any>ip + (4 * 2),
27502741
clauseIndex = getU16(retIp - 2),
27512742
clauseDataOffset = get_imethod_clause_data_offset(frame, clauseIndex);
27522743

@@ -2773,11 +2764,8 @@ function getBranchDisplacement (
27732764
case MintOpArgType.MintOpBranch:
27742765
result = getI32_unaligned(payloadAddress);
27752766
break;
2776-
case MintOpArgType.MintOpShortBranch:
2777-
result = getI16(payloadAddress);
2778-
break;
2779-
case MintOpArgType.MintOpShortAndShortBranch:
2780-
result = getI16(payloadAddress + 2);
2767+
case MintOpArgType.MintOpShortAndBranch:
2768+
result = getI32_unaligned(payloadAddress + 2);
27812769
break;
27822770
default:
27832771
return undefined;
@@ -2808,11 +2796,8 @@ function emit_branch (
28082796
// branch target (if possible), bailing out at the end otherwise
28092797
switch (opcode) {
28102798
case MintOpcode.MINT_CALL_HANDLER:
2811-
case MintOpcode.MINT_CALL_HANDLER_S:
2812-
case MintOpcode.MINT_BR:
2813-
case MintOpcode.MINT_BR_S: {
2814-
const isCallHandler = (opcode === MintOpcode.MINT_CALL_HANDLER) ||
2815-
(opcode === MintOpcode.MINT_CALL_HANDLER_S);
2799+
case MintOpcode.MINT_BR: {
2800+
const isCallHandler = opcode === MintOpcode.MINT_CALL_HANDLER;
28162801

28172802
const destination = <any>ip + (displacement * 2);
28182803

@@ -2824,7 +2809,7 @@ function emit_branch (
28242809
if (builder.backBranchTraceLevel > 1)
28252810
mono_log_info(`0x${(<any>ip).toString(16)} performing backward branch to 0x${destination.toString(16)}`);
28262811
if (isCallHandler)
2827-
append_call_handler_store_ret_ip(builder, ip, frame, opcode);
2812+
append_call_handler_store_ret_ip(builder, ip, frame);
28282813
builder.cfg.branch(destination, true, CfgBranchType.Unconditional);
28292814
modifyCounter(JiterpCounter.BackBranchesEmitted, 1);
28302815
return true;
@@ -2849,32 +2834,32 @@ function emit_branch (
28492834
// the current branch block after updating eip
28502835
builder.branchTargets.add(destination);
28512836
if (isCallHandler)
2852-
append_call_handler_store_ret_ip(builder, ip, frame, opcode);
2837+
append_call_handler_store_ret_ip(builder, ip, frame);
28532838
builder.cfg.branch(destination, false, CfgBranchType.Unconditional);
28542839
return true;
28552840
}
28562841
}
28572842

2858-
case MintOpcode.MINT_BRTRUE_I4_S:
2859-
case MintOpcode.MINT_BRFALSE_I4_S:
2843+
case MintOpcode.MINT_BRTRUE_I4:
2844+
case MintOpcode.MINT_BRFALSE_I4:
28602845
case MintOpcode.MINT_BRTRUE_I4_SP:
28612846
case MintOpcode.MINT_BRFALSE_I4_SP:
2862-
case MintOpcode.MINT_BRTRUE_I8_S:
2863-
case MintOpcode.MINT_BRFALSE_I8_S: {
2864-
const is64 = (opcode === MintOpcode.MINT_BRTRUE_I8_S) ||
2865-
(opcode === MintOpcode.MINT_BRFALSE_I8_S);
2847+
case MintOpcode.MINT_BRTRUE_I8:
2848+
case MintOpcode.MINT_BRFALSE_I8: {
2849+
const is64 = (opcode === MintOpcode.MINT_BRTRUE_I8) ||
2850+
(opcode === MintOpcode.MINT_BRFALSE_I8);
28662851

28672852
// Load the condition
28682853

28692854
append_ldloc(builder, getArgU16(ip, 1), is64 ? WasmOpcode.i64_load : WasmOpcode.i32_load);
28702855
if (
2871-
(opcode === MintOpcode.MINT_BRFALSE_I4_S) ||
2856+
(opcode === MintOpcode.MINT_BRFALSE_I4) ||
28722857
(opcode === MintOpcode.MINT_BRFALSE_I4_SP)
28732858
)
28742859
builder.appendU8(WasmOpcode.i32_eqz);
2875-
else if (opcode === MintOpcode.MINT_BRFALSE_I8_S) {
2860+
else if (opcode === MintOpcode.MINT_BRFALSE_I8) {
28762861
builder.appendU8(WasmOpcode.i64_eqz);
2877-
} else if (opcode === MintOpcode.MINT_BRTRUE_I8_S) {
2862+
} else if (opcode === MintOpcode.MINT_BRTRUE_I8) {
28782863
// do (i64 == 0) == 0 because br_if can only branch on an i32 operand
28792864
builder.appendU8(WasmOpcode.i64_eqz);
28802865
builder.appendU8(WasmOpcode.i32_eqz);

0 commit comments

Comments
 (0)