Skip to content

Commit 1ae035f

Browse files
authored
fix(ssa): Only attempt to inline constant Brillig calls for entry points (#7260)
1 parent a9e9850 commit 1ae035f

2 files changed

Lines changed: 99 additions & 12 deletions

File tree

compiler/noirc_evaluator/src/brillig/brillig_gen.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ pub(crate) fn gen_brillig_for(
5858
brillig: &Brillig,
5959
) -> Result<GeneratedBrillig<FieldElement>, InternalError> {
6060
// Create the entry point artifact
61-
let globals_memory_size = brillig.globals_memory_size.get(&func.id()).copied().unwrap_or(0);
61+
let globals_memory_size = brillig
62+
.globals_memory_size
63+
.get(&func.id())
64+
.copied()
65+
.expect("Should have the globals memory size specified for an entry point");
6266
let mut entry_point = BrilligContext::new_entry_point_artifact(
6367
arguments,
6468
FunctionContext::return_values(func),

compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ impl Ssa {
119119
let func_value = &function.dfg[*func_id];
120120
let Value::Function(func_id) = func_value else { continue };
121121

122-
brillig_functions.remove(func_id);
122+
if function.runtime().is_acir() {
123+
brillig_functions.remove(func_id);
124+
}
123125
}
124126
}
125127
}
@@ -336,17 +338,22 @@ impl<'brillig> Context<'brillig> {
336338
};
337339

338340
// First try to inline a call to a brillig function with all constant arguments.
339-
let new_results = Self::try_inline_brillig_call_with_all_constants(
340-
&instruction,
341-
&old_results,
342-
block,
343-
dfg,
344-
self.brillig_info,
345-
)
346-
// Otherwise, try inserting the instruction again to apply any optimizations using the newly resolved inputs.
347-
.unwrap_or_else(|| {
341+
let new_results = if runtime_is_brillig {
348342
Self::push_instruction(id, instruction.clone(), &old_results, block, dfg)
349-
});
343+
} else {
344+
// We only want to try to inline Brillig calls for Brillig entry points (functions called from an ACIR runtime).
345+
Self::try_inline_brillig_call_with_all_constants(
346+
&instruction,
347+
&old_results,
348+
block,
349+
dfg,
350+
self.brillig_info,
351+
)
352+
// Otherwise, try inserting the instruction again to apply any optimizations using the newly resolved inputs.
353+
.unwrap_or_else(|| {
354+
Self::push_instruction(id, instruction.clone(), &old_results, block, dfg)
355+
})
356+
};
350357

351358
Self::replace_result_ids(dfg, &old_results, &new_results);
352359

@@ -1485,6 +1492,82 @@ mod test {
14851492
assert_normalized_ssa_equals(ssa, expected);
14861493
}
14871494

1495+
#[test]
1496+
fn inlines_brillig_call_with_entry_point_globals() {
1497+
let src = "
1498+
g0 = Field 2
1499+
1500+
acir(inline) fn main f0 {
1501+
b0():
1502+
v1 = call f1() -> Field
1503+
return v1
1504+
}
1505+
1506+
brillig(inline) fn one f1 {
1507+
b0():
1508+
v1 = add g0, Field 3
1509+
return v1
1510+
}
1511+
";
1512+
let ssa = Ssa::from_str(src).unwrap();
1513+
let mut ssa = ssa.dead_instruction_elimination();
1514+
let used_globals_map = std::mem::take(&mut ssa.used_globals);
1515+
let brillig = ssa.to_brillig_with_globals(false, used_globals_map);
1516+
1517+
let expected = "
1518+
g0 = Field 2
1519+
1520+
acir(inline) fn main f0 {
1521+
b0():
1522+
return Field 5
1523+
}
1524+
";
1525+
1526+
let ssa = ssa.fold_constants_with_brillig(&brillig);
1527+
assert_normalized_ssa_equals(ssa, expected);
1528+
}
1529+
1530+
#[test]
1531+
fn inlines_brillig_call_with_non_entry_point_globals() {
1532+
let src = "
1533+
g0 = Field 2
1534+
1535+
acir(inline) fn main f0 {
1536+
b0():
1537+
v1 = call f1() -> Field
1538+
return v1
1539+
}
1540+
1541+
brillig(inline) fn entry_point f1 {
1542+
b0():
1543+
v1 = call f2() -> Field
1544+
return v1
1545+
}
1546+
1547+
brillig(inline) fn one f2 {
1548+
b0():
1549+
v1 = add g0, Field 3
1550+
return v1
1551+
}
1552+
";
1553+
let ssa = Ssa::from_str(src).unwrap();
1554+
let mut ssa = ssa.dead_instruction_elimination();
1555+
let used_globals_map = std::mem::take(&mut ssa.used_globals);
1556+
let brillig = ssa.to_brillig_with_globals(false, used_globals_map);
1557+
1558+
let expected = "
1559+
g0 = Field 2
1560+
1561+
acir(inline) fn main f0 {
1562+
b0():
1563+
return Field 5
1564+
}
1565+
";
1566+
1567+
let ssa = ssa.fold_constants_with_brillig(&brillig);
1568+
assert_normalized_ssa_equals(ssa, expected);
1569+
}
1570+
14881571
#[test]
14891572
fn does_not_use_cached_constrain_in_block_that_is_not_dominated() {
14901573
let src = "

0 commit comments

Comments
 (0)