Skip to content

Commit

Permalink
Refactor.
Browse files Browse the repository at this point in the history
  • Loading branch information
sisshiki1969 committed Dec 10, 2024
1 parent ed9807a commit e5d8882
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 124 deletions.
10 changes: 3 additions & 7 deletions monoruby/src/compiler/jitgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ enum CompileResult {
Branch,
/// leave the current method/block.
Leave,
/// deoptimize and fallback to the interpreter.
Deopt,
/// deoptimize and recompile.
Recompile,
}

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -790,11 +790,7 @@ impl Codegen {
Ok(true) => {}
_ => std::fs::create_dir(&path).unwrap(),
}
std::fs::write(
path.join(format!("fid-{}.dot", func.func_id().get())),
s,
)
.unwrap();
std::fs::write(path.join(format!("fid-{}.dot", func.func_id().get())), s).unwrap();
}
}

Expand Down
10 changes: 5 additions & 5 deletions monoruby/src/compiler/jitgen/asmir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,15 +424,15 @@ impl AsmIr {
&mut self,
bbctx: &mut BBContext,
dst: SlotId,
cached_version: usize,
cached_val: Value,
cache: &ConstCache,
pc: BytecodePtr,
) {
let ConstCache { version, value, .. } = cache;
let deopt = self.new_deopt(bbctx, pc);
if let Some(f) = cached_val.try_float() {
self.load_float_constant(bbctx, f, dst, cached_version, deopt);
if let Some(f) = value.try_float() {
self.load_float_constant(bbctx, f, dst, *version, deopt);
} else {
self.load_generic_constant(bbctx, cached_val, dst, cached_version, deopt);
self.load_generic_constant(bbctx, *value, dst, *version, deopt);
}
}

Expand Down
39 changes: 17 additions & 22 deletions monoruby/src/compiler/jitgen/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl JitContext {
match self.compile_instruction(&mut ir, &mut bbctx, store, func, bc_pos) {
CompileResult::Continue => {}
CompileResult::Branch | CompileResult::Leave => return ir,
CompileResult::Deopt => {
CompileResult::Recompile => {
let pc = func.get_pc(bc_pos);
ir.recompile_and_deopt(&mut bbctx, pc, position);
return ir;
Expand Down Expand Up @@ -102,7 +102,7 @@ impl JitContext {
match self.compile_instruction(&mut ir, &mut bbctx, store, func, bc_pos) {
CompileResult::Continue => {}
CompileResult::Branch => return,
CompileResult::Leave | CompileResult::Deopt | CompileResult::ExitLoop => {
CompileResult::Leave | CompileResult::Recompile | CompileResult::ExitLoop => {
liveness.merge(bbctx);
return;
}
Expand Down Expand Up @@ -222,23 +222,18 @@ impl JitContext {
TraceIr::LoadConst(dst, id) => {
bbctx.unlink(ir, dst);

if let ConstCache {
cached_version,
cached_base_class,
cached_value: Some(cached_val),
} = store[id].cache
{
if let Some(cache) = &store[id].cache {
let base_slot = store[id].base;
if let Some(slot) = base_slot {
if let Some(base_class) = cached_base_class {
if let Some(base_class) = cache.base_class {
ir.guard_base_class(bbctx, slot, base_class, pc);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
ir.load_constant(bbctx, dst, cached_version, cached_val, pc);
ir.load_constant(bbctx, dst, cache, pc);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::StoreConst(src, id) => {
Expand All @@ -264,7 +259,7 @@ impl JitContext {
}
bbctx.load_ivar(ir, dst, self_class, ivarid);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::StoreIvar(src, name, cache) => {
Expand All @@ -277,7 +272,7 @@ impl JitContext {
}
bbctx.store_ivar(ir, src, self_class, ivarid);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::LoadCvar { dst, name } => {
Expand Down Expand Up @@ -392,7 +387,7 @@ impl JitContext {
bbctx.rax2acc(ir, info.dst);
}
}
TraceIr::GBinOpNotrace { .. } => return CompileResult::Deopt,
TraceIr::GBinOpNotrace { .. } => return CompileResult::Recompile,
TraceIr::FCmp { kind, info } => {
if kind != CmpKind::Cmp {
let mode = bbctx.fmode(ir, info, pc);
Expand Down Expand Up @@ -425,7 +420,7 @@ impl JitContext {
bbctx.gen_cmp_generic(ir, pc, kind, info);
}
}
TraceIr::GCmpNotrace { .. } => return CompileResult::Deopt,
TraceIr::GCmpNotrace { .. } => return CompileResult::Recompile,
TraceIr::FCmpBr {
kind,
info,
Expand Down Expand Up @@ -467,7 +462,7 @@ impl JitContext {
bbctx.gen_cmpbr_generic(ir, pc, kind, info.mode, info.dst, brkind, branch_dest);
self.new_branch(func, index, dest, bbctx.clone(), branch_dest);
}
TraceIr::GCmpBrNotrace { .. } => return CompileResult::Deopt,
TraceIr::GCmpBrNotrace { .. } => return CompileResult::Recompile,
TraceIr::Index {
dst,
base,
Expand All @@ -477,7 +472,7 @@ impl JitContext {
if let Some((base_class, idx_class)) = class {
bbctx.index(ir, dst, base, idx, base_class, idx_class, pc);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::IndexAssign {
Expand All @@ -489,7 +484,7 @@ impl JitContext {
if let Some((base_class, idx_class)) = class {
bbctx.index_assign(ir, src, base, idx, base_class, idx_class, pc);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::Mov(dst, src) => {
Expand Down Expand Up @@ -525,10 +520,10 @@ impl JitContext {
ir.alias_method(bbctx, pc, new, old);
}
TraceIr::MethodCall { callid, cache } => {
if let Some((recv_class, fid, version)) = cache {
return bbctx.compile_call(ir, store, pc, callid, recv_class, fid, version);
if let Some(cache) = cache {
return bbctx.compile_call(ir, store, pc, callid, cache);
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}
TraceIr::Yield { callid } => {
Expand Down
44 changes: 24 additions & 20 deletions monoruby/src/compiler/jitgen/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ impl BBContext {
store: &Store,
pc: BytecodePtr,
callid: CallSiteId,
recv_class: ClassId,
fid: FuncId,
version: u32,
cache: MethodCacheEntry,
) -> CompileResult {
if store[callid].block_fid.is_none()
&& let Some(info) = store.inline_info.get_inline(fid)
&& let Some(info) = store.inline_info.get_inline(cache.func_id)
{
let f = &info.inline_gen;
if self.inline_call(ir, store, f, fid, callid, recv_class, version, pc) {
if self.inline_call(ir, store, f, callid, &cache, pc) {
return CompileResult::Continue;
}
}
self.call(ir, store, fid, recv_class, version, callid, pc)
self.call(ir, store, cache, callid, pc)
}

pub(super) fn compile_binop_call(
Expand All @@ -37,7 +35,7 @@ impl BBContext {
));
let callee = &store[fid];
if (!callee.is_rest() && callee.max_positional_args() < 1) || callee.req_num() > 1 {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
let BinOpInfo {
dst,
Expand Down Expand Up @@ -101,13 +99,16 @@ impl BBContext {
&mut self,
ir: &mut AsmIr,
store: &Store,
fid: FuncId,
recv_class: ClassId,
version: u32,
cache: MethodCacheEntry,
callid: CallSiteId,
pc: BytecodePtr,
) -> CompileResult {
let CallSiteInfo { dst, recv, .. } = store[callid];
let MethodCacheEntry {
recv_class,
func_id,
version,
} = cache;
if recv.is_self() && self.self_value.class() != recv_class {
// the inline method cache is invalid because the receiver class is not matched.
self.write_back_locals(ir);
Expand All @@ -117,26 +118,26 @@ impl BBContext {
self.rax2acc(ir, dst);
} else {
// We must write back and unlink all local vars when they are possibly accessed from inner blocks.
if store[callid].block_fid.is_some() || store[fid].meta().is_eval() {
if store[callid].block_fid.is_some() || store[func_id].meta().is_eval() {
self.write_back_locals(ir);
}
self.fetch_for_gpr(ir, recv, GP::Rdi);
let (deopt, error) = ir.new_deopt_error(self, pc);
let using_xmm = self.get_using_xmm();
ir.guard_version(fid, version, callid, using_xmm, deopt, error);
ir.guard_version(func_id, version, callid, using_xmm, deopt, error);
// If recv is *self*, a recv's class is guaranteed to be ctx.self_class.
// Thus, we can omit a class guard.
if !recv.is_self() && !self.is_class(recv, recv_class) {
ir.guard_class(self, recv, GP::Rdi, recv_class, deopt);
}
if let Some(evict) = self.call_cached(ir, store, callid, fid, recv_class, pc) {
if let Some(evict) = self.call_cached(ir, store, callid, func_id, recv_class, pc) {
self.rax2acc(ir, dst);
if let Some(evict) = evict {
ir.push(AsmInst::ImmediateEvict { evict });
ir[evict] = SideExit::Evict(Some((pc + 2, self.get_write_back())));
}
} else {
return CompileResult::Deopt;
return CompileResult::Recompile;
}
}

Expand All @@ -148,10 +149,8 @@ impl BBContext {
ir: &mut AsmIr,
store: &Store,
f: impl Fn(&mut AsmIr, &Store, &mut BBContext, CallSiteId, BytecodePtr) -> bool,
fid: FuncId,
callid: CallSiteId,
recv_class: ClassId,
version: u32,
cache: &MethodCacheEntry,
pc: BytecodePtr,
) -> bool {
let mut ctx_save = self.clone();
Expand All @@ -160,9 +159,14 @@ impl BBContext {
self.fetch_for_gpr(ir, recv, GP::Rdi);
let (deopt, error) = ir.new_deopt_error(self, pc);
let using_xmm = self.get_using_xmm();
ir.guard_version(fid, version, callid, using_xmm, deopt, error);
if !recv.is_self() && !self.is_class(recv, recv_class) {
ir.guard_class(self, recv, GP::Rdi, recv_class, deopt);
let MethodCacheEntry {
recv_class,
func_id,
version,
} = cache;
ir.guard_version(*func_id, *version, callid, using_xmm, deopt, error);
if !recv.is_self() && !self.is_class(recv, *recv_class) {
ir.guard_class(self, recv, GP::Rdi, *recv_class, deopt);
}
if f(ir, store, self, callid, pc) {
true
Expand Down
21 changes: 14 additions & 7 deletions monoruby/src/compiler/jitgen/trace_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ pub(crate) struct BinOpInfo {
pub rhs_class: ClassId,
}

#[derive(Debug, Clone)]
pub(crate) struct MethodCacheEntry {
pub recv_class: ClassId,
pub func_id: FuncId,
pub version: u32,
}

///
/// IR for JIT compiler.
///
Expand Down Expand Up @@ -205,7 +212,7 @@ pub(crate) enum TraceIr {
},
MethodCall {
callid: CallSiteId,
cache: Option<(ClassId, FuncId, u32)>, // (recv_class, func_id, version)
cache: Option<MethodCacheEntry>,
},

/// return(%src)
Expand Down Expand Up @@ -520,9 +527,9 @@ impl TraceIr {
format!(
"{:36} [{}]",
op1,
match store[*id].cache.cached_value {
match &store[*id].cache {
None => "<INVALID>".to_string(),
Some(val) => val.debug(store),
Some(cache) => cache.value.debug(store),
}
)
}
Expand Down Expand Up @@ -682,13 +689,13 @@ impl TraceIr {
format!(
"{:36} [{}] {}",
op1,
store.debug_class_name(if let Some((recv_class, ..)) = cache {
Some(*recv_class)
store.debug_class_name(if let Some(entry) = cache {
Some(entry.recv_class)
} else {
None
}),
if let Some((_, fid, _)) = cache {
format!("{:?}", fid)
if let Some(entry) = cache {
format!("{:?}", entry.func_id)
} else {
"-".to_string()
}
Expand Down
Loading

0 comments on commit e5d8882

Please sign in to comment.