Skip to content

Commit

Permalink
Merge pull request #975 from ptersilie/ptradd2
Browse files Browse the repository at this point in the history
Process ptradd instructions and global operands.
  • Loading branch information
ltratt authored Feb 20, 2024
2 parents 1201276 + 9b58be8 commit a2d37c3
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
18 changes: 18 additions & 0 deletions ykrt/src/compile/jitc_yk/aot_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,10 @@ pub(crate) struct IntegerType {
}

impl IntegerType {
pub(crate) fn num_bits(&self) -> u32 {
self.num_bits
}

fn const_to_str(&self, c: &Constant) -> String {
// FIXME: For now we just handle common integer types, but eventually we will need to
// implement printing of aribitrarily-sized (in bits) integers. Consider using a bigint
Expand Down Expand Up @@ -768,6 +772,12 @@ pub(crate) struct Constant {
bytes: Vec<u8>,
}

impl Constant {
pub(crate) fn bytes(&self) -> &[u8] {
&self.bytes
}
}

impl IRDisplay for Constant {
fn to_str(&self, m: &Module) -> String {
m.types[self.type_idx].const_to_str(self)
Expand Down Expand Up @@ -899,6 +909,14 @@ impl Module {
&self.types[instr.type_idx]
}

pub(crate) fn constant(&self, co: &ConstantOperand) -> &Constant {
&self.consts[co.const_idx]
}

pub(crate) fn const_type(&self, c: &Constant) -> &Type {
&self.types[c.type_idx]
}

// FIXME: rename this to `is_def()`, which we've decided is a beter name.
// FIXME: also move this to the `Instruction` type.
fn instr_generates_value(&self, i: &Instruction) -> bool {
Expand Down
20 changes: 11 additions & 9 deletions ykrt/src/compile/jitc_yk/jit_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,18 +340,12 @@ impl LoadArgInstruction {
pub struct LoadGlobalInstruction {
/// The pointer to load from.
global_idx: GlobalIdx,
/// The type of the pointee.
ty_idx: TypeIdx,
}

impl LoadGlobalInstruction {
pub(crate) fn new(
global_idx: aot_ir::GlobalIdx,
ty_idx: TypeIdx,
) -> Result<Self, CompilationError> {
pub(crate) fn new(global_idx: aot_ir::GlobalIdx) -> Result<Self, CompilationError> {
Ok(Self {
global_idx: GlobalIdx::from_aot(global_idx)?,
ty_idx,
})
}
}
Expand Down Expand Up @@ -380,7 +374,7 @@ pub struct CallInstruction {

impl fmt::Display for CallInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "LoadArg")
write!(f, "Call")
}
}

Expand Down Expand Up @@ -520,9 +514,17 @@ impl PtrAddInstruction {
let ptr = self.ptr;
ptr.get()
}

fn offset(&self) -> u32 {
self.off
}

pub(crate) fn new(ptr: Operand, off: u32) -> Self {
Self {
ptr: PackedOperand::new(&ptr),
off,
}
}
}

impl fmt::Display for PtrAddInstruction {
Expand Down Expand Up @@ -674,7 +676,7 @@ mod tests {
assert_eq!(mem::size_of::<CallInstruction>(), 7);
assert_eq!(mem::size_of::<StoreInstruction>(), 4);
assert_eq!(mem::size_of::<LoadInstruction>(), 6);
assert_eq!(mem::size_of::<LoadGlobalInstruction>(), 6);
assert_eq!(mem::size_of::<LoadGlobalInstruction>(), 3);
assert_eq!(mem::size_of::<StoreGlobalInstruction>(), 6);
assert_eq!(mem::size_of::<PtrAddInstruction>(), 6);
assert!(mem::size_of::<Instruction>() <= mem::size_of::<u64>());
Expand Down
36 changes: 35 additions & 1 deletion ykrt/src/compile/jitc_yk/trace_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl<'a> TraceBuilder<'a> {
aot_ir::Opcode::Load => self.handle_load(inst),
aot_ir::Opcode::Call => self.handle_call(inst),
aot_ir::Opcode::Store => self.handle_store(inst),
aot_ir::Opcode::PtrAdd => self.handle_ptradd(inst),
_ => todo!("{:?}", inst),
}?;

Expand Down Expand Up @@ -129,6 +130,15 @@ impl<'a> TraceBuilder<'a> {
let instridx = self.local_map[lvo.instr_id()];
jit_ir::Operand::Local(instridx)
}
aot_ir::Operand::Constant(_co) => {
todo!()
}
aot_ir::Operand::Global(go) => {
let load = jit_ir::LoadGlobalInstruction::new(go.index())?;
let idx = self.next_instr_id()?;
self.jit_mod.push(load.into());
jit_ir::Operand::Local(idx)
}
aot_ir::Operand::Unimplemented(_) => {
// FIXME: for now we push an arbitrary constant.
let constidx = self
Expand All @@ -149,7 +159,7 @@ impl<'a> TraceBuilder<'a> {
let ty_idx = jit_ir::TypeIdx::from_aot(inst.type_idx())?;
if let aot_ir::Operand::Global(go) = inst.operand(0) {
// Generate a special load instruction for globals.
Ok(jit_ir::LoadGlobalInstruction::new(go.index(), ty_idx)?.into())
Ok(jit_ir::LoadGlobalInstruction::new(go.index())?.into())
} else {
let jit_op = self.handle_operand(inst.operand(0))?;
Ok(jit_ir::LoadInstruction::new(jit_op, ty_idx).into())
Expand Down Expand Up @@ -181,6 +191,30 @@ impl<'a> TraceBuilder<'a> {
}
}

fn handle_ptradd(
&mut self,
inst: &aot_ir::Instruction,
) -> Result<jit_ir::Instruction, CompilationError> {
let target = self.handle_operand(inst.operand(0))?;
if let aot_ir::Operand::Constant(co) = inst.operand(1) {
let c = self.aot_mod.constant(co);
if let aot_ir::Type::Integer(it) = self.aot_mod.const_type(c) {
// Convert the offset into a 32 bit value, as that is the maximum we can fit into
// the jit_ir::PtrAddInstruction.
let offset: u32 = match it.num_bits() {
64 => u64::from_ne_bytes(c.bytes()[0..8].try_into().unwrap())
.try_into()
.map_err(|_| {
CompilationError::Unrecoverable("ptradd offset too big".into())
}),
_ => panic!(),
}?;
return Ok(jit_ir::PtrAddInstruction::new(target, offset).into());
};
}
panic!()
}

/// Entry point for building an IR trace.
///
/// Consumes the trace builder, returning a JIT module.
Expand Down

0 comments on commit a2d37c3

Please sign in to comment.