Skip to content

Commit 41a875b

Browse files
Merge branch 'noir-lang:master' into feat-implement-integer-printing
2 parents 0af5b6c + 70ee787 commit 41a875b

File tree

32 files changed

+471
-134
lines changed

32 files changed

+471
-134
lines changed

.github/workflows/docs-pr.yml

+5-20
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
if: needs.add_label.outputs.has_label == 'true'
5656
steps:
5757
- name: Checkout code
58-
uses: actions/checkout@v2
58+
uses: actions/checkout@v4
5959

6060
- name: Setup Node.js
6161
uses: actions/setup-node@v2
@@ -71,24 +71,8 @@ jobs:
7171
run: |
7272
npm i wasm-opt -g
7373
74-
- name: Install dependencies
75-
run: yarn
76-
77-
- name: Build acvm_js
78-
run: yarn workspace @noir-lang/acvm_js build
79-
80-
- name: Build noirc_abi
81-
run: yarn workspace @noir-lang/noirc_abi build
82-
83-
- name: Build noir_js_types
84-
run: yarn workspace @noir-lang/types build
85-
86-
- name: Build barretenberg wrapper
87-
run: yarn workspace @noir-lang/backend_barretenberg build
88-
89-
- name: Run noir_js
90-
run: |
91-
yarn workspace @noir-lang/noir_js build
74+
- name: Install Yarn dependencies
75+
uses: ./.github/actions/setup
9276

9377
- name: Remove pre-releases
9478
working-directory: docs
@@ -97,8 +81,9 @@ jobs:
9781
run: yarn setStable
9882

9983
- name: Build docs
84+
working-directory: docs
10085
run:
101-
yarn workspace docs build
86+
yarn workspaces foreach -Rt run build
10287

