Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interpreter specialization for whamm probe (whamm trampoline) #233

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
674fd78
inline tier
thelongmarch-azx Nov 25, 2024
44c4281
fix get operand bug
thelongmarch-azx Nov 25, 2024
bf3d6b8
Merge branch 'whamm-intrinsification' into whamm-inline
thelongmarch-azx Nov 25, 2024
d0a0b94
Merge branch 'whamm-intrinsification' into whamm-inline
thelongmarch-azx Nov 25, 2024
8cce635
fix inline code iterator bug
thelongmarch-azx Nov 25, 2024
075bf01
update inlining check for visit_END
thelongmarch-azx Nov 25, 2024
5db8b96
fix test failure in dyn mode
thelongmarch-azx Nov 25, 2024
c21bf82
whamm probe interpreter trampoline code complete
thelongmarch-azx Nov 27, 2024
079d595
swapped tag/val location to fix test failures
thelongmarch-azx Nov 27, 2024
3346807
add flag to toggle feature
thelongmarch-azx Nov 27, 2024
de98012
Merge branch 'titzer:master' into whamm-inline
thelongmarch-azx Nov 27, 2024
c4e94e5
Merge branch 'titzer:master' into whamm-trampoline
thelongmarch-azx Nov 27, 2024
6a7f564
associate trampoline with probe signature
thelongmarch-azx Nov 27, 2024
2de51b8
Merge branch 'titzer:master' into whamm-inline
thelongmarch-azx Nov 27, 2024
fb381dc
Merge branch 'whamm-intrinsification' into whamm-inline
thelongmarch-azx Nov 27, 2024
1fee70e
Merge branch 'titzer:master' into whamm-trampoline
thelongmarch-azx Nov 27, 2024
0280450
Merge branch 'whamm-inline' into whamm-trampoline
thelongmarch-azx Nov 27, 2024
79604df
resolve merge conflict
thelongmarch-azx Nov 27, 2024
1c25027
inline tier
thelongmarch-azx Nov 27, 2024
1a3fe30
Merge remote-tracking branch 'refs/remotes/origin/whamm-trampoline' i…
thelongmarch-azx Nov 27, 2024
f0f2f60
Merge branch 'titzer:master' into whamm-inline
thelongmarch-azx Nov 27, 2024
f5e2e0a
Merge branch 'titzer:master' into whamm-trampoline
thelongmarch-azx Nov 27, 2024
eb99fe0
clean up dead comments
thelongmarch-azx Nov 27, 2024
77fec0e
Merge remote-tracking branch 'refs/remotes/origin/whamm-inline' into …
thelongmarch-azx Nov 27, 2024
0c8cdb6
Merge branch 'titzer:master' into whamm-inline
thelongmarch-azx Dec 10, 2024
eca41f1
Merge branch 'titzer:master' into whamm-trampoline
thelongmarch-azx Dec 10, 2024
9488385
Merge branch 'whamm-inline' into whamm-trampoline
thelongmarch-azx Dec 10, 2024
8cb5fb8
implement read/write probe intrinsification
thelongmarch-azx Dec 10, 2024
f1bda15
refactored cache-sim monitor for benchmark measurement
thelongmarch-azx Dec 11, 2024
5bbeafd
update example monitor for evaluation
thelongmarch-azx Dec 11, 2024
2a9999e
major bugfix
thelongmarch-azx Dec 12, 2024
5974a34
add temp inline count
thelongmarch-azx Dec 12, 2024
6c09c42
add temp inline count
thelongmarch-azx Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/engine/BytecodeIterator.v3
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class BytecodeIterator {

// Read the first byte of the code
var b = codeptr.read1();
if (b == InternalOpcode.PROBE.code) { // probe is inserted here
if (b == InternalOpcode.PROBE.code || b == InternalOpcode.WHAMM_PROBE.code) { // probe is inserted here
b = origptr.reset(func.orig_bytecode, pc, func.orig_bytecode.length).read1();
}
// Query opcode attributes array
Expand Down Expand Up @@ -101,9 +101,10 @@ class BytecodeIterator {

// Read the first byte of the code
var b = codeptr.read1();
if (b == InternalOpcode.PROBE.code) { // probe is inserted here
if (b == InternalOpcode.PROBE.code || b == InternalOpcode.WHAMM_PROBE.code) { // probe is inserted here
v.visitProbe();
b = origptr.reset(func.orig_bytecode, pc, func.orig_bytecode.length).read1();
codeptr.reset(func.cur_bytecode, pc + 1, func.cur_bytecode.length);
}
// Query opcode attributes array
var opcode: Opcode;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/CodePtr.v3
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class CodePtr extends DataReader {
}
def read_opcode_but_skip_probe(func: FuncDecl) -> Opcode {
var pc = pos, b = read1();
if (b == InternalOpcode.PROBE.code) b = func.orig_bytecode[pc];
if (b == InternalOpcode.PROBE.code || b == InternalOpcode.WHAMM_PROBE.code) b = func.orig_bytecode[pc];
var op = Opcodes.opcode_by_prefix[b];
if (op != Opcode.INVALID) return op;
return if(Opcodes.isPrefix(b), Opcodes.find(b, read_uleb32()));
Expand Down
2 changes: 1 addition & 1 deletion src/engine/Engine.v3
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Engine {
if (data == null) return FileLoadResult.FileNotFound(path);
var limits = Limits.new().set(extensions);
var bp = BinParser.new(extensions, limits, path);
bp.tiering = tiering_override;
bp.tiering = if(tiering_override != null, tiering_override, Execute.tiering);
var r = bp.push(data, 0, data.length).finish();
match (r) {
Ok(module) =>
Expand Down
7 changes: 6 additions & 1 deletion src/engine/Instrumentation.v3
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,23 @@ component Instrumentation {
match (probe) {
l: ProbeList => {
l.add(p);
func.activateProbingAt(offset, InternalOpcode.PROBE.code);
Execute.tiering.onFuncProbeInsertN(module, func, offset, p);
}
null => {
map[offset] = p;
func.activateProbingAt(offset);
func.activateProbingAt(offset,
if (WhammProbe.?(p) && FastIntTuning.enableWhammProbeTrampoline,
InternalOpcode.WHAMM_PROBE.code,
InternalOpcode.PROBE.code));
Execute.tiering.onFuncProbeInsert1(module, func, offset, p);
}
_ => {
var list = ProbeList.new();
list.add(probe);
list.add(p);
map[offset] = list;
func.activateProbingAt(offset, InternalOpcode.PROBE.code);
Execute.tiering.onFuncProbeInsert1(module, func, offset, p);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/engine/Module.v3
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,15 @@ class FuncDecl(sig_index: int) extends Decl {
def setOrigCode(code: Array<byte>) -> this {
cur_bytecode = orig_bytecode = code;
var tc: TargetCode;
var tr: TargetCode;
target_code = tc; // reset target code as well
sidetable = Sidetables.NO_SIDETABLE;
}
def activateProbingAt(pc: int) {
def activateProbingAt(pc: int, probe_byte: byte) {
if (pc == 0) return void(entry_probed = true); // special case for function entry
// "orig" will become a copy of the original code, to allow in-place modification of old code
if (cur_bytecode == orig_bytecode) orig_bytecode = Arrays.dup(orig_bytecode);
cur_bytecode[pc] = InternalOpcode.PROBE.code;
cur_bytecode[pc] = probe_byte;
}
def deactiveProbingAt(pc: int) {
if (pc == 0) return;
Expand Down
3 changes: 2 additions & 1 deletion src/engine/Opcodes.v3
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ component ImmSigs {
// Internal opcodes used by the interpreter.
enum InternalOpcode(code: u8, mnemonic: string) {
PROBE(0x1E, "<probe>"), // Used to overwrite a bytecode where a probe has been inserted
WHAMM_PROBE(0x1D, "<whamm-probe>"),
//PROBE_COUNTER
//PROBE_COUNTER_n
//PROBE_TOS_i
Expand Down Expand Up @@ -1031,7 +1032,7 @@ class InstrTracer {
op = Opcodes.find(b, b2);
if (op == Opcode.INVALID) out.put2("%x %x <invalid>", b, b2);
else out.puts(op.mnemonic);
} else if (b == InternalOpcode.PROBE.code) {
} else if (b == InternalOpcode.PROBE.code || b == InternalOpcode.WHAMM_PROBE.code) {
out.put1("<probe>", b);
return;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/engine/Tuning.v3
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ component FastIntTuning {
def fourByteSidetable = true; // sidetable entries are 4-bytes
def entryTierUpDecrement = 1; // "cost" of entering a function in the interpreter
def loopTierUpDecrement = 1; // "cost" of looping in the interpreter
def enableWhammProbeTrampoline = true;
}

// Tuning settings for the single-pass compiler that have no effect on correctness.
Expand All @@ -53,4 +54,5 @@ component SpcTuning {
var inlineSmallFunc = true; // inline small functions, currently only applicable for whamm probes
def probeCallFreesRegs = true; // probe calls frees registers in abstract state
def runtimeCallFreesRegs = true; // runtime calls frees registers in abstract state
def intrinsifyMemoryProbes = true;
}
28 changes: 28 additions & 0 deletions src/engine/Value.v3
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,34 @@ type Value {
case F32(bits: u32);
case F64(bits: u64);
case V128(low: u64, high: u64);

def equal(that: Value) -> bool {
if (this == that) return true;
if (Value.Ref.?(this) == Value.Ref.?(that)) {
return Value.Ref.!(this).val == Value.Ref.!(that).val;
}
if (Value.I31.?(this) == Value.I31.?(that)) {
return Value.I31.!(this).val == Value.I31.!(that).val;
}
if (Value.I32.?(this) == Value.I32.?(that)) {
return Value.I32.!(this).val == Value.I32.!(that).val;
}
if (Value.I64.?(this) == Value.I64.?(that)) {
return Value.I64.!(this).val == Value.I64.!(that).val;
}
if (Value.F32.?(this) == Value.F32.?(that)) {
return Value.F32.!(this).bits == Value.F32.!(that).bits;
}
if (Value.F64.?(this) == Value.F64.?(that)) {
return Value.F64.!(this).bits == Value.F64.!(that).bits;
}
if (Value.V128.?(this) == Value.V128.?(that)) {
var a = Value.V128.!(this);
var b = Value.V128.!(that);
return a.low == b.low && a.high == b.high;
}
return false;
}
}

// Categorization of values into storage kinds.
Expand Down
9 changes: 6 additions & 3 deletions src/engine/compiler/MacroAssembler.v3
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class MacroAssembler(valuerep: Tagging, regConfig: RegConfig) {
}

// Architecture-specific load and store routines for Wasm load/store.
// if `intrinsify_probe` is true, writes the effective address to scratch register.
def emit_loadbsx_r_r_r_i(kind: ValueKind, dst: Reg, base: Reg, index: Reg, offset: u32);
def emit_loadbzx_r_r_r_i(kind: ValueKind, dst: Reg, base: Reg, index: Reg, offset: u32);
def emit_loadwsx_r_r_r_i(kind: ValueKind, dst: Reg, base: Reg, index: Reg, offset: u32);
Expand All @@ -173,9 +174,9 @@ class MacroAssembler(valuerep: Tagging, regConfig: RegConfig) {
def emit_loaddzx_r_r_r_i(kind: ValueKind, dst: Reg, base: Reg, index: Reg, offset: u32);
def emit_load_r_r_r_i(kind: ValueKind, dst: Reg, base: Reg, index: Reg, offset: u32);

def emit_storeb_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, index: Reg, offset: u32);
def emit_storew_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, index: Reg, offset: u32);
def emit_store_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, index: Reg, offset: u32);
def emit_storeb_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, mirror_base: Reg, index: Reg, offset: u32);
def emit_storew_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, mirror_base: Reg, index: Reg, offset: u32);
def emit_store_r_r_r_i(kind: ValueKind, val: Reg, base: Reg, mirror_base: Reg, index: Reg, offset: u32);

def emit_mov_r_r(kind: ValueKind, reg: Reg, reg2: Reg);
def emit_mov_r_m(kind: ValueKind, reg: Reg, addr: MasmAddr);
Expand Down Expand Up @@ -246,6 +247,8 @@ class MacroAssembler(valuerep: Tagging, regConfig: RegConfig) {
def emit_call_runtime_getFrameAccessorMetaRef();
def emit_increment_CountProbe(tmp: Reg, probe: CountProbe, increment: u64);
def emit_call_OperandProbe_i_v_fire(probe: OperandProbe_i_v, value_reg: Reg);
def emit_call_MemoryReadProbe_fire(probe: MemoryReadProbe);
def emit_call_MemoryWriteProbe_fire(probe: MemoryWriteProbe);

def emit_debugger_breakpoint();

Expand Down
Loading