Add a readonly flag for loads (#562)
* Add readonly MemFlag * Add readonly flag verifier check * Make global loads readonly * Fix gvn to consider readonly loads
This commit is contained in:
committed by
Dan Gohman
parent
3ec21459c5
commit
586a8835e9
@@ -18,10 +18,19 @@ fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool {
|
||||
|| opcode.can_trap()
|
||||
|| opcode.other_side_effects()
|
||||
|| opcode.can_store()
|
||||
|| opcode.can_load()
|
||||
|| opcode.writes_cpu_flags()
|
||||
}
|
||||
|
||||
/// Test that, if the specified instruction is a load, it doesn't have the `readonly` memflag.
|
||||
fn is_load_and_not_readonly(inst_data: &InstructionData) -> bool {
|
||||
match *inst_data {
|
||||
InstructionData::Load { flags, .. } | InstructionData::LoadComplex { flags, .. } => {
|
||||
!flags.readonly()
|
||||
}
|
||||
_ => inst_data.opcode().can_load(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around `InstructionData` which implements `Eq` and `Hash`
|
||||
#[derive(Clone)]
|
||||
struct HashKey<'a, 'f: 'a> {
|
||||
@@ -91,14 +100,23 @@ pub fn do_simple_gvn(func: &mut Function, domtree: &mut DominatorTree) {
|
||||
let func = Ref::map(pos.borrow(), |pos| &pos.func);
|
||||
|
||||
let opcode = func.dfg[inst].opcode();
|
||||
|
||||
if opcode.is_branch() && !opcode.is_terminator() {
|
||||
scope_stack.push(func.layout.next_inst(inst).unwrap());
|
||||
visible_values.increment_depth();
|
||||
}
|
||||
|
||||
if trivially_unsafe_for_gvn(opcode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let inst_data = func.dfg[inst].clone();
|
||||
|
||||
// These are split up to separate concerns.
|
||||
if is_load_and_not_readonly(&inst_data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let ctrl_typevar = func.dfg.ctrl_typevar(inst);
|
||||
let key = HashKey {
|
||||
inst: func.dfg[inst].clone(),
|
||||
|
||||
Reference in New Issue
Block a user