Skip to content

Commit e4aa109

Browse files
committed
Merge remote-tracking branch 'origin/main' into dani/compiler-improvements
2 parents 5cfc2c7 + e46d8ff commit e4aa109

5 files changed

Lines changed: 34 additions & 1 deletion

File tree

crates/revmc-backend/src/traits.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ pub enum Attribute {
153153
ArgMemOnly,
154154
/// `initializes((0, N))` — function initializes bytes `[0, N)` through this pointer.
155155
Initializes(u64),
156+
/// `dead_on_return` — the contents of the pointed-to memory are dead after the function
157+
/// returns, allowing the caller to elide stores to the memory.
158+
DeadOnReturn,
156159
// TODO: Range?
157160
}
158161

crates/revmc-cli/src/cmd/run.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ pub(crate) struct RunArgs {
8282
/// Inspect the stack after the function has been executed.
8383
#[arg(long)]
8484
inspect_stack: bool,
85+
/// Disable frame pointers in the JIT'd function. Frees up `rbp` for the
86+
/// register allocator (15 GPRs instead of 14 on x86_64) at the cost of
87+
/// not having `rbp`-based stack walks. DWARF `.eh_frame` unwinding still
88+
/// works.
89+
#[arg(long)]
90+
no_frame_pointers: bool,
8591
#[arg(long, default_value = "1000000000")]
8692
gas_limit: u64,
8793
}
@@ -161,6 +167,9 @@ impl RunArgs {
161167
}
162168

163169
compiler.inspect_stack(self.inspect_stack);
170+
if self.no_frame_pointers {
171+
compiler.frame_pointers(false);
172+
}
164173

165174
let parsed = compiler.parse(bytecode.as_slice().into(), compile_spec_id)?;
166175
if self.display || self.parse_only {

crates/revmc-codegen/src/bytecode/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,12 @@ impl<'a> Bytecode<'a> {
563563
self.may_suspend
564564
}
565565

566+
/// Returns `true` if the stack argument's contents are observed by the caller after the
567+
/// function returns (either through `inspect_stack` mode or because execution may suspend).
568+
pub(crate) fn stack_observed(&self) -> bool {
569+
self.config.contains(AnalysisConfig::INSPECT_STACK) || self.may_suspend()
570+
}
571+
566572
/// Returns `true` if any dead-block redirects exist.
567573
pub(crate) fn has_redirects(&self) -> bool {
568574
!self.redirects.is_empty()

crates/revmc-codegen/src/compiler/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ impl<B: Backend> EvmCompiler<B> {
585585
}
586586

587587
let linkage = Linkage::Public;
588-
let (bcx, id) = Self::make_builder(&mut self.backend, &self.config, name, linkage)?;
588+
let (bcx, id) =
589+
Self::make_builder(&mut self.backend, &self.config, bytecode, name, linkage)?;
589590
FunctionCx::translate(bcx, self.config, &mut self.builtins, bytecode)?;
590591
Ok(id)
591592
}
@@ -653,6 +654,7 @@ impl<B: Backend> EvmCompiler<B> {
653654
fn make_builder<'a>(
654655
backend: &'a mut B,
655656
config: &FcxConfig,
657+
bytecode: &Bytecode<'_>,
656658
name: &str,
657659
linkage: Linkage,
658660
) -> Result<(B::Builder<'a>, B::FuncId)> {
@@ -687,6 +689,18 @@ impl<B: Backend> EvmCompiler<B> {
687689
}
688690
}
689691

692+
// The stack argument's contents are dead after return when the stack is not observed,
693+
// so the caller can elide any stores to the buffer.
694+
if !bytecode.stack_observed() {
695+
for param in 1..=2 {
696+
bcx.add_function_attribute(
697+
None,
698+
Attribute::DeadOnReturn,
699+
FunctionAttributeLocation::Param(param),
700+
);
701+
}
702+
}
703+
690704
Ok((bcx, id))
691705
}
692706

crates/revmc-llvm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,7 @@ fn convert_attribute(bcx: &EvmLlvmBuilder<'_>, attr: revmc_backend::Attribute) -
20842084
OurAttr::Writable => ("writable", AttrValue::Enum(0)),
20852085
// memory(argmem: readwrite) = ModRef(3) << ArgMem(0) = 3.
20862086
OurAttr::ArgMemOnly => ("memory", AttrValue::Enum(3)),
2087+
OurAttr::DeadOnReturn => ("dead_on_return", AttrValue::Enum(0)),
20872088

20882089
OurAttr::Initializes(size) => {
20892090
return cpp::create_initializes_attr(bcx.cx, 0, size as i64);

0 commit comments

Comments
 (0)