Skip to content

Commit

Permalink
do ot duplicate codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
vezenovm committed Jan 9, 2025
1 parent bb5a9ea commit 74a7358
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 357 deletions.
6 changes: 0 additions & 6 deletions compiler/noirc_evaluator/src/ssa/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,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
67 changes: 52 additions & 15 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.values_iter() {
match global_value {
Value::NumericConstant { constant, typ } => {
writeln!(f, "g{} = {typ} {constant}", id.to_u32())?;
}
Value::Instruction { instruction, .. } => {
display_instruction(&self.globals, *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.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, true, f)?;
display_instruction(dfg, *instruction, false, f)?;
}

display_terminator(dfg, block.terminator(), f)
Expand All @@ -54,7 +87,7 @@ fn value(dfg: &DataFlowGraph, id: ValueId) -> String {
Value::ForeignFunction(function) => function.clone(),
Value::Param { .. } | Value::Instruction { .. } => id.to_string(),
Value::Global(_) => {
format!("@{id}")
format!("g{}", id.to_u32())
}
}
}
Expand All @@ -75,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 @@ -110,20 +143,24 @@ pub(crate) fn display_terminator(
}

/// Display an arbitrary instruction
pub(crate) fn display_instruction(
fn display_instruction(
dfg: &DataFlowGraph,
instruction: InstructionId,
indent: bool,
in_global_space: bool,
f: &mut Formatter,
) -> Result {
if indent {
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
18 changes: 4 additions & 14 deletions compiler/noirc_evaluator/src/ssa/ir/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,16 @@ pub(crate) enum Value {
/// Example, if you add two numbers together, then the resulting
/// value would have position `0`, the typ would be the type
/// of the operands, and the instruction would map to an add instruction.
Instruction {
instruction: InstructionId,
position: usize,
typ: Type,
},
Instruction { instruction: InstructionId, position: usize, typ: Type },

/// This Value originates from a block parameter. Since function parameters
/// are also represented as block parameters, this includes function parameters as well.
///
/// position -- the index of this Value in the block parameters list
Param {
block: BasicBlockId,
position: usize,
typ: Type,
},
Param { block: BasicBlockId, position: usize, typ: Type },

/// This Value originates from a numeric constant
NumericConstant {
constant: FieldElement,
typ: NumericType,
},
NumericConstant { constant: FieldElement, typ: NumericType },

/// This Value refers to a function in the IR.
/// Functions always have the type Type::Function.
Expand All @@ -65,6 +54,7 @@ pub(crate) enum Value {
/// 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),
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/noirc_evaluator/src/ssa/opt/inlining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use crate::ssa::{
ir::{
basic_block::BasicBlockId,
call_stack::CallStackId,
dfg::InsertInstructionResult,
dfg::{DataFlowGraph, InsertInstructionResult},
function::{Function, FunctionId, RuntimeType},
instruction::{Instruction, InstructionId, TerminatorInstruction},
value::{Value, ValueId},
},
ssa_gen::{context::GlobalsContext, Ssa},
ssa_gen::Ssa,
};
use fxhash::FxHashMap as HashMap;

Expand Down Expand Up @@ -99,7 +99,7 @@ struct InlineContext<'global> {
// These are the functions of the program that we shouldn't inline.
functions_not_to_inline: BTreeSet<FunctionId>,

globals: &'global GlobalsContext,
globals: &'global DataFlowGraph,
}

/// The per-function inlining context contains information that is only valid for one function.
Expand Down Expand Up @@ -382,7 +382,7 @@ impl<'global> InlineContext<'global> {
let mut context = PerFunctionContext::new(&mut self, entry_point);
context.inlining_entry = true;

for (_, value) in ssa.globals.dfg.values_iter() {
for (_, value) in ssa.globals.values_iter() {
context.context.builder.current_function.dfg.make_global(value.get_type().into_owned());
}

Expand Down Expand Up @@ -491,10 +491,10 @@ impl<'function, 'global> PerFunctionContext<'function, 'global> {
Value::Global(_) => {
// TODO: Inlining the global into the function is only a temporary measure
// until Brillig gen with globals is working end to end
match &self.context.globals.dfg[id] {
match &self.context.globals[id] {
Value::Instruction { instruction, .. } => {
let Instruction::MakeArray { elements, typ } =
&self.context.globals.dfg[*instruction]
&self.context.globals[*instruction]
else {
panic!("Only expect Instruction::MakeArray for a global");
};
Expand Down
7 changes: 4 additions & 3 deletions compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use std::collections::BTreeMap;
use crate::ssa::{
ir::{
basic_block::BasicBlockId,
dfg::DataFlowGraph,
function::{Function, FunctionId},
map::SparseMap,
post_order::PostOrder,
value::{Value, ValueId},
},
ssa_gen::{context::GlobalsContext, Ssa},
ssa_gen::Ssa,
};
use fxhash::FxHashMap as HashMap;
use iter_extended::vecmap;
Expand Down Expand Up @@ -65,14 +66,14 @@ impl Context {
}
}

fn normalize_ids(&mut self, old_function: &mut Function, globals: &GlobalsContext) {
fn normalize_ids(&mut self, old_function: &mut Function, globals: &DataFlowGraph) {
self.new_ids.blocks.clear();
self.new_ids.values.clear();

let new_function_id = self.new_ids.function_ids[&old_function.id()];
let new_function = &mut self.functions[new_function_id];

for (_, value) in globals.dfg.values_iter() {
for (_, value) in globals.values_iter() {
new_function.dfg.make_global(value.get_type().into_owned());
}

Expand Down
Loading

0 comments on commit 74a7358

Please sign in to comment.