Skip to content

Commit

Permalink
perf: set weight metadata on switches too (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes authored Apr 27, 2024
1 parent 5098178 commit 0a43be3
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 25 deletions.
1 change: 1 addition & 0 deletions crates/revm-jit-backend/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ pub trait Builder: BackendTypes + TypeMethods {
index: Self::Value,
default: Self::BasicBlock,
targets: &[(u64, Self::BasicBlock)],
default_is_cold: bool,
);
fn phi(&mut self, ty: Self::Type, incoming: &[(Self::Value, Self::BasicBlock)]) -> Self::Value;
fn select(
Expand Down
10 changes: 10 additions & 0 deletions crates/revm-jit-cli/src/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ pub fn get_benches() -> Vec<Bench> {
calldata: hex!("30627b7c").to_vec(),
..Default::default()
},
Bench {
name: "fiat_token",
bytecode: hex::decode(include_str!("../../../data/fiat_token.rt.hex")).unwrap(),
..Default::default()
},
Bench {
name: "usdc_proxy",
bytecode: hex::decode(include_str!("../../../data/usdc_proxy.rt.hex")).unwrap(),
..Default::default()
},
]
}

Expand Down
6 changes: 5 additions & 1 deletion crates/revm-jit-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{
#[derive(Parser)]
struct Cli {
bench_name: String,
#[arg(default_value = "0")]
#[arg(default_value = "1")]
n_iters: u64,

#[arg(long)]
Expand Down Expand Up @@ -154,6 +154,10 @@ fn main() -> Result<()> {
(r, interpreter.next_action)
};

if cli.n_iters == 0 {
return Ok(());
}

let (ret, action) = debug_time!("run", || run(f));
println!("InstructionResult::{ret:?}");
println!("InterpreterAction::{action:#?}");
Expand Down
2 changes: 2 additions & 0 deletions crates/revm-jit-cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,9 @@ impl<'a> Builder for EvmCraneliftBuilder<'a> {
index: Self::Value,
default: Self::BasicBlock,
targets: &[(u64, Self::BasicBlock)],
default_is_cold: bool,
) {
let _ = default_is_cold;
let mut switch = cranelift::frontend::Switch::new();
for (value, block) in targets {
switch.set_entry(*value as u128, *block);
Expand Down
64 changes: 50 additions & 14 deletions crates/revm-jit-llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ use inkwell::{
AnyType, AnyTypeEnum, BasicType, BasicTypeEnum, FunctionType, IntType, PointerType,
StringRadix, VoidType,
},
values::{BasicValue, BasicValueEnum, FunctionValue, PointerValue},
values::{
BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, InstructionValue,
PointerValue,
},
AddressSpace, IntPredicate, OptimizationLevel,
};
use revm_jit_backend::{
eyre, Backend, BackendTypes, Builder, Error, IntCC, Result, TypeMethods, U256,
};
use rustc_hash::FxHashMap;
use std::{
iter,
path::Path,
sync::{Once, OnceLock},
};
Expand All @@ -39,6 +43,9 @@ pub use inkwell::{self, context::Context};
mod dh;
pub mod orc;

const DEFAULT_WEIGHT: u32 = 20000;
const OVERRIDE_TARGET: bool = false;

/// Executes the given closure with a thread-local LLVM context.
#[inline]
pub fn with_llvm_context<R>(f: impl FnOnce(&Context) -> R) -> R {
Expand Down Expand Up @@ -358,12 +365,24 @@ impl TargetDefaults {
fn get() -> &'static Self {
static TARGET_DEFAULTS: OnceLock<TargetDefaults> = OnceLock::new();
TARGET_DEFAULTS.get_or_init(|| {
if let Some(r#override) = Self::r#override() {
return r#override;
}
let triple = TargetMachine::get_default_triple();
let cpu = TargetMachine::get_host_cpu_name().to_string_lossy().into_owned();
let features = TargetMachine::get_host_cpu_features().to_string_lossy().into_owned();
TargetDefaults { triple, cpu, features }
})
}

fn r#override() -> Option<Self> {
OVERRIDE_TARGET.then(|| {
let triple = TargetTriple::create("aarch64-unknown-linux-gnu");
let cpu = String::from("");
let features = String::from("");
TargetDefaults { triple, cpu, features }
})
}
}

/// The LLVM-based EVM bytecode compiler function builder.
Expand Down Expand Up @@ -466,6 +485,23 @@ impl<'a, 'ctx> EvmLlvmBuilder<'a, 'ctx> {
}
}
}

