Skip to content

Commit 1a92399

Browse files
authored
Merge pull request RustPython#4263 from evilpie/jitvalue
Make JitValue an enum
2 parents 5b5abe2 + 634aca0 commit 1a92399

File tree

1 file changed

+96
-99
lines changed

1 file changed

+96
-99
lines changed

jit/src/instructions.rs

Lines changed: 96 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,33 @@ struct Local {
2121
}
2222

2323
#[derive(Debug)]
24-
struct JitValue {
25-
val: Value,
26-
ty: JitType,
24+
enum JitValue {
25+
Int(Value),
26+
Float(Value),
27+
Bool(Value),
2728
}
2829

2930
impl JitValue {
30-
fn new(val: Value, ty: JitType) -> JitValue {
31-
JitValue { val, ty }
31+
fn from_type_and_value(ty: JitType, val: Value) -> JitValue {
32+
match ty {
33+
JitType::Int => JitValue::Int(val),
34+
JitType::Float => JitValue::Float(val),
35+
JitType::Bool => JitValue::Bool(val),
36+
}
37+
}
38+
39+
fn to_jit_type(&self) -> Option<JitType> {
40+
match self {
41+
JitValue::Int(_) => Some(JitType::Int),
42+
JitValue::Float(_) => Some(JitType::Float),
43+
JitValue::Bool(_) => Some(JitType::Bool),
44+
}
45+
}
46+
47+
fn into_value(self) -> Option<Value> {
48+
match self {
49+
JitValue::Int(val) | JitValue::Float(val) | JitValue::Bool(val) => Some(val),
50+
}
3251
}
3352
}
3453

@@ -60,7 +79,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
6079
let params = compiler.builder.func.dfg.block_params(entry_block).to_vec();
6180
for (i, (ty, val)) in arg_types.iter().zip(params).enumerate() {
6281
compiler
63-
.store_variable(i as u32, JitValue::new(val, ty.clone()))
82+
.store_variable(i as u32, JitValue::from_type_and_value(ty.clone(), val))
6483
.unwrap();
6584
}
6685
compiler
@@ -72,36 +91,37 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
7291
val: JitValue,
7392
) -> Result<(), JitCompileError> {
7493
let builder = &mut self.builder;
94+
let ty = val.to_jit_type().ok_or(JitCompileError::NotSupported)?;
7595
let local = self.variables[idx as usize].get_or_insert_with(|| {
7696
let var = Variable::new(idx as usize);
7797
let local = Local {
7898
var,
79-
ty: val.ty.clone(),
99+
ty: ty.clone(),
80100
};
81-
builder.declare_var(var, val.ty.to_cranelift());
101+
builder.declare_var(var, ty.to_cranelift());
82102
local
83103
});
84-
if val.ty != local.ty {
104+
if ty != local.ty {
85105
Err(JitCompileError::NotSupported)
86106
} else {
87-
self.builder.def_var(local.var, val.val);
107+
self.builder.def_var(local.var, val.into_value().unwrap());
88108
Ok(())
89109
}
90110
}
91111

92112
fn boolean_val(&mut self, val: JitValue) -> Result<Value, JitCompileError> {
93-
match val.ty {
94-
JitType::Float => {
113+
match val {
114+
JitValue::Float(val) => {
95115
let zero = self.builder.ins().f64const(0);
96-
let val = self.builder.ins().fcmp(FloatCC::NotEqual, val.val, zero);
116+
let val = self.builder.ins().fcmp(FloatCC::NotEqual, val, zero);
97117
Ok(self.builder.ins().bint(types::I8, val))
98118
}
99-
JitType::Int => {
119+
JitValue::Int(val) => {
100120
let zero = self.builder.ins().iconst(types::I64, 0);
101-
let val = self.builder.ins().icmp(IntCC::NotEqual, val.val, zero);
121+
let val = self.builder.ins().icmp(IntCC::NotEqual, val, zero);
102122
Ok(self.builder.ins().bint(types::I8, val))
103123
}
104-
JitType::Bool => Ok(val.val),
124+
JitValue::Bool(val) => Ok(val),
105125
}
106126
}
107127

@@ -160,26 +180,17 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
160180
types::I64,
161181
value.to_i64().ok_or(JitCompileError::NotSupported)?,
162182
);
163-
self.stack.push(JitValue {
164-
val,
165-
ty: JitType::Int,
166-
});
183+
self.stack.push(JitValue::Int(val));
167184
Ok(())
168185
}
169186
BorrowedConstant::Float { value } => {
170187
let val = self.builder.ins().f64const(value);
171-
self.stack.push(JitValue {
172-
val,
173-
ty: JitType::Float,
174-
});
188+
self.stack.push(JitValue::Float(val));
175189
Ok(())
176190
}
177191
BorrowedConstant::Boolean { value } => {
178192
let val = self.builder.ins().iconst(types::I8, value as i64);
179-
self.stack.push(JitValue {
180-
val,
181-
ty: JitType::Bool,
182-
});
193+
self.stack.push(JitValue::Bool(val));
183194
Ok(())
184195
}
185196
_ => Err(JitCompileError::NotSupported),
@@ -228,10 +239,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
228239
let local = self.variables[*idx as usize]
229240
.as_ref()
230241
.ok_or(JitCompileError::BadBytecode)?;
231-
self.stack.push(JitValue {
232-
val: self.builder.use_var(local.var),
233-
ty: local.ty.clone(),
234-
});
242+
self.stack.push(JitValue::from_type_and_value(
243+
local.ty.clone(),
244+
self.builder.use_var(local.var),
245+
));
235246
Ok(())
236247
}
237248
Instruction::StoreFast(idx) => {
@@ -244,27 +255,28 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
244255
Instruction::ReturnValue => {
245256
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
246257
if let Some(ref ty) = self.sig.ret {
247-
if val.ty != *ty {
258+
if val.to_jit_type().as_ref() != Some(ty) {
248259
return Err(JitCompileError::NotSupported);
249260
}
250261
} else {
251-
self.sig.ret = Some(val.ty.clone());
262+
let ty = val.to_jit_type().ok_or(JitCompileError::NotSupported)?;
263+
self.sig.ret = Some(ty.clone());
252264
self.builder
253265
.func
254266
.signature
255267
.returns
256-
.push(AbiParam::new(val.ty.to_cranelift()));
268+
.push(AbiParam::new(ty.to_cranelift()));
257269
}
258-
self.builder.ins().return_(&[val.val]);
270+
self.builder.ins().return_(&[val.into_value().unwrap()]);
259271
Ok(())
260272
}
261273
Instruction::CompareOperation { op, .. } => {
262274
// the rhs is popped off first
263275
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
264276
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
265277

266-
match (a.ty, b.ty) {
267-
(JitType::Int, JitType::Int) => {
278+
match (a, b) {
279+
(JitValue::Int(a), JitValue::Int(b)) => {
268280
let cond = match op {
269281
ComparisonOperator::Equal => IntCC::Equal,
270282
ComparisonOperator::NotEqual => IntCC::NotEqual,
@@ -274,16 +286,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
274286
ComparisonOperator::GreaterOrEqual => IntCC::SignedLessThanOrEqual,
275287
};
276288

277-
let val = self.builder.ins().icmp(cond, a.val, b.val);
278-
self.stack.push(JitValue {
279-
// TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
280-
val: self.builder.ins().bint(types::I8, val),
281-
ty: JitType::Bool,
282-
});
283-
289+
let val = self.builder.ins().icmp(cond, a, b);
290+
// TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
291+
self.stack
292+
.push(JitValue::Bool(self.builder.ins().bint(types::I8, val)));
284293
Ok(())
285294
}
286-
(JitType::Float, JitType::Float) => {
295+
(JitValue::Float(a), JitValue::Float(b)) => {
287296
let cond = match op {
288297
ComparisonOperator::Equal => FloatCC::Equal,
289298
ComparisonOperator::NotEqual => FloatCC::NotEqual,
@@ -293,13 +302,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
293302
ComparisonOperator::GreaterOrEqual => FloatCC::GreaterThanOrEqual,
294303
};
295304

296-
let val = self.builder.ins().fcmp(cond, a.val, b.val);
297-
self.stack.push(JitValue {
298-
// TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8
299-
val: self.builder.ins().bint(types::I8, val),
300-
ty: JitType::Bool,
301-
});
302-
305+
let val = self.builder.ins().fcmp(cond, a, b);
306+
// TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8
307+
self.stack
308+
.push(JitValue::Bool(self.builder.ins().bint(types::I8, val)));
303309
Ok(())
304310
}
305311
_ => Err(JitCompileError::NotSupported),
@@ -308,16 +314,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
308314
Instruction::UnaryOperation { op, .. } => {
309315
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
310316

311-
match a.ty {
312-
JitType::Int => match op {
317+
match a {
318+
JitValue::Int(val) => match op {
313319
UnaryOperator::Minus => {
314320
// Compile minus as 0 - a.
315321
let zero = self.builder.ins().iconst(types::I64, 0);
316-
let out = self.compile_sub(zero, a.val);
317-
self.stack.push(JitValue {
318-
val: out,
319-
ty: JitType::Int,
320-
});
322+
let out = self.compile_sub(zero, val);
323+
self.stack.push(JitValue::Int(out));
321324
Ok(())
322325
}
323326
UnaryOperator::Plus => {
@@ -327,14 +330,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
327330
}
328331
_ => Err(JitCompileError::NotSupported),
329332
},
330-
JitType::Bool => match op {
333+
JitValue::Bool(val) => match op {
331334
UnaryOperator::Not => {
332-
let val = self.boolean_val(a)?;
333335
let not_val = self.builder.ins().bxor_imm(val, 1);
334-
self.stack.push(JitValue {
335-
val: not_val,
336-
ty: JitType::Bool,
337-
});
336+
self.stack.push(JitValue::Bool(not_val));
338337
Ok(())
339338
}
340339
_ => Err(JitCompileError::NotSupported),
@@ -346,73 +345,71 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
346345
// the rhs is popped off first
347346
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
348347
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
349-
let (val, ty) = match (op, a.ty, b.ty) {
350-
(BinaryOperator::Add, JitType::Int, JitType::Int) => {
351-
let (out, carry) = self.builder.ins().iadd_ifcout(a.val, b.val);
348+
let val = match (op, a, b) {
349+
(BinaryOperator::Add, JitValue::Int(a), JitValue::Int(b)) => {
350+
let (out, carry) = self.builder.ins().iadd_ifcout(a, b);
352351
self.builder.ins().trapif(
353352
IntCC::Overflow,
354353
carry,
355354
TrapCode::IntegerOverflow,
356355
);
357-
(out, JitType::Int)
356+
JitValue::Int(out)
358357
}
359-
(BinaryOperator::Subtract, JitType::Int, JitType::Int) => {
360-
(self.compile_sub(a.val, b.val), JitType::Int)
358+
(BinaryOperator::Subtract, JitValue::Int(a), JitValue::Int(b)) => {
359+
JitValue::Int(self.compile_sub(a, b))
361360
}
362-
(BinaryOperator::FloorDivide, JitType::Int, JitType::Int) => {
363-
(self.builder.ins().sdiv(a.val, b.val), JitType::Int)
361+
(BinaryOperator::FloorDivide, JitValue::Int(a), JitValue::Int(b)) => {
362+
JitValue::Int(self.builder.ins().sdiv(a, b))
364363
}
365-
(BinaryOperator::Modulo, JitType::Int, JitType::Int) => {
366-
(self.builder.ins().srem(a.val, b.val), JitType::Int)
364+
(BinaryOperator::Modulo, JitValue::Int(a), JitValue::Int(b)) => {
365+
JitValue::Int(self.builder.ins().srem(a, b))
367366
}
368367
(
369368
BinaryOperator::Lshift | BinaryOperator::Rshift,
370-
JitType::Int,
371-
JitType::Int,
369+
JitValue::Int(a),
370+
JitValue::Int(b),
372371
) => {
373372
// Shifts throw an exception if we have a negative shift count
374373
// Remove all bits except the sign bit, and trap if its 1 (i.e. negative).
375-
let sign = self.builder.ins().ushr_imm(b.val, 63);
374+
let sign = self.builder.ins().ushr_imm(b, 63);
376375
self.builder.ins().trapnz(
377376
sign,
378377
TrapCode::User(CustomTrapCode::NegativeShiftCount as u16),
379378
);
380379

381380
let out = if *op == BinaryOperator::Lshift {
382-
self.builder.ins().ishl(a.val, b.val)
381+
self.builder.ins().ishl(a, b)
383382
} else {
384-
self.builder.ins().sshr(a.val, b.val)
383+
self.builder.ins().sshr(a, b)
385384
};
386-
387-
(out, JitType::Int)
385+
JitValue::Int(out)
388386
}
389-
(BinaryOperator::And, JitType::Int, JitType::Int) => {
390-
(self.builder.ins().band(a.val, b.val), JitType::Int)
387+
(BinaryOperator::And, JitValue::Int(a), JitValue::Int(b)) => {
388+
JitValue::Int(self.builder.ins().band(a, b))
391389
}
392-
(BinaryOperator::Or, JitType::Int, JitType::Int) => {
393-
(self.builder.ins().bor(a.val, b.val), JitType::Int)
390+
(BinaryOperator::Or, JitValue::Int(a), JitValue::Int(b)) => {
391+
JitValue::Int(self.builder.ins().bor(a, b))
394392
}
395-
(BinaryOperator::Xor, JitType::Int, JitType::Int) => {
396-
(self.builder.ins().bxor(a.val, b.val), JitType::Int)
393+
(BinaryOperator::Xor, JitValue::Int(a), JitValue::Int(b)) => {
394+
JitValue::Int(self.builder.ins().bxor(a, b))
397395
}
398396

399397
// Floats
400-
(BinaryOperator::Add, JitType::Float, JitType::Float) => {
401-
(self.builder.ins().fadd(a.val, b.val), JitType::Float)
398+
(BinaryOperator::Add, JitValue::Float(a), JitValue::Float(b)) => {
399+
JitValue::Float(self.builder.ins().fadd(a, b))
402400
}
403-
(BinaryOperator::Subtract, JitType::Float, JitType::Float) => {
404-
(self.builder.ins().fsub(a.val, b.val), JitType::Float)
401+
(BinaryOperator::Subtract, JitValue::Float(a), JitValue::Float(b)) => {
402+
JitValue::Float(self.builder.ins().fsub(a, b))
405403
}
406-
(BinaryOperator::Multiply, JitType::Float, JitType::Float) => {
407-
(self.builder.ins().fmul(a.val, b.val), JitType::Float)
404+
(BinaryOperator::Multiply, JitValue::Float(a), JitValue::Float(b)) => {
405+
JitValue::Float(self.builder.ins().fmul(a, b))
408406
}
409-
(BinaryOperator::Divide, JitType::Float, JitType::Float) => {
410-
(self.builder.ins().fdiv(a.val, b.val), JitType::Float)
407+
(BinaryOperator::Divide, JitValue::Float(a), JitValue::Float(b)) => {
408+
JitValue::Float(self.builder.ins().fdiv(a, b))
411409
}
412410
_ => return Err(JitCompileError::NotSupported),
413411
};
414-
415-
self.stack.push(JitValue { val, ty });
412+
self.stack.push(val);
416413

417414
Ok(())
418415
}

0 commit comments

Comments
 (0)