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
@@ -15,7 +15,8 @@ pub enum GlobalValueData {
|
||||
///
|
||||
/// The `base` global value is assumed to contain a pointer. This global value is computed
|
||||
/// by loading from memory at that pointer value. The memory must be accessible, and
|
||||
/// naturally aligned to hold a value of the type.
|
||||
/// naturally aligned to hold a value of the type. The data at this address is assumed
|
||||
/// to never change while the current function is executing.
|
||||
Load {
|
||||
/// The base pointer global value.
|
||||
base: GlobalValue,
|
||||
@@ -25,6 +26,9 @@ pub enum GlobalValueData {
|
||||
|
||||
/// Type of the loaded value.
|
||||
global_type: Type,
|
||||
|
||||
/// Specifies whether the memory that this refers to is readonly, allowing for the elimination of redundant loads.
|
||||
readonly: bool,
|
||||
},
|
||||
|
||||
/// Value is an offset from another global value.
|
||||
@@ -90,7 +94,15 @@ impl fmt::Display for GlobalValueData {
|
||||
base,
|
||||
offset,
|
||||
global_type,
|
||||
} => write!(f, "load.{} notrap aligned {}{}", global_type, base, offset),
|
||||
readonly,
|
||||
} => write!(
|
||||
f,
|
||||
"load.{} notrap aligned {}{}{}",
|
||||
global_type,
|
||||
if readonly { "readonly " } else { "" },
|
||||
base,
|
||||
offset
|
||||
),
|
||||
GlobalValueData::IAddImm {
|
||||
global_type,
|
||||
base,
|
||||
|
||||
@@ -5,9 +5,10 @@ use std::fmt;
|
||||
enum FlagBit {
|
||||
Notrap,
|
||||
Aligned,
|
||||
Readonly,
|
||||
}
|
||||
|
||||
const NAMES: [&str; 2] = ["notrap", "aligned"];
|
||||
const NAMES: [&str; 3] = ["notrap", "aligned", "readonly"];
|
||||
|
||||
/// Flags for memory operations like load/store.
|
||||
///
|
||||
@@ -79,6 +80,20 @@ impl MemFlags {
|
||||
pub fn set_aligned(&mut self) {
|
||||
self.set(FlagBit::Aligned)
|
||||
}
|
||||
|
||||
/// Test if the `readonly` flag is set.
|
||||
///
|
||||
/// Loads with this flag have no memory dependendies.
|
||||
/// This results in indefined behavior if the dereferenced memory is mutated at any time
|
||||
/// between when the function is called and when it is exited.
|
||||
pub fn readonly(self) -> bool {
|
||||
self.read(FlagBit::Readonly)
|
||||
}
|
||||
|
||||
/// Set the `readonly` flag.
|
||||
pub fn set_readonly(&mut self) {
|
||||
self.set(FlagBit::Readonly)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MemFlags {
|
||||
|
||||
Reference in New Issue
Block a user