Skip to content

Commit

Permalink
remove hardcoded u32 type
Browse files Browse the repository at this point in the history
and use type given by the frontend instead.
  • Loading branch information
guipublic committed Mar 8, 2022
1 parent 95bfb87 commit b4cb444
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 26 deletions.
2 changes: 1 addition & 1 deletion crates/nargo/tests/test_data/6_array/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main(x : [5]u32 , y : [5]u32 , z : u32, t : u32) {
for i in 0..5 {
z = z + x[i]*y[i];
for _i in 0..3 {
c = i as u32 - 2;
c = i as u32 - 2 as u32;
z=c*z;
};
};
Expand Down
28 changes: 8 additions & 20 deletions crates/noirc_evaluator/src/ssa/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,7 @@ impl<'a> IRGenerator<'a> {
optype: node::ObjectType,
) -> NodeId {
//Add a new instruction to the nodes arena
let cb = self.get_current_block();

let mut i = node::Instruction::new(opcode, lhs, rhs, optype, Some(cb.id));
let mut i = node::Instruction::new(opcode, lhs, rhs, optype, Some(self.current_block));
//Basic simplification
optim::simplify(self, &mut i);
if i.is_deleted {
Expand Down Expand Up @@ -434,18 +432,6 @@ impl<'a> IRGenerator<'a> {
Ok(())
}

//Cast lhs into type rtype. a cast b means (a) b
fn new_cast_expression(&mut self, lhs: NodeId, rtype: node::ObjectType) -> NodeId {
//generate instruction 'a cast a', with result type rtype
self.push_instruction(Instruction::new(
node::Operation::Cast,
lhs,
lhs,
rtype,
Some(self.current_block),
))
}

fn evaluate_infix_expression(
&mut self,
lhs: NodeId,
Expand Down Expand Up @@ -731,7 +717,7 @@ impl<'a> IRGenerator<'a> {
HirExpression::Cast(cast_expr) => {
let lhs = self.expression_to_object(env, &cast_expr.lhs)?;
let rtype = node::ObjectType::from_type(cast_expr.r#type);
Ok(self.new_cast_expression(lhs, rtype))
Ok(self.new_instruction(lhs, lhs, Operation::Cast, rtype))

//We should generate a cast instruction and handle properly type conversion:
// unsigned integer to field ; ok, just checks if bit size over FieldElement::max_num_bits()
Expand Down Expand Up @@ -774,8 +760,9 @@ impl<'a> IRGenerator<'a> {

// Evaluate the index expression
let index_as_obj = self.expression_to_object(env, &indexed_expr.index)?;
let base_adr = self.get_or_create_const(FieldElement::from(address as i128), node::ObjectType::Unsigned(32));
let adr_id = self.new_instruction(base_adr, index_as_obj, node::Operation::Add, node::ObjectType::Unsigned(32));
let index_type = self.get_object_type(index_as_obj);
let base_adr = self.get_or_create_const(FieldElement::from(address as i128), index_type);
let adr_id = self.new_instruction(base_adr, index_as_obj, node::Operation::Add, index_type);
Ok(self.new_instruction(adr_id, adr_id, node::Operation::Load(array_index), o_type))
},
HirExpression::Call(call_expr) => {
Expand Down Expand Up @@ -851,10 +838,11 @@ impl<'a> IRGenerator<'a> {
.unwrap()
.def_interner
.ident_def(&for_expr.identifier);
let int_type = self.context().def_interner.id_type(&for_expr.identifier);
env.store(iter_name.clone(), Object::Constants(start));
let iter_id = self.create_new_variable(iter_name, iter_def, env); //TODO do we need to store and retrieve it ?
let iter_id = self.create_new_variable(iter_name, iter_def, env);
let iter_var = self.get_mut_variable(iter_id).unwrap();
iter_var.obj_type = node::ObjectType::Unsigned(32); //TODO create_new_variable should set the correct type
iter_var.obj_type = node::ObjectType::from_type(int_type);
let iter_type = self.get_object_type(iter_id);
let iter_ass = self.new_instruction(iter_id, start_idx, node::Operation::Ass, iter_type);
//We map the iterator to start_idx so that when we seal the join block, we will get the corrdect value.
Expand Down
16 changes: 11 additions & 5 deletions crates/noirc_evaluator/src/ssa/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,9 @@ impl Instruction {
pub fn get_const_value(c: FieldElement, ctype: ObjectType) -> (u128, u32) {
match ctype {
ObjectType::Boolean => (if c.is_zero() { 0 } else { 1 }, 1),
ObjectType::NativeField => (0, 256),
ObjectType::NativeField => {
(c.to_u128(), 256) //TODO: handle elements that do not fit in 128 bits
}
ObjectType::Signed(b) | ObjectType::Unsigned(b) => {
assert!(b < 128); //we do not support integers bigger than 128 bits for now.
(c.to_u128(), b)
Expand Down Expand Up @@ -431,7 +433,7 @@ impl Instruction {
unreachable!();
}
assert!(l_bsize == r_bsize);
let res_value = (l_const + r_const) % l_bsize as u128;
let res_value = (l_const + r_const) % (1_u128 << l_bsize) as u128;
return NodeEval::Const(FieldElement::from(res_value), self.res_type);
}
//if only one is const, we could try to do constant propagation but this will be handled by the arithmetization step anyways
Expand All @@ -458,7 +460,8 @@ impl Instruction {
//if l_constant.is_some() && r_constant.is_some() {
assert!(l_bsize == r_bsize);

let res_value = l_const.overflowing_sub(r_const).0 % l_bsize as u128;
let res_value =
l_const.overflowing_sub(r_const).0 % (1_u128 << l_bsize) as u128;
return NodeEval::Const(FieldElement::from(res_value), self.res_type);
}
}
Expand All @@ -483,7 +486,7 @@ impl Instruction {
}

assert!(l_bsize == r_bsize);
let res_value = (l_const * r_const) % l_bsize as u128;
let res_value = (l_const * r_const) % (1_u128 << l_bsize) as u128;
return NodeEval::Const(FieldElement::from(res_value), self.res_type);
}
//if only one is const, we could try to do constant propagation but this will be handled by the arithmetization step anyways
Expand Down Expand Up @@ -661,8 +664,11 @@ impl Instruction {
}
Operation::Cast => {
if let Some(l_const) = l_constant {
if self.res_type == ObjectType::NativeField {
return NodeEval::Const(FieldElement::from(l_const), self.res_type);
}
return NodeEval::Const(
FieldElement::from(l_const % (1 << self.res_type.bits())),
FieldElement::from(l_const % (1_u128 << self.res_type.bits())),
self.res_type,
);
}
Expand Down

0 comments on commit b4cb444

Please sign in to comment.