mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-20 18:56:17 +00:00
Remove stripping of minsize attribute for functions with 256-bit integer division (#501)
## Description We previously had a workaround to strip `minsize` attributes for functions with 256-bit integer division due to a crash in the LLVM backend. We now [patch](https://github.com/paritytech/revive/pull/500) LLVM with the fix, allowing us to use `minsize` with correct backend optimization, making the workaround unnecessary.
This commit is contained in:
1 file changed
-46
@@ -9,7 +9,6 @@ use inkwell::debug_info::AsDIScope;
|
|||||||
use inkwell::debug_info::DIScope;
|
use inkwell::debug_info::DIScope;
|
||||||
use inkwell::types::BasicType;
|
use inkwell::types::BasicType;
|
||||||
use inkwell::values::BasicValue;
|
use inkwell::values::BasicValue;
|
||||||
use inkwell::values::InstructionOpcode;
|
|
||||||
use revive_solc_json_interface::PolkaVMDefaultHeapMemorySize;
|
use revive_solc_json_interface::PolkaVMDefaultHeapMemorySize;
|
||||||
use revive_solc_json_interface::PolkaVMDefaultStackMemorySize;
|
use revive_solc_json_interface::PolkaVMDefaultStackMemorySize;
|
||||||
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
|
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
|
||||||
@@ -312,17 +311,6 @@ impl<'ctx> Context<'ctx> {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Remove MinSize on functions that perform large integer div/rem to
|
|
||||||
// avoid compiler crash that happens when large integer div/rem by
|
|
||||||
// power-of-2 are not being expanded by ExpandLargeIntDivRem pass as
|
|
||||||
// it expects peephole from DAGCombine, which doesn't happen due to the
|
|
||||||
// MinSize attribute being set on the function.
|
|
||||||
// NOTE: As soon as it strips attribute from a function where large
|
|
||||||
// integer div/rem is used, it's crucial to call it after inlining.
|
|
||||||
// TODO: Remove this once LLVM fix is backported to LLVM 21 and we
|
|
||||||
// switch to corresponding inkwell version.
|
|
||||||
self.strip_minsize_for_divrem();
|
|
||||||
|
|
||||||
self.debug_config
|
self.debug_config
|
||||||
.dump_llvm_ir_optimized(contract_path, self.module())?;
|
.dump_llvm_ir_optimized(contract_path, self.module())?;
|
||||||
|
|
||||||
@@ -1468,38 +1456,4 @@ impl<'ctx> Context<'ctx> {
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scans all functions in the module and removes the `MinSize` attribute
|
|
||||||
/// if the function contains any large sdiv, udiv, srem, urem instructions with either unknown
|
|
||||||
/// NOTE: The check here could be relaxed by checking denominator: if the denominator is
|
|
||||||
/// unknown or is a power-of-2 constant, then need to strip the `minsize` attribute; otherwise
|
|
||||||
/// instruction can be ignored as backend will expand it correctly.
|
|
||||||
fn strip_minsize_for_divrem(&self) {
|
|
||||||
self.module().get_functions().for_each(|func| {
|
|
||||||
let has_divrem = func.get_basic_block_iter().any(|b| {
|
|
||||||
b.get_instructions().any(|inst| match inst.get_opcode() {
|
|
||||||
InstructionOpcode::SDiv
|
|
||||||
| InstructionOpcode::UDiv
|
|
||||||
| InstructionOpcode::SRem
|
|
||||||
| InstructionOpcode::URem => {
|
|
||||||
inst.get_type().into_int_type().get_bit_width() >= 256
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
if has_divrem
|
|
||||||
&& func
|
|
||||||
.get_enum_attribute(
|
|
||||||
inkwell::attributes::AttributeLoc::Function,
|
|
||||||
Attribute::MinSize as u32,
|
|
||||||
)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
func.remove_enum_attribute(
|
|
||||||
inkwell::attributes::AttributeLoc::Function,
|
|
||||||
Attribute::MinSize as u32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user