Skip to content

Commit 9b8c84b

Browse files
committed
refactor: change LowerCtx::get_immediate to return a DataValue
This change abstracts away (from the perspective of the new backend) how immediate values are stored in InstructionData. It gathers large immediates from necessary places (e.g. constant pool) and delegates to `InstructionData::imm_value` for the rest. This refactor only touches original users of `LowerCtx::get_immediate` but a future change could do the same for any place the new backend is accessing InstructionData directly to retrieve immediates.
1 parent 91f6019 commit 9b8c84b

File tree

4 files changed

+38
-28
lines changed

4 files changed

+38
-28
lines changed

cranelift/codegen/src/ir/constant.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ impl ConstantData {
6363
self.0.is_empty()
6464
}
6565

66+
/// Return the data as a slice.
67+
pub fn as_slice(&self) -> &[u8] {
68+
self.0.as_slice()
69+
}
70+
6671
/// Convert the data to a vector.
6772
pub fn into_vec(self) -> Vec<u8> {
6873
self.0

cranelift/codegen/src/isa/aarch64/lower.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use crate::ir::condcodes::{FloatCC, IntCC};
1111
use crate::ir::types::*;
1212
use crate::ir::Inst as IRInst;
13-
use crate::ir::{InstructionData, Opcode, Type};
13+
use crate::ir::{Opcode, Type};
1414
use crate::machinst::lower::*;
1515
use crate::machinst::*;
1616
use crate::CodegenResult;
@@ -20,6 +20,7 @@ use crate::isa::aarch64::AArch64Backend;
2020

2121
use super::lower_inst;
2222

23+
use crate::data_value::DataValue;
2324
use log::{debug, trace};
2425
use regalloc::{Reg, RegClass, Writable};
2526
use smallvec::SmallVec;
@@ -126,22 +127,9 @@ pub(crate) fn const_param_to_u128<C: LowerCtx<I = Inst>>(
126127
ctx: &mut C,
127128
inst: IRInst,
128129
) -> Option<u128> {
129-
let data = match ctx.data(inst) {
130-
&InstructionData::Shuffle { mask, .. } => ctx.get_immediate(mask),
131-
&InstructionData::UnaryConst {
132-
constant_handle, ..
133-
} => ctx.get_constant_data(constant_handle),
134-
_ => return None,
135-
};
136-
let data = data.clone().into_vec();
137-
138-
if data.len() == 16 {
139-
let mut bytes = [0u8; 16];
140-
141-
bytes.copy_from_slice(&data);
142-
Some(u128::from_le_bytes(bytes))
143-
} else {
144-
None
130+
match ctx.get_immediate(inst) {
131+
Some(DataValue::V128(bytes)) => Some(u128::from_le_bytes(bytes)),
132+
_ => None,
145133
}
146134
}
147135

cranelift/codegen/src/isa/x64/lower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![allow(non_snake_case)]
44

5+
use crate::data_value::DataValue;
56
use crate::ir::{
67
condcodes::FloatCC, types, AbiParam, ArgumentPurpose, ExternalName, Inst as IRInst,
78
InstructionData, LibCall, Opcode, Signature, Type,
@@ -2642,10 +2643,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
26422643
let lhs_ty = ctx.input_ty(insn, 0);
26432644
let lhs = put_input_in_reg(ctx, inputs[0]);
26442645
let rhs = put_input_in_reg(ctx, inputs[1]);
2645-
let mask = if let &InstructionData::Shuffle { mask, .. } = ctx.data(insn) {
2646-
ctx.get_immediate(mask).clone()
2647-
} else {
2648-
unreachable!("shuffle should always have the shuffle format")
2646+
let mask = match ctx.get_immediate(insn) {
2647+
Some(DataValue::V128(bytes)) => bytes.to_vec(),
2648+
_ => unreachable!("shuffle should always have a 16-byte immediate"),
26492649
};
26502650

26512651
// A mask-building helper: in 128-bit SIMD, 0-15 indicate which lane to read from and a

cranelift/codegen/src/machinst/lower.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ use crate::inst_predicates::{has_lowering_side_effect, is_constant_64bit};
88
use crate::ir::instructions::BranchInfo;
99
use crate::ir::types::I64;
1010
use crate::ir::{
11-
ArgumentPurpose, Block, Constant, ConstantData, ExternalName, Function, GlobalValueData,
12-
Immediate, Inst, InstructionData, MemFlags, Opcode, Signature, SourceLoc, Type, Value,
13-
ValueDef,
11+
ArgumentPurpose, Block, Constant, ConstantData, ExternalName, Function, GlobalValueData, Inst,
12+
InstructionData, MemFlags, Opcode, Signature, SourceLoc, Type, Value, ValueDef,
1413
};
1514
use crate::machinst::{
1615
ABICallee, BlockIndex, BlockLoweringOrder, LoweredBlock, MachLabel, VCode, VCodeBuilder,
@@ -20,8 +19,10 @@ use crate::CodegenResult;
2019

2120
use regalloc::{Reg, RegClass, StackmapRequestInfo, VirtualReg, Writable};
2221

22+
use crate::data_value::DataValue;
2323
use alloc::boxed::Box;
2424
use alloc::vec::Vec;
25+
use core::convert::TryInto;
2526
use log::debug;
2627
use smallvec::SmallVec;
2728

@@ -161,8 +162,9 @@ pub trait LowerCtx {
161162
fn is_reg_needed(&self, ir_inst: Inst, reg: Reg) -> bool;
162163
/// Retrieve constant data given a handle.
163164
fn get_constant_data(&self, constant_handle: Constant) -> &ConstantData;
164-
/// Retrieve an immediate given a reference.
165-
fn get_immediate(&self, imm: Immediate) -> &ConstantData;
165+
/// Retrieve the value immediate from an instruction. This will perform necessary lookups on the
166+
/// `DataFlowGraph` to retrieve even large immediates.
167+
fn get_immediate(&self, ir_inst: Inst) -> Option<DataValue>;
166168
/// Cause the value in `reg` to be in a virtual reg, by copying it into a new virtual reg
167169
/// if `reg` is a real reg. `ty` describes the type of the value in `reg`.
168170
fn ensure_in_vreg(&mut self, reg: Reg, ty: Type) -> Reg;
@@ -1007,8 +1009,23 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
10071009
self.f.dfg.constants.get(constant_handle)
10081010
}
10091011

1010-
fn get_immediate(&self, imm: Immediate) -> &ConstantData {
1011-
self.f.dfg.immediates.get(imm).unwrap()
1012+
fn get_immediate(&self, ir_inst: Inst) -> Option<DataValue> {
1013+
let inst_data = self.data(ir_inst);
1014+
match inst_data {
1015+
InstructionData::Shuffle { mask, .. } => {
1016+
let buffer = self.f.dfg.immediates.get(mask.clone()).unwrap().as_slice();
1017+
let value = DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"));
1018+
Some(value)
1019+
}
1020+
InstructionData::UnaryConst {
1021+
constant_handle, ..
1022+
} => {
1023+
let buffer = self.f.dfg.constants.get(constant_handle.clone()).as_slice();
1024+
let value = DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"));
1025+
Some(value)
1026+
}
1027+
_ => inst_data.imm_value(),
1028+
}
10121029
}
10131030

10141031
fn ensure_in_vreg(&mut self, reg: Reg, ty: Type) -> Reg {

0 commit comments

Comments
 (0)