Factor out a MemFlags constructor for trusted notrap/aligned accesses.

This commit is contained in:
Dan Gohman
2018-12-11 05:44:26 -08:00
parent 68a13646f9
commit a55c933f19
5 changed files with 14 additions and 15 deletions

View File

@@ -26,6 +26,15 @@ impl MemFlags {
Self { bits: 0 } Self { bits: 0 }
} }
/// Create a set of flags representing an access from a "trusted" address, meaning it's
/// known to be aligned and non-trapping.
pub fn trusted() -> Self {
let mut result = Self::new();
result.set_notrap();
result.set_aligned();
result
}
/// Read a flag bit. /// Read a flag bit.
fn read(self, bit: FlagBit) -> bool { fn read(self, bit: FlagBit) -> bool {
self.bits & (1 << bit as usize) != 0 self.bits & (1 << bit as usize) != 0

View File

@@ -110,9 +110,7 @@ fn load_addr(
}; };
// Global-value loads are always notrap and aligned. They may be readonly. // Global-value loads are always notrap and aligned. They may be readonly.
let mut mflags = ir::MemFlags::new(); let mut mflags = ir::MemFlags::trusted();
mflags.set_notrap();
mflags.set_aligned();
if readonly { if readonly {
mflags.set_readonly(); mflags.set_readonly();
} }

View File

@@ -400,10 +400,8 @@ fn expand_stack_load(
let addr = pos.ins().stack_addr(addr_ty, stack_slot, offset); let addr = pos.ins().stack_addr(addr_ty, stack_slot, offset);
let mut mflags = MemFlags::new();
// Stack slots are required to be accessible and aligned. // Stack slots are required to be accessible and aligned.
mflags.set_notrap(); let mflags = MemFlags::trusted();
mflags.set_aligned();
pos.func.dfg.replace(inst).load(ty, mflags, addr, 0); pos.func.dfg.replace(inst).load(ty, mflags, addr, 0);
} }

View File

@@ -77,9 +77,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
GlobalVariable::Const(val) => val, GlobalVariable::Const(val) => val,
GlobalVariable::Memory { gv, offset, ty } => { GlobalVariable::Memory { gv, offset, ty } => {
let addr = builder.ins().global_value(environ.pointer_type(), gv); let addr = builder.ins().global_value(environ.pointer_type(), gv);
let mut flags = ir::MemFlags::new(); let flags = ir::MemFlags::trusted();
flags.set_notrap();
flags.set_aligned();
builder.ins().load(ty, flags, addr, offset) builder.ins().load(ty, flags, addr, offset)
} }
}; };
@@ -90,9 +88,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
GlobalVariable::Const(_) => panic!("global #{} is a constant", global_index), GlobalVariable::Const(_) => panic!("global #{} is a constant", global_index),
GlobalVariable::Memory { gv, offset, ty } => { GlobalVariable::Memory { gv, offset, ty } => {
let addr = builder.ins().global_value(environ.pointer_type(), gv); let addr = builder.ins().global_value(environ.pointer_type(), gv);
let mut flags = ir::MemFlags::new(); let flags = ir::MemFlags::trusted();
flags.set_notrap();
flags.set_aligned();
let val = state.pop1(); let val = state.pop1();
debug_assert_eq!(ty, builder.func.dfg.value_type(val)); debug_assert_eq!(ty, builder.func.dfg.value_type(val));
builder.ins().store(flags, val, addr, offset); builder.ins().store(flags, val, addr, offset);

View File

@@ -270,9 +270,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
let ext = pos.ins().uextend(I64, callee); let ext = pos.ins().uextend(I64, callee);
pos.ins().imul_imm(ext, 4) pos.ins().imul_imm(ext, 4)
}; };
let mut mflags = ir::MemFlags::new(); let mflags = ir::MemFlags::trusted();
mflags.set_notrap();
mflags.set_aligned();
let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0); let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0);
// Build a value list for the indirect call instruction containing the callee, call_args, // Build a value list for the indirect call instruction containing the callee, call_args,