Skip to content

Commit

Permalink
always build alloca in the entry block (#46)
Browse files Browse the repository at this point in the history
Signed-off-by: xermicus <[email protected]>
  • Loading branch information
xermicus authored Sep 13, 2024
1 parent 7dc8e60 commit 616f044
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
9 changes: 3 additions & 6 deletions crates/common/src/byte_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ pub const BYTE_LENGTH_BYTE: usize = 1;
/// The x86 word byte-length.
pub const BYTE_LENGTH_X32: usize = 4;

/// Native stack alignment size in bytes
#[cfg(not(feature = "riscv-64"))]
pub const BYTE_LENGTH_STACK_ALIGN: usize = 4;
#[cfg(feature = "riscv-64")]
pub const BYTE_LENGTH_STACK_ALIGN: usize = 8;

/// The x86_64 word byte-length.
pub const BYTE_LENGTH_X64: usize = 8;

/// EVM native stack alignment size in bytes
pub const BYTE_LENGTH_STACK_ALIGN: usize = 32;

/// The ETH address byte-length.
pub const BYTE_LENGTH_ETH_ADDRESS: usize = 20;

Expand Down
37 changes: 30 additions & 7 deletions crates/llvm-context/src/polkavm/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ where
0 => FunctionReturn::none(),
1 => {
self.set_basic_block(entry_block);
let pointer = self.build_alloca(self.word_type(), "return_pointer");
let pointer = self.build_alloca_internal(self.word_type(), "return_pointer");
FunctionReturn::primitive(pointer)
}
size if name.starts_with(Function::ZKSYNC_NEAR_CALL_ABI_PREFIX) => {
Expand All @@ -452,7 +452,7 @@ where
}
size => {
self.set_basic_block(entry_block);
let pointer = self.build_alloca(
let pointer = self.build_alloca_internal(
self.structure_type(
vec![self.word_type().as_basic_type_enum(); size].as_slice(),
),
Expand Down Expand Up @@ -595,19 +595,42 @@ where
self.builder.get_insert_block().expect("Always exists")
}

/// Builds a stack allocation instruction.
/// Sets the alignment to 128 bits.
/// Builds an aligned stack allocation at the function entry.
pub fn build_alloca<T: BasicType<'ctx> + Clone + Copy>(
&self,
r#type: T,
name: &str,
) -> Pointer<'ctx> {
let current_block = self.basic_block();
let entry_block = self.current_function().borrow().entry_block();

match entry_block.get_first_instruction() {
Some(instruction) => self.builder().position_before(&instruction),
None => self.builder().position_at_end(entry_block),
}

let pointer = self.build_alloca_internal(r#type, name);

self.set_basic_block(current_block);
return pointer;
}

/// Builds a stack allocation and sets the alignment.
///
/// Stack allocations should always happen at the function prelude.
/// Only use this when the position is guaranteed to be at the entry!
fn build_alloca_internal<T: BasicType<'ctx> + Clone + Copy>(
&self,
r#type: T,
name: &str,
) -> Pointer<'ctx> {
let pointer = self.builder.build_alloca(r#type, name).unwrap();
self.basic_block()
.get_last_instruction()
.expect("Always exists")
pointer
.as_instruction()
.unwrap()
.set_alignment(revive_common::BYTE_LENGTH_STACK_ALIGN as u32)
.expect("Alignment is valid");

Pointer::new(r#type, AddressSpace::Stack, pointer)
}

Expand Down

0 comments on commit 616f044

Please sign in to comment.