Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for indexing register array #81

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions isla-axiomatic/src/litmus/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ fn loc_latex(loc: &Loc<Name>, symtab: &Symtab) -> String {
Loc::Id(id) => zencode::decode(symtab.to_str(*id)),
Loc::Field(loc, field) => format!("{}.{}", loc_latex(loc, symtab), zencode::decode(symtab.to_str(*field))),
Loc::Addr(loc) => format!("(*{})", loc_latex(loc, symtab)),
Loc::Index(loc, index) => format!("{}[{}]", loc_latex(loc, symtab), *index),
}
}

Expand Down
43 changes: 43 additions & 0 deletions isla-lib/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ fn get_loc_and_initialize<'ir, B: BV>(
panic!("Struct expression did not evaluate to a struct")
}
}
Loc::Index(loc, index) => {
if let Val::Vector(vs) =
get_loc_and_initialize(loc, local_state, shared_state, solver, accessor, info, for_write)?
{
match vs.get(*index as usize) {
Some(index_value) => index_value.clone(),
None => panic!("Out of range {:?}", *index),
}
} else {
panic!("Index expression did not evalue to an array")
}
}
_ => panic!("Cannot get_loc_and_initialize"),
})
}
Expand Down Expand Up @@ -567,6 +579,37 @@ fn assign_with_accessor<'ir, B: BV>(
panic!("Cannot get address of non-reference {:?}", loc)
}
}

Loc::Index(loc, index) => {
if let Val::Vector(index_values) =
get_loc_and_initialize(loc, local_state, shared_state, solver, &mut accessor.clone(), info, true)?
{
// As a sanity test, check that the index is in the range.
match index_values.get(*index as usize) {
Some(_) => {
let mut index_values = index_values.clone();
index_values[*index as usize] = v;
assign_with_accessor(
loc,
Val::Vector(index_values),
local_state,
shared_state,
solver,
accessor,
info,
)?;
}
None => panic!("Out of range"),
}
} else {
panic!(
"Cannot assign Index to non-index {:?}.{:?} ({:?})",
loc,
index,
get_loc_and_initialize(loc, local_state, shared_state, solver, &mut accessor.clone(), info, true)
)
}
}
};
Ok(())
}
Expand Down
8 changes: 6 additions & 2 deletions isla-lib/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,21 @@ pub enum Loc<A> {
Id(A),
Field(Box<Loc<A>>, A),
Addr(Box<Loc<A>>),
Index(Box<Loc<A>>, u32),
}

impl<A: Clone> Loc<A> {
pub fn id(&self) -> A {
match self {
Loc::Id(id) => id.clone(),
Loc::Field(loc, _) | Loc::Addr(loc) => loc.id(),
Loc::Field(loc, _) | Loc::Addr(loc) | Loc::Index(loc, _) => loc.id(),
}
}

pub fn id_mut(&mut self) -> &mut A {
match self {
Loc::Id(id) => id,
Loc::Field(loc, _) | Loc::Addr(loc) => loc.id_mut(),
Loc::Field(loc, _) | Loc::Addr(loc) | Loc::Index(loc, _) => loc.id_mut(),
}
}
}
Expand All @@ -179,6 +180,7 @@ impl fmt::Display for Loc<String> {
Loc::Id(a) => write!(f, "{}", zencode::decode(a)),
Loc::Field(loc, a) => write!(f, "{}.{}", loc, a),
Loc::Addr(a) => write!(f, "{}*", a),
Loc::Index(loc, a) => write!(f, "{}[{}]", loc, a),
}
}
}
Expand Down Expand Up @@ -922,6 +924,7 @@ impl<'ir> Symtab<'ir> {
Id(v) => Id(self.get(v)?),
Field(loc, field) => Field(Box::new(self.get_loc(loc)?), self.get(field)?),
Addr(loc) => Addr(Box::new(self.get_loc(loc)?)),
Index(loc, idx) => Index(Box::new(self.get_loc(loc)?), *idx),
})
}

Expand All @@ -942,6 +945,7 @@ pub fn loc_string(loc: &Loc<Name>, symtab: &Symtab) -> String {
Loc::Id(a) => zencode::decode(symtab.to_str(*a)),
Loc::Field(loc, a) => format!("{}.{}", loc_string(loc, symtab), zencode::decode(symtab.to_str(*a))),
Loc::Addr(a) => format!("{}*", loc_string(a, symtab)),
Loc::Index(loc, a) => format!("{}[{}]", loc_string(loc, symtab), a),
}
}

