Skip to content

Commit

Permalink
Merge aae17de into e71fcdf
Browse files Browse the repository at this point in the history
  • Loading branch information
vezenovm authored Jan 10, 2025
2 parents e71fcdf + aae17de commit 2c3f7b9
Show file tree
Hide file tree
Showing 23 changed files with 357 additions and 65 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions compiler/noirc_evaluator/src/acir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1892,6 +1892,9 @@ impl<'a> Context<'a> {
Value::Instruction { .. } | Value::Param { .. } => {
unreachable!("ICE: Should have been in cache {value_id} {value:?}")
}
Value::Global(_) => {
unreachable!("ICE: All globals should have been inlined");
}
};
self.ssa_values.insert(value_id, acir_value.clone());
acir_value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,10 @@ impl<'block> BrilligBlock<'block> {
}
}
}
Value::Instruction { .. } | Value::Param { .. } | Value::NumericConstant { .. } => {
Value::Instruction { .. }
| Value::Param { .. }
| Value::NumericConstant { .. }
| Value::Global(_) => {
unreachable!("unsupported function call type {:?}", dfg[*func])
}
},
Expand Down Expand Up @@ -1557,6 +1560,9 @@ impl<'block> BrilligBlock<'block> {
let value = &dfg[value_id];

match value {
Value::Global(_) => {
unreachable!("ICE: All globals should have been inlined");
}
Value::Param { .. } | Value::Instruction { .. } => {
// All block parameters and instruction results should have already been
// converted to registers so we fetch from the cache.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ pub(crate) fn collect_variables_of_value(
let value = &dfg[value_id];

match value {
Value::Instruction { .. } | Value::Param { .. } | Value::NumericConstant { .. } => {
Some(value_id)
}
Value::Instruction { .. }
| Value::Param { .. }
| Value::NumericConstant { .. }
| Value::Global(_) => Some(value_id),
// Functions are not variables in a defunctionalized SSA. Only constant function values should appear.
Value::ForeignFunction(_) | Value::Function(_) | Value::Intrinsic(..) => None,
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ impl SsaBuilder {
let ssa_path = emit_ssa.with_extension("ssa.json");
write_to_file(&serde_json::to_vec(&ssa).unwrap(), &ssa_path);
}
Ok(SsaBuilder { ssa_logging, print_codegen_timings, ssa }.print("Initial SSA:"))
Ok(SsaBuilder { ssa_logging, print_codegen_timings, ssa }.print("Initial SSA"))
}

fn finish(self) -> Ssa {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ impl DependencyContext {
}
Value::Instruction { .. }
| Value::NumericConstant { .. }
| Value::Param { .. } => {
| Value::Param { .. }
| Value::Global(_) => {
panic!(
"calling non-function value with ID {func_id} in function {}",
function.name()
Expand Down Expand Up @@ -618,7 +619,8 @@ impl Context {
}
Value::Instruction { .. }
| Value::NumericConstant { .. }
| Value::Param { .. } => {
| Value::Param { .. }
| Value::Global(_) => {
panic!("At the point we are running disconnect there shouldn't be any other values as arguments")
}
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ impl DataFlowGraph {
id
}

pub(crate) fn make_global(&mut self, typ: Type) -> ValueId {
self.values.insert(Value::Global(typ))
}

/// Gets or creates a ValueId for the given FunctionId.
pub(crate) fn import_function(&mut self, function: FunctionId) -> ValueId {
if let Some(existing) = self.functions.get(&function) {
Expand Down Expand Up @@ -613,6 +617,9 @@ impl DataFlowGraph {
}
_ => false,
},
// TODO: Make this true and handle instruction simplifications with globals.
// Currently all globals are inlined as a temporary measure so this is fine to have as false.
Value::Global(_) => false,
_ => true,
}
}
Expand Down
22 changes: 12 additions & 10 deletions compiler/noirc_evaluator/src/ssa/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub(crate) struct Function {
/// Name of the function for debugging only
name: String,

id: FunctionId,
id: Option<FunctionId>,

/// The DataFlowGraph holds the majority of data pertaining to the function
/// including its blocks, instructions, and values.
Expand All @@ -90,14 +90,22 @@ impl Function {
pub(crate) fn new(name: String, id: FunctionId) -> Self {
let mut dfg = DataFlowGraph::default();
let entry_block = dfg.make_block();
Self { name, id, entry_block, dfg }
Self { name, id: Some(id), entry_block, dfg }
}

/// Globals are generated using the same codegen process as functions.
/// To avoid a recursive global context we should create a pseudo function to mock a globals context.
pub(crate) fn new_for_globals() -> Self {
let mut dfg = DataFlowGraph::default();
let entry_block = dfg.make_block();
Self { name: "globals".to_owned(), id: None, entry_block, dfg }
}

/// Creates a new function as a clone of the one passed in with the passed in id.
pub(crate) fn clone_with_id(id: FunctionId, another: &Function) -> Self {
let dfg = another.dfg.clone();
let entry_block = another.entry_block;
Self { name: another.name.clone(), id, entry_block, dfg }
Self { name: another.name.clone(), id: Some(id), entry_block, dfg }
}

/// Takes the signature (function name & runtime) from a function but does not copy the body.
Expand All @@ -115,7 +123,7 @@ impl Function {

/// The id of the function.
pub(crate) fn id(&self) -> FunctionId {
self.id
self.id.expect("FunctionId should be initialized")
}

/// Runtime type of the function.
Expand Down Expand Up @@ -228,12 +236,6 @@ pub(crate) struct Signature {
pub(crate) returns: Vec<Type>,
}

impl std::fmt::Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
super::printer::display_function(self, f)
}
}

#[test]
fn sign_smoke() {
let mut signature = Signature::default();
Expand Down
71 changes: 57 additions & 14 deletions compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
//! This file is for pretty-printing the SSA IR in a human-readable form for debugging.
use std::fmt::{Formatter, Result};
use std::fmt::{Display, Formatter, Result};

use acvm::acir::AcirField;
use im::Vector;
use iter_extended::vecmap;

use crate::ssa::ir::types::{NumericType, Type};
use crate::ssa::{
ir::types::{NumericType, Type},
Ssa,
};

use super::{
basic_block::BasicBlockId,
Expand All @@ -15,8 +18,42 @@ use super::{
value::{Value, ValueId},
};

impl Display for Ssa {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
for (id, global_value) in self.globals.dfg.values_iter() {
match global_value {
Value::NumericConstant { constant, typ } => {
writeln!(f, "g{} = {typ} {constant}", id.to_u32())?;
}
Value::Instruction { instruction, .. } => {
display_instruction(&self.globals.dfg, *instruction, true, f)?;
}
Value::Global(_) => {
panic!("Value::Global should only be in the function dfg");
}
_ => panic!("Expected only numeric constant or instruction"),
};
}

if self.globals.dfg.values_iter().len() > 0 {
writeln!(f)?;
}

for function in self.functions.values() {
writeln!(f, "{function}")?;
}
Ok(())
}
}

impl Display for Function {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
display_function(self, f)
}
}

/// Helper function for Function's Display impl to pretty-print the function with the given formatter.
pub(crate) fn display_function(function: &Function, f: &mut Formatter) -> Result {
fn display_function(function: &Function, f: &mut Formatter) -> Result {
writeln!(f, "{} fn {} {} {{", function.runtime(), function.name(), function.id())?;
for block_id in function.reachable_blocks() {
display_block(&function.dfg, block_id, f)?;
Expand All @@ -25,17 +62,13 @@ pub(crate) fn display_function(function: &Function, f: &mut Formatter) -> Result
}

/// Display a single block. This will not display the block's successors.
pub(crate) fn display_block(
dfg: &DataFlowGraph,
block_id: BasicBlockId,
f: &mut Formatter,
) -> Result {
fn display_block(dfg: &DataFlowGraph, block_id: BasicBlockId, f: &mut Formatter) -> Result {
let block = &dfg[block_id];

writeln!(f, " {}({}):", block_id, value_list_with_types(dfg, block.parameters()))?;

for instruction in block.instructions() {
display_instruction(dfg, *instruction, f)?;
display_instruction(dfg, *instruction, false, f)?;
}

display_terminator(dfg, block.terminator(), f)
Expand All @@ -53,6 +86,9 @@ fn value(dfg: &DataFlowGraph, id: ValueId) -> String {
Value::Intrinsic(intrinsic) => intrinsic.to_string(),
Value::ForeignFunction(function) => function.clone(),
Value::Param { .. } | Value::Instruction { .. } => id.to_string(),
Value::Global(_) => {
format!("g{}", id.to_u32())
}
}
}

Expand All @@ -72,7 +108,7 @@ fn value_list(dfg: &DataFlowGraph, values: &[ValueId]) -> String {
}

/// Display a terminator instruction
pub(crate) fn display_terminator(
fn display_terminator(
dfg: &DataFlowGraph,
terminator: Option<&TerminatorInstruction>,
f: &mut Formatter,
Expand Down Expand Up @@ -107,17 +143,24 @@ pub(crate) fn display_terminator(
}

/// Display an arbitrary instruction
pub(crate) fn display_instruction(
fn display_instruction(
dfg: &DataFlowGraph,
instruction: InstructionId,
in_global_space: bool,
f: &mut Formatter,
) -> Result {
// instructions are always indented within a function
write!(f, " ")?;
if !in_global_space {
// instructions are always indented within a function
write!(f, " ")?;
}

let results = dfg.instruction_results(instruction);
if !results.is_empty() {
write!(f, "{} = ", value_list(dfg, results))?;
let mut value_list = value_list(dfg, results);
if in_global_space {
value_list = value_list.replace('v', "g");
}
write!(f, "{} = ", value_list)?;
}

display_instruction_inner(dfg, &dfg[instruction], results, f)
Expand Down
4 changes: 4 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ pub(crate) enum Value {
/// ForeignFunction's always have the type Type::Function and have similar semantics to Function,
/// other than generating different backend operations and being only accessible through Brillig.
ForeignFunction(String),

/// This Value indicates we have a reserved slot that needs to be accessed in a separate global context
Global(Type),
}

impl Value {
Expand All @@ -64,6 +67,7 @@ impl Value {
Value::Function { .. } | Value::Intrinsic { .. } | Value::ForeignFunction { .. } => {
Cow::Owned(Type::Function)
}
Value::Global(typ) => Cow::Borrowed(typ),
}
}
}
Loading

0 comments on commit 2c3f7b9

Please sign in to comment.