fn set_branch_weights(
&self,
inst: InstructionValue<'ctx>,
weights: impl IntoIterator<Item = u32>,
) {
let weights = weights.into_iter();
let mut values =
Vec::<BasicMetadataValueEnum<'ctx>>::with_capacity(1 + weights.size_hint().1.unwrap());
values.push(self.cx.metadata_string("branch_weights").into());
for weight in weights {
values.push(self.ty_i32.const_int(weight as u64, false).into());
}
let metadata = self.cx.metadata_node(&values);
let kind_id = self.cx.get_kind_id("prof");
inst.set_metadata(metadata, kind_id).unwrap();
}
}

impl<'a, 'ctx> BackendTypes for EvmLlvmBuilder<'a, 'ctx> {
Expand Down Expand Up @@ -653,29 +689,25 @@ impl<'a, 'ctx> Builder for EvmLlvmBuilder<'a, 'ctx> {
.bcx
.build_conditional_branch(cond.into_int_value(), then_block, else_block)
.unwrap();
let metadata = {
// From Clang.
let branch_weights = self.cx.metadata_string("branch_weights");
let then_weight = if then_is_cold { 1 } else { 2000 };
let else_weight = if then_is_cold { 2000 } else { 1 };
let then_weight = self.ty_i32.const_int(then_weight, false);
let else_weight = self.ty_i32.const_int(else_weight, false);
self.cx.metadata_node(&[branch_weights.into(), then_weight.into(), else_weight.into()])
};
let kind_id = self.cx.get_kind_id("prof");
inst.set_metadata(metadata, kind_id).unwrap();
let weights = if then_is_cold { [1, DEFAULT_WEIGHT] } else { [DEFAULT_WEIGHT, 1] };
self.set_branch_weights(inst, weights);
}

fn switch(
&mut self,
index: Self::Value,
default: Self::BasicBlock,
targets: &[(u64, Self::BasicBlock)],
default_is_cold: bool,
) {
let ty = index.get_type().into_int_type();
let targets =
targets.iter().map(|(v, b)| (ty.const_int(*v, false), *b)).collect::<Vec<_>>();
self.bcx.build_switch(index.into_int_value(), default, &targets).unwrap();
let inst = self.bcx.build_switch(index.into_int_value(), default, &targets).unwrap();
if default_is_cold {
let weights = iter::once(1).chain(iter::repeat(DEFAULT_WEIGHT).take(targets.len()));
self.set_branch_weights(inst, weights);
}
}

fn phi(&mut self, ty: Self::Type, incoming: &[(Self::Value, Self::BasicBlock)]) -> Self::Value {
Expand Down Expand Up @@ -988,7 +1020,11 @@ fn init_() -> Result<()> {
info: true,
machine_code: true,
};
Target::initialize_native(&config).map_err(Error::msg)?;
if OVERRIDE_TARGET {
Target::initialize_all(&config);
} else {
Target::initialize_native(&config).map_err(Error::msg)?;
}

Ok(())
}
Expand Down
28 changes: 18 additions & 10 deletions crates/revm-jit/src/compiler/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ pub(super) struct FunctionCx<'a, B: Backend> {
incoming_dynamic_jumps: Incoming<B>,
/// The dynamic jump table block where all dynamic jumps branch to.
dynamic_jump_table: B::BasicBlock,
/// The block that all jumps branch to if the jump is invalid.
jump_fail: B::BasicBlock,

/// `failure_block` incoming values.
incoming_failures: Incoming<B>,
Expand Down Expand Up @@ -212,12 +210,12 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
let ecx = bcx.fn_param(5);

// Create all instruction entry blocks.
let jump_fail = bcx.create_block("jump_fail");
let unreachable_block = bcx.create_block("unreachable");
let inst_entries: Vec<_> = bytecode
.iter_all_insts()
.map(|(i, data)| {
if data.is_dead_code() {
jump_fail
unreachable_block
} else {
bcx.create_block(&op_block_name_with(i, data, ""))
}
Expand Down Expand Up @@ -254,7 +252,6 @@ impl<'a, B: Backend> FunctionCx<'a, B> {

incoming_dynamic_jumps: Vec::new(),
dynamic_jump_table,
jump_fail,

incoming_failures: Vec::new(),
failure_block,
Expand Down Expand Up @@ -317,8 +314,8 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
}

// Finalize the dynamic jump table.
fx.bcx.switch_to_block(jump_fail);
fx.build_fail_imm(InstructionResult::InvalidJump);
fx.bcx.switch_to_block(unreachable_block);
fx.bcx.unreachable();
let i32_type = fx.bcx.type_int(32);
if bytecode.has_dynamic_jumps() {
fx.bcx.switch_to_block(fx.dynamic_jump_table);
Expand All @@ -338,7 +335,8 @@ impl<'a, B: Backend> FunctionCx<'a, B> {

// fx.bcx.switch_to_block(target);
// let index = fx.bcx.ireduce(i32_type, index);
fx.bcx.switch(index, jump_fail, &targets);
fx.add_invalid_jump();
fx.bcx.switch(index, return_block, &targets, true);
} else {
// No dynamic jumps.
debug_assert!(fx.incoming_dynamic_jumps.is_empty());
Expand Down Expand Up @@ -391,7 +389,7 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
let stack_len = fx.bcx.load(fx.isize_type, stack_len_arg, "stack_len");
fx.stack_len.store(&mut fx.bcx, stack_len);
fx.resume_blocks[0].1 = default; // Zero case is handled above.
fx.bcx.switch(resume_at, default, &fx.resume_blocks);
fx.bcx.switch(resume_at, default, &fx.resume_blocks, true);
}

// Suspend block: store the `resume_at` value and return `CallOrCreate`.
Expand Down Expand Up @@ -987,7 +985,7 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
debug_assert_eq!(*data, op::JUMPI);
// The jump target is invalid, but we still need to account for the stack.
self.len_offset -= 1;
self.jump_fail
self.return_block
} else if data.flags.contains(InstFlags::STATIC_JUMP) {
let target_inst = data.data as usize;
debug_assert_eq!(
Expand All @@ -1009,6 +1007,9 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
let cond_word = self.pop();
let cond = self.bcx.icmp_imm(IntCC::NotEqual, cond_word, 0);
let next = self.inst_entries[inst + 1];
if target == self.return_block {
self.add_invalid_jump();
}
self.bcx.brif(cond, target, next);
} else {
self.bcx.br(target);
Expand Down Expand Up @@ -1411,6 +1412,13 @@ impl<'a, B: Backend> FunctionCx<'a, B> {
self.bcx.br(self.return_block);
}

fn add_invalid_jump(&mut self) {
self.incoming_returns.push((
self.bcx.iconst(self.i8_type, InstructionResult::InvalidJump as i64),
self.bcx.current_block().unwrap(),
));
}

// Pointer must not be null if `must_be_set` is true.
fn pointer_panic_with_bool(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions data/fiat_token.rt.hex

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions data/usdc_proxy.rt.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633659cfe6146100775780634f1ef286146100ba5780635c60da1b146101085780638f2839701461015f578063f851a440146101a2575b6100756101f9565b005b34801561008357600080fd5b506100b8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610213565b005b610106600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001919091929391929390505050610268565b005b34801561011457600080fd5b5061011d610308565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561016b57600080fd5b506101a0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610360565b005b3480156101ae57600080fd5b506101b761051e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610201610576565b61021161020c610651565b610682565b565b61021b6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025c57610257816106d9565b610265565b6102646101f9565b5b50565b6102706106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102fa576102ac836106d9565b3073ffffffffffffffffffffffffffffffffffffffff163483836040518083838082843782019150509250505060006040518083038185875af19250505015156102f557600080fd5b610303565b6103026101f9565b5b505050565b60006103126106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156103545761034d610651565b905061035d565b61035c6101f9565b5b90565b6103686106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561051257600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515610466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001807f43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f81526020017f787920746f20746865207a65726f20616464726573730000000000000000000081525060400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61048f6106a8565b82604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a161050d81610748565b61051b565b61051a6101f9565b5b50565b60006105286106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561056a576105636106a8565b9050610573565b6105726101f9565b5b90565b61057e6106a8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151515610647576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001807f43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e20667281526020017f6f6d207468652070726f78792061646d696e000000000000000000000000000081525060400191505060405180910390fd5b61064f610777565b565b6000807f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36001029050805491505090565b3660008037600080366000845af43d6000803e80600081146106a3573d6000f35b3d6000fd5b6000807f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b6001029050805491505090565b6106e281610779565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b60010290508181555050565b565b60006107848261084b565b151561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b8152602001807f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f81526020017f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000081525060400191505060405180910390fd5b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c360010290508181555050565b600080823b9050600081119150509190505600a165627a7a72305820a4a547cfc7202c5acaaae74d428e988bc62ad5024eb0165532d3a8f91db4ed240029

0 comments on commit 0a43be3

Please sign in to comment.