10388
- name: Deploy to Netlify
10489
uses: nwtgck/actions-netlify@v2.1
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: noir_codegen
2+
3+
on:
4+
pull_request:
5+
merge_group:
6+
push:
7+
branches:
8+
- master
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
build-nargo:
16+
runs-on: ubuntu-22.04
17+
strategy:
18+
matrix:
19+
target: [x86_64-unknown-linux-gnu]
20+
21+
steps:
22+
- name: Checkout Noir repo
23+
uses: actions/checkout@v4
24+
25+
- name: Setup toolchain
26+
uses: dtolnay/rust-toolchain@1.71.1
27+
28+
- uses: Swatinem/rust-cache@v2
29+
with:
30+
key: ${{ matrix.target }}
31+
cache-on-failure: true
32+
save-if: ${{ github.event_name != 'merge_group' }}
33+
34+
- name: Build Nargo
35+
run: cargo build --package nargo_cli --release
36+
37+
- name: Package artifacts
38+
run: |
39+
mkdir dist
40+
cp ./target/release/nargo ./dist/nargo
41+
7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz
42+
43+
- name: Upload artifact
44+
uses: actions/upload-artifact@v3
45+
with:
46+
name: nargo
47+
path: ./dist/*
48+
retention-days: 3
49+
50+
test:
51+
needs: [build-nargo]
52+
name: Test noir_codegen
53+
runs-on: ubuntu-latest
54+
steps:
55+
- name: Checkout
56+
uses: actions/checkout@v4
57+
58+
- name: Install Yarn dependencies
59+
uses: ./.github/actions/setup
60+
61+
- name: Setup toolchain
62+
uses: dtolnay/rust-toolchain@1.71.1
63+
with:
64+
targets: wasm32-unknown-unknown
65+
66+
- uses: Swatinem/rust-cache@v2
67+
with:
68+
key: wasm32-unknown-unknown-noir-js
69+
cache-on-failure: true
70+
save-if: ${{ github.event_name != 'merge_group' }}
71+
72+
- name: Install jq
73+
run: sudo apt-get install jq
74+
75+
- name: Install wasm-bindgen-cli
76+
uses: taiki-e/install-action@v2
77+
with:
78+
tool: wasm-bindgen-cli@0.2.86
79+
80+
- name: Install wasm-opt
81+
run: |
82+
npm i wasm-opt -g
83+
84+
- name: Build acvm_js
85+
run: yarn workspace @noir-lang/acvm_js build
86+
87+
- name: Build noirc_abi
88+
run: yarn workspace @noir-lang/noirc_abi build
89+
90+
- name: Build noir_js_types
91+
run: yarn workspace @noir-lang/types build
92+
93+
- name: Build noir_js
94+
run: yarn workspace @noir-lang/noir_js build
95+
96+
- name: Run noir_codegen tests
97+
run: yarn workspace @noir-lang/noir_codegen test

compiler/noirc_evaluator/src/ssa/function_builder/mod.rs

+28-26
Original file line numberDiff line numberDiff line change
@@ -282,32 +282,34 @@ impl FunctionBuilder {
282282
) -> ValueId {
283283
let base = self.field_constant(FieldElement::from(2_u128));
284284
let typ = self.current_function.dfg.type_of_value(lhs);
285-
let (max_bit, pow) = if let Some(rhs_constant) =
286-
self.current_function.dfg.get_numeric_constant(rhs)
287-
{
288-
// Happy case is that we know precisely by how many bits the the integer will
289-
// increase: lhs_bit_size + rhs
290-
let (rhs_bit_size_pow_2, overflows) =
291-
2_u32.overflowing_pow(rhs_constant.to_u128() as u32);
292-
if overflows {
293-
let zero = self.numeric_constant(FieldElement::zero(), typ);
294-
return InsertInstructionResult::SimplifiedTo(zero).first();
295-
}
296-
let pow = self.numeric_constant(FieldElement::from(rhs_bit_size_pow_2 as u128), typ);
297-
(bit_size + (rhs_constant.to_u128() as u32), pow)
298-
} else {
299-
// we use a predicate to nullify the result in case of overflow
300-
let bit_size_var =
301-
self.numeric_constant(FieldElement::from(bit_size as u128), typ.clone());
302-
let overflow = self.insert_binary(rhs, BinaryOp::Lt, bit_size_var);
303-
let one = self.numeric_constant(FieldElement::one(), Type::unsigned(1));
304-
let predicate = self.insert_binary(overflow, BinaryOp::Eq, one);
305-
let predicate = self.insert_cast(predicate, typ.clone());
306-
307-
let pow = self.pow(base, rhs);
308-
let pow = self.insert_cast(pow, typ);
309-
(FieldElement::max_num_bits(), self.insert_binary(predicate, BinaryOp::Mul, pow))
310-
};
285+
let (max_bit, pow) =
286+
if let Some(rhs_constant) = self.current_function.dfg.get_numeric_constant(rhs) {
287+
// Happy case is that we know precisely by how many bits the the integer will
288+
// increase: lhs_bit_size + rhs
289+
let (rhs_bit_size_pow_2, overflows) =
290+
2_u128.overflowing_pow(rhs_constant.to_u128() as u32);
291+
if overflows {
292+
assert!(bit_size < 128, "ICE - shift left with big integers are not supported");
293+
if bit_size < 128 {
294+
let zero = self.numeric_constant(FieldElement::zero(), typ);
295+
return InsertInstructionResult::SimplifiedTo(zero).first();
296+
}
297+
}
298+
let pow = self.numeric_constant(FieldElement::from(rhs_bit_size_pow_2), typ);
299+
(bit_size + (rhs_constant.to_u128() as u32), pow)
300+
} else {
301+
// we use a predicate to nullify the result in case of overflow
302+
let bit_size_var =
303+
self.numeric_constant(FieldElement::from(bit_size as u128), typ.clone());
304+
let overflow = self.insert_binary(rhs, BinaryOp::Lt, bit_size_var);
305+
let one = self.numeric_constant(FieldElement::one(), Type::unsigned(1));
306+
let predicate = self.insert_binary(overflow, BinaryOp::Eq, one);
307+
let predicate = self.insert_cast(predicate, typ.clone());
308+
309+
let pow = self.pow(base, rhs);
310+
let pow = self.insert_cast(pow, typ);
311+
(FieldElement::max_num_bits(), self.insert_binary(predicate, BinaryOp::Mul, pow))
312+
};
311313

312314
let instruction = Instruction::Binary(Binary { lhs, rhs: pow, operator: BinaryOp::Mul });
313315
if max_bit <= bit_size {

compiler/noirc_evaluator/src/ssa/opt/mem2reg/block.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{borrow::Cow, collections::BTreeMap};
1+
use std::borrow::Cow;
22

33
use crate::ssa::ir::{
44
function::Function,
@@ -19,27 +19,27 @@ pub(super) struct Block {
1919
/// Maps a ValueId to the Expression it represents.
2020
/// Multiple ValueIds can map to the same Expression, e.g.
2121
/// dereferences to the same allocation.
22-
pub(super) expressions: BTreeMap<ValueId, Expression>,
22+
pub(super) expressions: im::OrdMap<ValueId, Expression>,
2323

2424
/// Each expression is tracked as to how many aliases it
2525
/// may have. If there is only 1, we can attempt to optimize
2626
/// out any known loads to that alias. Note that "alias" here
2727
/// includes the original reference as well.
28-
pub(super) aliases: BTreeMap<Expression, AliasSet>,
28+
pub(super) aliases: im::OrdMap<Expression, AliasSet>,
2929

3030
/// Each allocate instruction result (and some reference block parameters)
3131
/// will map to a Reference value which tracks whether the last value stored
3232
/// to the reference is known.
33-
pub(super) references: BTreeMap<ValueId, ReferenceValue>,
33+
pub(super) references: im::OrdMap<ValueId, ReferenceValue>,
3434

3535
/// The last instance of a `Store` instruction to each address in this block
36-
pub(super) last_stores: BTreeMap<ValueId, InstructionId>,
36+
pub(super) last_stores: im::OrdMap<ValueId, InstructionId>,
3737
}
3838

3939
/// An `Expression` here is used to represent a canonical key
4040
/// into the aliases map since otherwise two dereferences of the
4141
/// same address will be given different ValueIds.
42-
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
42+
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
4343
pub(super) enum Expression {
4444
Dereference(Box<Expression>),
4545
ArrayElement(Box<Expression>),
@@ -111,10 +111,7 @@ impl Block {
111111
}
112112

113113
fn invalidate_all_references(&mut self) {
114-
for reference_value in self.references.values_mut() {
115-
*reference_value = ReferenceValue::Unknown;
116-
}
117-
114+
self.references.clear();
118115
self.last_stores.clear();
119116
}
120117

@@ -137,7 +134,7 @@ impl Block {
137134
}
138135

139136
// Keep only the references present in both maps.
140-
let mut intersection = BTreeMap::new();
137+
let mut intersection = im::OrdMap::new();
141138
for (value_id, reference) in &other.references {
142139
if let Some(existing) = self.references.get(value_id) {
143140
intersection.insert(*value_id, existing.unify(*reference));

compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,6 @@ fn resolve_globals(
646646
let globals = vecmap(globals, |global| {
647647
let module_id = ModuleId { local_id: global.module_id, krate: crate_id };
648648
let path_resolver = StandardPathResolver::new(module_id);
649-
let storage_slot = context.next_storage_slot(module_id);
650649

651650
let mut resolver = Resolver::new(
652651
&mut context.def_interner,
@@ -662,7 +661,7 @@ fn resolve_globals(
662661

663662
context.def_interner.update_global(global.stmt_id, hir_stmt);
664663

665-
context.def_interner.push_global(global.stmt_id, name, global.module_id, storage_slot);
664+
context.def_interner.push_global(global.stmt_id, name, global.module_id);
666665

667666
(global.file_id, global.stmt_id)
668667
});

compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,11 @@ impl<'a> ModCollector<'a> {
528528
};
529529
errors.push((error.into(), location.file));
530530

531-
let error2 = DefCollectorErrorKind::ModuleOriginallyDefined {
531+
let error = DefCollectorErrorKind::ModuleOriginallyDefined {
532532
mod_name: mod_name.clone(),
533533
span: old_location.span,
534534
};
535-
errors.push((error2.into(), old_location.file));
535+
errors.push((error.into(), old_location.file));
536536
return errors;
537537
}
538538

compiler/noirc_frontend/src/hir/mod.rs

-19
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ pub struct Context {
2929
/// A map of each file that already has been visited from a prior `mod foo;` declaration.
3030
/// This is used to issue an error if a second `mod foo;` is declared to the same file.
3131
pub visited_files: BTreeMap<fm::FileId, Location>,
32-
33-
/// Maps a given (contract) module id to the next available storage slot
34-
/// for that contract.
35-
pub storage_slots: BTreeMap<def_map::ModuleId, StorageSlot>,
3632
}
3733

3834
#[derive(Debug, Copy, Clone)]
@@ -42,8 +38,6 @@ pub enum FunctionNameMatch<'a> {
4238
Contains(&'a str),
4339
}
4440

45-
pub type StorageSlot = u32;
46-
4741
impl Context {
4842
pub fn new(file_manager: FileManager, crate_graph: CrateGraph) -> Context {
4943
Context {
@@ -52,7 +46,6 @@ impl Context {
5246
visited_files: BTreeMap::new(),
5347
crate_graph,
5448
file_manager,
55-
storage_slots: BTreeMap::new(),
5649
}
5750
}
5851

@@ -200,16 +193,4 @@ impl Context {
200193
fn module(&self, module_id: def_map::ModuleId) -> &def_map::ModuleData {
201194
module_id.module(&self.def_maps)
202195
}
203-
204-
/// Returns the next available storage slot in the given module.
205-
/// Returns None if the given module is not a contract module.
206-
fn next_storage_slot(&mut self, module_id: def_map::ModuleId) -> Option<StorageSlot> {
207-
let module = self.module(module_id);
208-
209-
module.is_contract.then(|| {
210-
let next_slot = self.storage_slots.entry(module_id).or_insert(0);
211-
*next_slot += 1;
212-
*next_slot
213-
})
214-
}
215196
}

compiler/noirc_frontend/src/node_interner.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::ast::Ident;
99
use crate::graph::CrateId;
1010
use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias};
1111
use crate::hir::def_map::{LocalModuleId, ModuleId};
12-
use crate::hir::StorageSlot;
1312
use crate::hir_def::stmt::HirLetStatement;
1413
use crate::hir_def::traits::TraitImpl;
1514
use crate::hir_def::traits::{Trait, TraitConstraint};
@@ -399,10 +398,6 @@ impl DefinitionKind {
399398
pub struct GlobalInfo {
400399
pub ident: Ident,
401400
pub local_id: LocalModuleId,
402-
403-
/// Global definitions have an associated storage slot if they are defined within
404-
/// a contract. If they're defined elsewhere, this value is None.
405-
pub storage_slot: Option<StorageSlot>,
406401
}
407402

408403
impl Default for NodeInterner {
@@ -578,14 +573,8 @@ impl NodeInterner {
578573
self.id_to_type.insert(definition_id.into(), typ);
579574
}
580575

581-
pub fn push_global(
582-
&mut self,
583-
stmt_id: StmtId,
584-
ident: Ident,
585-
local_id: LocalModuleId,
586-
storage_slot: Option<StorageSlot>,
587-
) {
588-
self.globals.insert(stmt_id, GlobalInfo { ident, local_id, storage_slot });
576+
pub fn push_global(&mut self, stmt_id: StmtId, ident: Ident, local_id: LocalModuleId) {
577+
self.globals.insert(stmt_id, GlobalInfo { ident, local_id });
589578
}
590579

591580
/// Intern an empty global stmt. Used for collecting globals

compiler/noirc_printable_type/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn to_string(value: &PrintableValue, typ: &PrintableType) -> Option<String> {
209209
}
210210

211211
(PrintableValue::String(s), PrintableType::String { .. }) => {
212-
output.push_str(&format!(r#""{s}""#));
212+
output.push_str(s);
213213
}
214214

215215
(PrintableValue::Struct(map), PrintableType::Struct { name, fields, .. }) => {

docs/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@docusaurus/preset-classic": "^2.4.0",
1414
"@easyops-cn/docusaurus-search-local": "^0.35.0",
1515
"@mdx-js/react": "^1.6.22",
16+
"@noir-lang/noir_js": "workspace:*",
1617
"axios": "^1.4.0",
1718
"clsx": "^1.2.1",
1819
"docusaurus-plugin-typedoc": "1.0.0-next.18",

0 commit comments

Comments
 (0)