1 //! The [InstructionContext] trait describes a Cranelift instruction; a default implementation is
2 //! provided with [DfgInstructionContext]
3 use cranelift_codegen::ir::{DataFlowGraph, Inst, InstructionData, Type, Value};
4 
5 /// Exposes the necessary information for understanding a single Cranelift instruction. It would be
6 /// nice if [InstructionData] contained everything necessary for interpreting the instruction, but
7 /// Cranelift's current design requires looking at other structures. A default implementation using
8 /// a reference to a [DataFlowGraph] is provided in [DfgInstructionContext].
9 pub trait InstructionContext {
data(&self) -> InstructionData10     fn data(&self) -> InstructionData;
args(&self) -> &[Value]11     fn args(&self) -> &[Value];
type_of(&self, v: Value) -> Option<Type>12     fn type_of(&self, v: Value) -> Option<Type>;
controlling_type(&self) -> Option<Type>13     fn controlling_type(&self) -> Option<Type>;
14 }
15 
16 /// Since [InstructionContext] is likely used within a Cranelift context in which a [DataFlowGraph]
17 /// is available, a default implementation is provided--[DfgInstructionContext].
18 pub struct DfgInstructionContext<'a>(Inst, &'a DataFlowGraph);
19 
20 impl<'a> DfgInstructionContext<'a> {
new(inst: Inst, dfg: &'a DataFlowGraph) -> Self21     pub fn new(inst: Inst, dfg: &'a DataFlowGraph) -> Self {
22         Self(inst, dfg)
23     }
24 }
25 
26 impl InstructionContext for DfgInstructionContext<'_> {
data(&self) -> InstructionData27     fn data(&self) -> InstructionData {
28         self.1.insts[self.0]
29     }
30 
args(&self) -> &[Value]31     fn args(&self) -> &[Value] {
32         self.1.inst_args(self.0)
33     }
34 
type_of(&self, v: Value) -> Option<Type>35     fn type_of(&self, v: Value) -> Option<Type> {
36         Some(self.1.value_type(v))
37     }
38 
controlling_type(&self) -> Option<Type>39     fn controlling_type(&self) -> Option<Type> {
40         Some(self.1.ctrl_typevar(self.0))
41     }
42 }
43