Skip to content

Commit

Permalink
Show transitive constant values in rich IR
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasWanke committed Dec 19, 2023
1 parent 69c83f5 commit d348c95
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 51 deletions.
2 changes: 1 addition & 1 deletion compiler/frontend/src/lir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl Body {
let range = builder.push(id.to_string(), TokenType::Variable, EnumSet::empty());
builder.push_definition(*id, range);
builder.push(" = ", None, EnumSet::empty());
expression.build_rich_ir_with_constants(builder, constants);
expression.build_rich_ir_with_constants(builder, constants, self);
});
}
}
Expand Down
42 changes: 26 additions & 16 deletions compiler/frontend/src/lir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ impl Display for ConstantId {
write!(f, "%{}", self.0)
}
}
impl ConstantId {
pub fn build_rich_ir_with_constants(
self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
) {
self.build_rich_ir(builder);
if let Some(constants) = constants.into() {
builder.push("<", None, EnumSet::empty());
constants
.get(self)
.build_rich_ir_with_constants(builder, constants);
builder.push(">", None, EnumSet::empty());
}
}
}
impl ToRichIr for ConstantId {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
let range = builder.push(self.to_string(), TokenType::Constant, EnumSet::empty());
Expand Down Expand Up @@ -67,7 +83,7 @@ impl ToRichIr for Constants {
let range = builder.push(id.to_string(), TokenType::Constant, EnumSet::empty());
builder.push_definition(*id, range);
builder.push(" = ", None, EnumSet::empty());
constant.build_rich_ir(builder);
constant.build_rich_ir_with_constants(builder, self);
});
}
}
Expand Down Expand Up @@ -97,16 +113,6 @@ impl Constant {
constants: impl Into<Option<&Constants>>,
) {
let constants = constants.into();
let build_constant = |builder: &mut RichIrBuilder, id: ConstantId| {
if let Some(constants) = constants {
constants
.get(id)
.build_rich_ir_with_constants(builder, constants);
} else {
id.build_rich_ir(builder);
}
};

match self {
Self::Int(int) => {
int.build_rich_ir(builder);
Expand All @@ -121,15 +127,19 @@ impl Constant {
builder.push_reference(ReferenceKey::Symbol(symbol.clone()), range);
if let Some(value) = value {
builder.push(" ", None, EnumSet::empty());
build_constant(builder, *value);
value.build_rich_ir_with_constants(builder, constants);
}
}
Self::Builtin(builtin) => {
builtin.build_rich_ir(builder);
}
Self::List(items) => {
builder.push("(", None, EnumSet::empty());
builder.push_children(items, ", ");
builder.push_children_custom(
items,
|builder, item| item.build_rich_ir_with_constants(builder, constants),
", ",
);
if items.len() <= 1 {
builder.push(",", None, EnumSet::empty());
}
Expand All @@ -140,9 +150,9 @@ impl Constant {
builder.push_children_custom(
fields.iter().collect_vec(),
|builder, (key, value)| {
build_constant(builder, **key);
key.build_rich_ir_with_constants(builder, constants);
builder.push(": ", None, EnumSet::empty());
build_constant(builder, **value);
value.build_rich_ir_with_constants(builder, constants);
},
", ",
);
Expand All @@ -164,6 +174,6 @@ impl Constant {
impl_display_via_richir!(Constant);
impl ToRichIr for Constant {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None)
self.build_rich_ir_with_constants(builder, None);
}
}
78 changes: 44 additions & 34 deletions compiler/frontend/src/lir/expression.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{BodyId, ConstantId, Constants, Id};
use super::{Body, BodyId, ConstantId, Constants, Id};
use crate::{
impl_display_via_richir,
rich_ir::{ReferenceKey, RichIrBuilder, ToRichIr, TokenType},
Expand Down Expand Up @@ -165,18 +165,25 @@ impl Expression {
&self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
body: impl Into<Option<&Body>>,
) {
let constants = constants.into();
let body = body.into();

match self {
Self::CreateTag { symbol, value } => {
let range = builder.push(symbol, TokenType::Symbol, EnumSet::empty());
builder.push_reference(ReferenceKey::Symbol(symbol.clone()), range);
builder.push(" ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
}
Self::CreateList(items) => {
builder.push("(", None, EnumSet::empty());
builder.push_children(items, ", ");
builder.push_children_custom(
items,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
", ",
);
if items.len() <= 1 {
builder.push(",", None, EnumSet::empty());
}
Expand All @@ -187,9 +194,9 @@ impl Expression {
builder.push_children_custom(
fields.iter().collect_vec(),
|builder, (key, value)| {
key.build_rich_ir(builder);
key.build_rich_ir_with_constants(builder, constants, body);
builder.push(": ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
},
", ",
);
Expand All @@ -202,57 +209,56 @@ impl Expression {
if captured.is_empty() {
builder.push("nothing", None, EnumSet::empty());
} else {
builder.push_children(captured, ", ");
builder.push_children_custom(
captured,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
", ",
);
}

builder.push(" }", None, EnumSet::empty());
}
Self::Constant(id) => {
id.build_rich_ir(builder);
if let Some(constants) = constants {
builder.push("<", None, EnumSet::empty());
constants
.get(*id)
.build_rich_ir_with_constants(builder, constants);
builder.push(">", None, EnumSet::empty());
}
}
Self::Reference(id) => id.build_rich_ir(builder),
Self::Constant(id) => id.build_rich_ir_with_constants(builder, constants),
Self::Reference(id) => id.build_rich_ir_with_constants(builder, constants, body),
Self::Dup { id, amount } => {
builder.push("dup ", None, EnumSet::empty());
id.build_rich_ir(builder);
id.build_rich_ir_with_constants(builder, constants, body);
builder.push(" by ", None, EnumSet::empty());
builder.push(amount.to_string(), None, EnumSet::empty());
}
Self::Drop(id) => {
builder.push("drop ", None, EnumSet::empty());
id.build_rich_ir(builder);
id.build_rich_ir_with_constants(builder, constants, body);
}
Self::Call {
function,
arguments,
responsible,
} => {
builder.push("call ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" with ", None, EnumSet::empty());
if arguments.is_empty() {
builder.push("no arguments", None, EnumSet::empty());
} else {
builder.push_children(arguments, " ");
builder.push_children_custom(
arguments,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
" ",
);
}
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is responsible)", None, EnumSet::empty());
}
Self::Panic {
reason,
responsible,
} => {
builder.push("panicking because ", None, EnumSet::empty());
reason.build_rich_ir(builder);
reason.build_rich_ir_with_constants(builder, constants, body);
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is at fault)", None, EnumSet::empty());
}
Self::TraceCallStarts {
Expand All @@ -262,13 +268,17 @@ impl Expression {
responsible,
} => {
builder.push("trace: start of call of ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" with ", None, EnumSet::empty());
builder.push_children(arguments, " ");
builder.push_children_custom(
arguments,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
" ",
);
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is responsible, code is at ", None, EnumSet::empty());
hir_call.build_rich_ir(builder);
hir_call.build_rich_ir_with_constants(builder, constants, body);
builder.push(")", None, EnumSet::empty());
}
Self::TraceCallEnds { return_value } => {
Expand All @@ -277,25 +287,25 @@ impl Expression {
None,
EnumSet::empty(),
);
return_value.build_rich_ir(builder);
return_value.build_rich_ir_with_constants(builder, constants, body);
}
Self::TraceExpressionEvaluated {
hir_expression,
value,
} => {
builder.push("trace: expression ", None, EnumSet::empty());
hir_expression.build_rich_ir(builder);
hir_expression.build_rich_ir_with_constants(builder, constants, body);
builder.push(" evaluated to ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
}
Self::TraceFoundFuzzableFunction {
hir_definition,
function,
} => {
builder.push("trace: found fuzzable function ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" defined at ", None, EnumSet::empty());
hir_definition.build_rich_ir(builder);
hir_definition.build_rich_ir_with_constants(builder, constants, body);
}
}
}
Expand All @@ -304,6 +314,6 @@ impl Expression {
impl_display_via_richir!(Expression);
impl ToRichIr for Expression {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None)
self.build_rich_ir_with_constants(builder, None, None);
}
}
16 changes: 16 additions & 0 deletions compiler/frontend/src/lir/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::{Body, Constants, Expression};
use crate::{
impl_countable_id,
rich_ir::{RichIrBuilder, ToRichIr, TokenType},
Expand All @@ -20,6 +21,21 @@ impl Debug for Id {
write!(f, "${}", self.0)
}
}
impl Id {
pub fn build_rich_ir_with_constants(
self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
body: impl Into<Option<&Body>>,
) {
self.build_rich_ir(builder);
if let Some(body) = body.into() && let Some(Expression::Constant(constant_id)) = body.expression(self) {
builder.push("<", None, EnumSet::empty());
constant_id.build_rich_ir_with_constants(builder, constants);
builder.push(">", None, EnumSet::empty());
}
}
}
impl ToRichIr for Id {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
let range = builder.push(self.to_string(), TokenType::Variable, EnumSet::empty());
Expand Down

1 comment on commit d348c95

@jwbot
Copy link
Collaborator

@jwbot jwbot commented on d348c95 Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compiler

Benchmark suite Current: d348c95 Previous: 648991e Ratio
Time: Compiler/hello_world 17902924 ns/iter (± 880322) 16578244 ns/iter (± 585944) 1.08
Time: Compiler/fibonacci 134467227 ns/iter (± 1916395) 133785301 ns/iter (± 886512) 1.01
Time: VM Runtime/hello_world 34043 ns/iter (± 3354) 33206 ns/iter (± 35840) 1.03
Time: VM Runtime/fibonacci/15 58108288 ns/iter (± 1018559) 58795821 ns/iter (± 789388) 0.99
Time: VM Runtime/PLB/binarytrees/6 889938298 ns/iter (± 8169042) 894413363 ns/iter (± 6506275) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.