Skip to content

Commit c34f677

Browse files
committed
Optimize array of literals
1 parent 8550af9 commit c34f677

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

compiler/qsc_eval/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ impl State {
617617

618618
match &expr.kind {
619619
ExprKind::Array(arr) => self.eval_arr(arr.len()),
620+
ExprKind::ArrayLit(arr) => self.eval_arr_lit(arr, globals),
620621
ExprKind::ArrayRepeat(..) => self.eval_arr_repeat(expr.span)?,
621622
ExprKind::Assign(lhs, _) => self.eval_assign(env, globals, *lhs)?,
622623
ExprKind::AssignOp(op, lhs, rhs) => {
@@ -736,6 +737,19 @@ impl State {
736737
self.set_curr_val(Value::Array(arr.into()));
737738
}
738739

740+
fn eval_arr_lit(&mut self, arr: &Vec<ExprId>, globals: &impl PackageStoreLookup) {
741+
let mut new_arr: Rc<Vec<Value>> = Rc::new(Vec::with_capacity(arr.len()));
742+
for id in arr {
743+
let ExprKind::Lit(lit) = &globals.get_expr((self.package, *id).into()).kind else {
744+
panic!("expr kind should be lit")
745+
};
746+
Rc::get_mut(&mut new_arr)
747+
.expect("array should be uniquely referenced")
748+
.push(lit_to_val(lit));
749+
}
750+
self.curr_val = Some(Value::Array(new_arr));
751+
}
752+
739753
fn eval_array_append_in_place(
740754
&mut self,
741755
env: &mut Env,

compiler/qsc_eval/src/lower.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -303,16 +303,34 @@ impl Lowerer {
303303
let ty = self.lower_ty(&expr.ty);
304304

305305
let kind = match &expr.kind {
306-
hir::ExprKind::Array(items) => fir::ExprKind::Array(
307-
items
306+
hir::ExprKind::Array(items) => {
307+
if items
308308
.iter()
309-
.map(|i| {
310-
let i = self.lower_expr(i);
311-
self.cfg.push(CfgNode::Store);
312-
i
313-
})
314-
.collect(),
315-
),
309+
.all(|i| matches!(i.kind, hir::ExprKind::Lit(..)))
310+
{
311+
fir::ExprKind::ArrayLit(
312+
items
313+
.iter()
314+
.map(|i| {
315+
let i = self.lower_expr(i);
316+
self.cfg.pop();
317+
i
318+
})
319+
.collect(),
320+
)
321+
} else {
322+
fir::ExprKind::Array(
323+
items
324+
.iter()
325+
.map(|i| {
326+
let i = self.lower_expr(i);
327+
self.cfg.push(CfgNode::Store);
328+
i
329+
})
330+
.collect(),
331+
)
332+
}
333+
}
316334
hir::ExprKind::ArrayRepeat(value, size) => {
317335
let value = self.lower_expr(value);
318336
self.cfg.push(CfgNode::Store);

compiler/qsc_fir/src/fir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,8 @@ impl Display for Expr {
10151015
pub enum ExprKind {
10161016
/// An array: `[a, b, c]`.
10171017
Array(Vec<ExprId>),
1018+
/// An array of literal values, ie: `[1, 2, 3]`.
1019+
ArrayLit(Vec<ExprId>),
10181020
/// An array constructed by repeating a value: `[a, size = b]`.
10191021
ArrayRepeat(ExprId, ExprId),
10201022
/// An assignment: `set a = b`.
@@ -1074,6 +1076,7 @@ impl Display for ExprKind {
10741076
let mut indent = set_indentation(indented(f), 0);
10751077
match self {
10761078
ExprKind::Array(exprs) => display_array(indent, exprs)?,
1079+
ExprKind::ArrayLit(exprs) => display_array(indent, exprs)?,
10771080
ExprKind::ArrayRepeat(val, size) => display_array_repeat(indent, *val, *size)?,
10781081
ExprKind::Assign(lhs, rhs) => display_assign(indent, *lhs, *rhs)?,
10791082
ExprKind::AssignOp(op, lhs, rhs) => display_assign_op(indent, *op, *lhs, *rhs)?,

compiler/qsc_fir/src/mut_visit.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub fn walk_stmt<'a>(vis: &mut impl MutVisitor<'a>, id: StmtId) {
123123
pub fn walk_expr<'a>(vis: &mut impl MutVisitor<'a>, expr: ExprId) {
124124
let expr = vis.get_expr(expr);
125125
match &expr.kind {
126-
ExprKind::Array(exprs) => exprs.iter().for_each(|e| vis.visit_expr(*e)),
126+
ExprKind::Array(exprs) | ExprKind::ArrayLit(exprs) => {
127+
exprs.iter().for_each(|e| vis.visit_expr(*e));
128+
}
127129
ExprKind::ArrayRepeat(item, size) => {
128130
vis.visit_expr(*item);
129131
vis.visit_expr(*size);

compiler/qsc_fir/src/visit.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub fn walk_stmt<'a>(vis: &mut impl Visitor<'a>, id: StmtId) {
123123
pub fn walk_expr<'a>(vis: &mut impl Visitor<'a>, expr: ExprId) {
124124
let expr = vis.get_expr(expr);
125125
match &expr.kind {
126-
ExprKind::Array(exprs) => exprs.iter().for_each(|e| vis.visit_expr(*e)),
126+
ExprKind::Array(exprs) | ExprKind::ArrayLit(exprs) => {
127+
exprs.iter().for_each(|e| vis.visit_expr(*e));
128+
}
127129
ExprKind::ArrayRepeat(item, size) => {
128130
vis.visit_expr(*item);
129131
vis.visit_expr(*size);

0 commit comments

Comments
 (0)