use __bswap in favor of LLVM intrinsic

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-04-25 11:45:28 +02:00
parent df8ebb61ec
commit 2913fbc494
7 changed files with 63 additions and 21 deletions
Generated
+6 -5
View File
@@ -687,6 +687,7 @@ dependencies = [
"regex",
"revive-builtins",
"revive-common",
"revive-extensions",
"revive-linker",
"revive-stdlib",
"semver 1.0.22",
@@ -1349,7 +1350,7 @@ dependencies = [
[[package]]
name = "polkavm"
version = "0.9.3"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e"
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
dependencies = [
"libc",
"log",
@@ -1361,7 +1362,7 @@ dependencies = [
[[package]]
name = "polkavm-assembler"
version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e"
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
dependencies = [
"log",
]
@@ -1369,7 +1370,7 @@ dependencies = [
[[package]]
name = "polkavm-common"
version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e"
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
dependencies = [
"log",
]
@@ -1377,7 +1378,7 @@ dependencies = [
[[package]]
name = "polkavm-linker"
version = "0.9.2"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e"
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
dependencies = [
"gimli",
"hashbrown 0.14.3",
@@ -1391,7 +1392,7 @@ dependencies = [
[[package]]
name = "polkavm-linux-raw"
version = "0.9.0"
source = "git+https://github.com/koute/polkavm.git#4ca06cc1b7cb435b2b92e81e30c2eb0e988f563e"
source = "git+https://github.com/koute/polkavm.git?branch=master_byteswap#8b8050bd58be30c6001925b5b2785bc9c98cca4e"
[[package]]
name = "ppv-lite86"
+3 -3
View File
@@ -27,9 +27,9 @@ path-slash = "0.2"
rayon = "1.8"
structopt = { version = "0.3", default-features = false }
rand = "0.8"
polkavm-common = { git = "https://github.com/koute/polkavm.git" }
polkavm-linker = { git = "https://github.com/koute/polkavm.git" }
polkavm = { git = "https://github.com/koute/polkavm.git" }
polkavm-common = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
polkavm-linker = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
polkavm = { branch = "master_byteswap", git = "https://github.com/koute/polkavm.git" }
alloy-primitives = "0.6"
alloy-sol-types = "0.6"
env_logger = { version = "0.10.0", default-features = false }
+1 -1
View File
@@ -5,7 +5,7 @@ fn compile(source_path: &str, output_path: &str) {
.args([
"-O3",
"-filetype=asm",
"-mattr=+zbb,+e",
"-mattr=+zbb,+e,+m",
source_path,
"-o",
output_path,
+1
View File
@@ -33,3 +33,4 @@ pallet-contracts-pvm-llapi = { path = "../pallet-contracts-pvm-llapi" }
revive-linker = { path = "../linker" }
revive-builtins = { path = "../builtins" }
revive-stdlib = { path = "../stdlib" }
revive-extensions = { path = "../extensions" }
+50 -10
View File
@@ -122,6 +122,31 @@ where
/// The PolkaVM minimum stack size.
const POLKAVM_STACK_SIZE: u32 = 0x4000;
/// Link in the extensions module.
fn link_extensions_module(
llvm: &'ctx inkwell::context::Context,
module: &inkwell::module::Module<'ctx>,
) {
module
.link_in_module(revive_extensions::module(llvm, "revive_extensions").unwrap())
.expect("the extensions module should be linkable");
let i256_type = llvm.custom_width_int_type(revive_common::BIT_LENGTH_FIELD as u32);
let bswap = module.add_function(
"__bswap",
i256_type.fn_type(&[i256_type.into()], false),
Some(inkwell::module::Linkage::External),
);
bswap.add_attribute(
inkwell::attributes::AttributeLoc::Function,
llvm.create_enum_attribute(Attribute::AlwaysInline as u32, 0),
);
bswap.add_attribute(
inkwell::attributes::AttributeLoc::Function,
llvm.create_enum_attribute(Attribute::WillReturn as u32, 0),
);
}
/// Link in the stdlib module.
fn link_stdlib_module(
llvm: &'ctx inkwell::context::Context,
@@ -203,6 +228,7 @@ where
debug_config: Option<DebugConfig>,
) -> Self {
Self::link_stdlib_module(llvm, &module);
Self::link_extensions_module(llvm, &module);
Self::link_polkavm_guest_module(llvm, &module);
Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE);
Self::set_module_flags(llvm, &module);
@@ -703,7 +729,7 @@ where
.set_alignment(revive_common::BYTE_LENGTH_BYTE as u32)
.expect("Alignment is valid");
Ok(self.build_byte_swap(value))
self.build_byte_swap(value)
}
AddressSpace::TransientStorage => todo!(),
AddressSpace::Storage => {
@@ -761,13 +787,13 @@ where
// TODO check return value
self.build_load(storage_value_pointer, "storage_value_load")
.map(|value| self.build_byte_swap(value))
.and_then(|value| self.build_byte_swap(value))
}
AddressSpace::Code | AddressSpace::HeapAuxiliary => todo!(),
AddressSpace::Generic => Ok(self.build_byte_swap(self.build_load(
AddressSpace::Generic => self.build_byte_swap(self.build_load(
pointer.address_space_cast(self, AddressSpace::Stack, &format!("{}_cast", name))?,
name,
)?)),
)?),
AddressSpace::Stack => {
let value = self
.builder()
@@ -811,7 +837,7 @@ where
let value = value.as_basic_value_enum();
let value = match value.get_type().into_int_type().get_bit_width() as usize {
revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value),
revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value)?,
revive_common::BIT_LENGTH_BYTE => value,
_ => unreachable!("Only word and byte sized values can be stored on EVM heap"),
};
@@ -834,7 +860,7 @@ where
self.build_alloca(storage_key_value.get_type(), "storage_key");
let storage_value_value = self
.build_byte_swap(value.as_basic_value_enum())
.build_byte_swap(value.as_basic_value_enum())?
.into_int_value();
let storage_value_pointer =
self.build_alloca(storage_value_value.get_type(), "storage_value");
@@ -871,7 +897,7 @@ where
AddressSpace::Code | AddressSpace::HeapAuxiliary => {}
AddressSpace::Generic => self.build_store(
pointer.address_space_cast(self, AddressSpace::Stack, "cast")?,
self.build_byte_swap(value.as_basic_value_enum()),
self.build_byte_swap(value.as_basic_value_enum())?,
)?,
AddressSpace::Stack => {
let instruction = self.builder.build_store(pointer.value, value).unwrap();
@@ -888,9 +914,23 @@ where
pub fn build_byte_swap(
&self,
value: inkwell::values::BasicValueEnum<'ctx>,
) -> inkwell::values::BasicValueEnum<'ctx> {
self.build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap")
.expect("byte_swap should return a value")
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
//return Ok(self
// .build_call(self.intrinsics().byte_swap, &[value], "call_byte_swap")
// .expect("__bswap should return a value"));
let function = self
.module()
.get_function("__bswap")
.expect("should be declared");
Ok(self
.builder()
.build_direct_call(function, &[value.into()], "call_byte_swap")?
.try_as_basic_value()
.left()
.expect("__bswap should return a value")
.into())
}
///
@@ -30,7 +30,7 @@ where
);
context
.build_load(offset, "calldata_value")
.map(|value| context.build_byte_swap(value))
.and_then(|value| context.build_byte_swap(value))
}
///
+1 -1
View File
@@ -47,5 +47,5 @@ where
"call_seal_hash_keccak_256",
)?;
Ok(context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?))
context.build_byte_swap(context.build_load(output_pointer, "sha3_output")?)
}