Expand Down
1 change: 1 addition & 0 deletions isla-lib/src/ir/linearize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ fn unssa_loc(loc: &BlockLoc, symtab: &mut Symtab, names: &mut HashMap<SSAName, N
BlockLoc::Id(id) => Id(id.unssa(symtab, names)),
BlockLoc::Field(loc, _, field) => Field(Box::new(unssa_loc(loc, symtab, names)), field.unssa_orig(symtab)),
BlockLoc::Addr(loc) => Addr(Box::new(unssa_loc(loc, symtab, names))),
BlockLoc::Index(loc, index) => Index(Box::new(unssa_loc(loc, symtab, names)), index.unssa_orig(symtab).id),
}
}

Expand Down
8 changes: 7 additions & 1 deletion isla-lib/src/ir/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,15 @@ pub enum BlockLoc {
// Field locations contain the previous name so that we can update one field at a time
Field(Box<BlockLoc>, SSAName, SSAName),
Addr(Box<BlockLoc>),
// Index is not assignable and don't need SSA Name, so the ssa number is always -1.
Index(Box<BlockLoc>, SSAName),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this just use a u32 like Loc?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's essentially a wrapper of u32. I use SSAName for consistency in style.

Copy link
Collaborator

@Alasdair Alasdair Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should just be u32. It should only be a SSAName if it was originally a Name in the non-SSA IR.

Name::from_u32(n) could maybe have a more descriptive name - it is not just creating a Name for the number, it's creating a name that indexes the nth element of the symbol table which is not what we want here.

}

impl BlockLoc {
fn id(&self) -> SSAName {
match self {
BlockLoc::Id(id) => *id,
BlockLoc::Field(loc, _, _) | BlockLoc::Addr(loc) => loc.id(),
BlockLoc::Field(loc, _, _) | BlockLoc::Addr(loc) | BlockLoc::Index(loc, _) => loc.id(),
}
}

Expand All @@ -172,6 +174,7 @@ impl BlockLoc {
BlockLoc::Id(id) => (*id, None),
BlockLoc::Field(loc, base_id, _) => (loc.id(), Some(*base_id)),
BlockLoc::Addr(loc) => (loc.id(), None),
BlockLoc::Index(loc, index) => (loc.id(), Some(*index)),
}
}

Expand All @@ -183,6 +186,8 @@ impl BlockLoc {
vars.push(Variable::Usage(id))
}
BlockLoc::Addr(loc) => loc.collect_variables(vars),
// idx is not var.
BlockLoc::Index(loc, _) => loc.collect_variables(vars),
}
}

Expand All @@ -203,6 +208,7 @@ impl From<&Loc<Name>> for BlockLoc {
BlockLoc::Field(Box::new(Self::from(loc.as_ref())), base_name, SSAName::new(*field))
}
Loc::Addr(loc) => BlockLoc::Addr(Box::new(Self::from(loc.as_ref()))),
Loc::Index(loc, index) => BlockLoc::Index(Box::new(Self::from(loc.as_ref())), SSAName::new(Name::from_u32(*index))),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions isla-lib/src/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,10 @@ impl WriteVar for Loc<String> {
l = loc
}
Loc::Addr(loc) => l = loc,
Loc::Index(loc, idx) => {
write!(buf, "(_ index |{}|) ", idx)?;
l = loc
}
}
}
write!(buf, "))")
Expand Down
6 changes: 4 additions & 2 deletions isla-lib/src/smt_parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ Comma<T>: Vec<T> = {

Ident: String = <id:r"[A-Za-z_][A-Za-z0-9_'#]*"> => zencode::encode(id);

Num: u32 = <n:r"[0-9]+"> =>? Ok(u32::from_str(n).map_err(|e| e.to_string())?);

Loc: Loc<String> = {
<id:Ident> => Loc::Id(id),
<loc:Loc> "." <id:Ident> => Loc::Field(Box::new(loc), id),
// locate var by indexing array var
<loc:Loc> "[" <idx:Num> "]" => Loc::Index(Box::new(loc), idx),
}

Num: u32 = <n:r"[0-9]+"> =>? Ok(u32::from_str(n).map_err(|e| e.to_string())?);

pub Exp: Exp<Loc<String>> = {
"=" <exp:Exp1> <mut exps:Exp1+> => {
exps.drain(..).fold(None, |acc, r| match acc {
Expand Down