Skip to content

Commit 698f1a8

Browse files
committed
Make CallIseq and CallCFunc potentially elidable
1 parent 039b8db commit 698f1a8

File tree

2 files changed

+31
-23
lines changed

2 files changed

+31
-23
lines changed

zjit/src/codegen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::state::ZJITState;
77
use crate::{asm::CodeBlock, cruby::*, options::debug, virtualmem::CodePtr};
88
use crate::invariants::{iseq_escapes_ep, track_no_ep_escape_assumption};
99
use crate::backend::lir::{self, asm_comment, Assembler, Opnd, Target, CFP, C_ARG_OPNDS, C_RET_OPND, EC, SP};
10-
use crate::hir::{iseq_to_hir, Block, BlockId, BranchEdge, CallInfo};
10+
use crate::hir::{iseq_to_hir, Block, BlockId, BranchEdge};
1111
use crate::hir::{Const, FrameState, Function, Insn, InsnId};
1212
use crate::hir_type::{types::Fixnum, Type};
1313
use crate::options::get_option;

zjit/src/hir.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ pub enum Insn {
362362
/// Ignoring keyword arguments etc for now
363363
LookupMethod { self_val: InsnId, method_id: ID, state: InsnId },
364364
CallMethod { callable: InsnId, cd: CallDataPtr, self_val: InsnId, args: Vec<InsnId>, state: InsnId },
365-
CallIseq { iseq: IseqPtr, cd: CallDataPtr, self_val: InsnId, args: Vec<InsnId>, state: InsnId },
366-
CallCFunc { cfunc: CFuncPtr, cd: CallDataPtr, self_val: InsnId, args: Vec<InsnId>, state: InsnId },
365+
CallIseq { iseq: IseqPtr, cd: CallDataPtr, self_val: InsnId, args: Vec<InsnId>, return_type: Type, elidable: bool, state: InsnId },
366+
CallCFunc { cfunc: CFuncPtr, cd: CallDataPtr, self_val: InsnId, args: Vec<InsnId>, return_type: Type, elidable: bool, state: InsnId },
367367

368368
Send { self_val: InsnId, call_info: CallInfo, cd: CallDataPtr, blockiseq: IseqPtr, args: Vec<InsnId>, state: InsnId },
369369

@@ -442,6 +442,8 @@ impl Insn {
442442
Insn::FixnumGe { .. } => false,
443443
Insn::LookupMethod { .. } => false,
444444
Insn::CCall { elidable, .. } => !elidable,
445+
Insn::CallCFunc { elidable, .. } => !elidable,
446+
Insn::CallIseq { elidable, .. } => !elidable,
445447
_ => true,
446448
}
447449
}
@@ -882,19 +884,23 @@ impl Function {
882884
args: args.iter().map(|arg| find!(*arg)).collect(),
883885
state: find!(*state),
884886
},
885-
CallIseq { iseq, self_val, cd, args, state } => CallIseq {
886-
iseq: *iseq,
887-
self_val: find!(*self_val),
888-
cd: *cd,
887+
&CallIseq { iseq, self_val, cd, ref args, return_type, elidable, state } => CallIseq {
888+
iseq,
889+
self_val: find!(self_val),
890+
cd,
889891
args: args.iter().map(|arg| find!(*arg)).collect(),
890-
state: find!(*state),
892+
return_type,
893+
elidable,
894+
state: find!(state),
891895
},
892-
CallCFunc { cfunc, self_val, cd, args, state } => CallCFunc {
893-
cfunc: *cfunc,
894-
self_val: find!(*self_val),
895-
cd: *cd,
896+
&CallCFunc { cfunc, self_val, cd, ref args, return_type, elidable, state } => CallCFunc {
897+
cfunc,
898+
self_val: find!(self_val),
899+
cd,
896900
args: args.iter().map(|arg| find!(*arg)).collect(),
897-
state: find!(*state),
901+
return_type,
902+
elidable,
903+
state: find!(state),
898904
},
899905
ArraySet { array, idx, val } => ArraySet { array: find!(*array), idx: *idx, val: find!(*val) },
900906
ArrayDup { val , state } => ArrayDup { val: find!(*val), state: *state },
@@ -949,6 +955,8 @@ impl Function {
949955
Insn::NewArray { .. } => types::ArrayExact,
950956
Insn::ArrayDup { .. } => types::ArrayExact,
951957
Insn::CCall { return_type, .. } => *return_type,
958+
Insn::CallCFunc { return_type, .. } => *return_type,
959+
Insn::CallIseq { return_type, .. } => *return_type,
952960
Insn::GuardType { val, guard_type, .. } => self.type_of(*val).intersection(*guard_type),
953961
Insn::GuardBitEquals { val, expected, .. } => self.type_of(*val).intersection(Type::from_value(*expected)),
954962
Insn::FixnumAdd { .. } => types::Fixnum,
@@ -969,8 +977,6 @@ impl Function {
969977
Insn::ArrayMax { .. } => types::BasicObject,
970978
Insn::LookupMethod { .. } => types::CallableMethodEntry,
971979
Insn::CallMethod { .. } => types::BasicObject,
972-
Insn::CallIseq { .. } => types::BasicObject,
973-
Insn::CallCFunc { .. } => types::BasicObject,
974980
}
975981
}
976982

@@ -1171,16 +1177,18 @@ impl Function {
11711177
if let Some(value) = self.type_of(callable).ruby_object() {
11721178
assert!(self.type_of(callable).is_subtype(types::CallableMethodEntry), "LookupMethod should return CME");
11731179
let cme: CmePtr = value.as_cme();
1180+
let properties = ZJITState::get_method_annotations().get_cfunc_properties(cme);
1181+
let (return_type, elidable) = properties.map(|p| (p.return_type, p.elidable)).unwrap_or((types::BasicObject, false));
11741182
let def_type = unsafe { get_cme_def_type(cme) };
11751183
if def_type == VM_METHOD_TYPE_ISEQ {
11761184
let iseq = unsafe { get_def_iseq_ptr((*cme).def) };
1177-
let replacement = self.push_insn(block, Insn::CallIseq { iseq, cd, self_val, args, state });
1185+
let replacement = self.push_insn(block, Insn::CallIseq { iseq, cd, self_val, args, return_type, elidable, state });
11781186
self.make_equal_to(insn_id, replacement);
11791187
continue;
11801188
}
11811189
if def_type == VM_METHOD_TYPE_CFUNC {
11821190
let cfunc = unsafe { get_cme_def_body_cfunc(cme) };
1183-
let replacement = self.push_insn(block, Insn::CallCFunc { cfunc, cd, self_val, args, state });
1191+
let replacement = self.push_insn(block, Insn::CallCFunc { cfunc, cd, self_val, args, return_type, elidable, state });
11841192
self.make_equal_to(insn_id, replacement);
11851193
continue;
11861194
}
@@ -2690,7 +2698,7 @@ mod tests {
26902698
assert_method_hir("test", expect![[r#"
26912699
fn test:
26922700
bb0(v0:BasicObject, v1:BasicObject):
2693-
v4:BasicObject = LookupMethod v0, :<=
2701+
v4:CallableMethodEntry = LookupMethod v0, :<=
26942702
v5:BasicObject = CallMethod v4 (:<=), v0, v1
26952703
Return v5
26962704
"#]]);
@@ -3890,8 +3898,8 @@ mod opt_tests {
38903898
fn test:
38913899
bb0():
38923900
PatchPoint MethodRedefined(Array@0x1000, itself@0x1008)
3893-
v6:Fixnum[1] = Const Value(1)
3894-
Return v6
3901+
v7:Fixnum[1] = Const Value(1)
3902+
Return v7
38953903
"#]]);
38963904
}
38973905

@@ -3911,8 +3919,8 @@ mod opt_tests {
39113919
PatchPoint SingleRactorMode
39123920
PatchPoint StableConstantNames(0x1000, M)
39133921
PatchPoint MethodRedefined(Module@0x1008, name@0x1010)
3914-
v5:Fixnum[1] = Const Value(1)
3915-
Return v5
3922+
v6:Fixnum[1] = Const Value(1)
3923+
Return v6
39163924
"#]]);
39173925
}
39183926

@@ -3983,7 +3991,7 @@ mod opt_tests {
39833991
v1:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
39843992
v2:StringExact = StringCopy v1
39853993
PatchPoint MethodRedefined(String@0x1008, bytesize@0x1010)
3986-
v9:BasicObject = CallCFunc 0x1018 (:bytesize), v2
3994+
v9:Fixnum = CallCFunc 0x1018 (:bytesize), v2
39873995
Return v9
39883996
"#]]);
39893997
}

0 commit comments

Comments
 (0)