Reorganize the global value kinds. (#490)

* Reorganize the global value kinds.

This:
 - renames "deref" global values to "load" and gives it a offset that works
   like the "load" instructions' does
 - adds an explicit "iadd_imm" global value kind, which replaces the
   builtin iadd in "vmctx" and "deref" global values.
 - also renames "globalsym" to "symbol"
This commit is contained in:
Dan Gohman
2018-09-04 21:09:04 -07:00
committed by GitHub
parent 59b83912ba
commit ca9da7702e
30 changed files with 467 additions and 320 deletions

View File

@@ -1,6 +1,6 @@
//! Global values.
use ir::immediates::Offset32;
use ir::immediates::{Imm64, Offset32};
use ir::{ExternalName, GlobalValue, Type};
use isa::TargetIsa;
use std::fmt;
@@ -8,35 +8,47 @@ use std::fmt;
/// Information about a global value declaration.
#[derive(Clone)]
pub enum GlobalValueData {
/// Value is the address of a field in the VM context struct, a constant offset from the VM
/// context pointer.
VMContext {
/// Offset from the `vmctx` pointer.
offset: Offset32,
},
/// Value is the address of the VM context struct.
VMContext,
/// Value is pointed to by another global value.
///
/// The `base` global value is assumed to contain a pointer. This global value is computed
/// by loading from memory at that pointer value, and then adding an offset. The memory must
/// be accessible, and naturally aligned to hold a value of the type.
Deref {
/// by loading from memory at that pointer value. The memory must be accessible, and
/// naturally aligned to hold a value of the type.
Load {
/// The base pointer global value.
base: GlobalValue,
/// Byte offset to be added to the loaded value.
/// Offset added to the base pointer before doing the load.
offset: Offset32,
/// Type of the loaded value.
memory_type: Type,
global_type: Type,
},
/// Value is identified by a symbolic name. Cranelift itself does not interpret this name;
/// Value is an offset from another global value.
IAddImm {
/// The base pointer global value.
base: GlobalValue,
/// Byte offset to be added to the value.
offset: Imm64,
/// Type of the iadd.
global_type: Type,
},
/// Value is a symbolic address. Cranelift itself does not interpret this name;
/// it's used by embedders to link with other data structures.
Sym {
Symbol {
/// The symbolic name.
name: ExternalName,
/// Offset from the symbol. This can be used instead of IAddImm to represent folding an
/// offset into a symbol.
offset: Imm64,
/// Will this symbol be defined nearby, such that it will always be a certain distance
/// away, after linking? If so, references to it can avoid going through a GOT. Note that
/// symbols meant to be preemptible cannot be colocated.
@@ -45,10 +57,10 @@ pub enum GlobalValueData {
}
impl GlobalValueData {
/// Assume that `self` is an `GlobalValueData::Sym` and return its name.
/// Assume that `self` is an `GlobalValueData::Symbol` and return its name.
pub fn symbol_name(&self) -> &ExternalName {
match *self {
GlobalValueData::Sym { ref name, .. } => name,
GlobalValueData::Symbol { ref name, .. } => name,
_ => panic!("only symbols have names"),
}
}
@@ -56,8 +68,11 @@ impl GlobalValueData {
/// Return the type of this global.
pub fn global_type(&self, isa: &TargetIsa) -> Type {
match *self {
GlobalValueData::VMContext { .. } | GlobalValueData::Sym { .. } => isa.pointer_type(),
GlobalValueData::Deref { memory_type, .. } => memory_type,
GlobalValueData::VMContext { .. } | GlobalValueData::Symbol { .. } => {
isa.pointer_type()
}
GlobalValueData::IAddImm { global_type, .. }
| GlobalValueData::Load { global_type, .. } => global_type,
}
}
}
@@ -65,20 +80,34 @@ impl GlobalValueData {
impl fmt::Display for GlobalValueData {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
GlobalValueData::VMContext { offset } => write!(f, "vmctx{}", offset),
GlobalValueData::Deref {
GlobalValueData::VMContext => write!(f, "vmctx"),
GlobalValueData::Load {
base,
offset,
memory_type,
} => write!(f, "deref({}){}: {}", base, offset, memory_type),
GlobalValueData::Sym {
global_type,
} => write!(f, "load.{} notrap aligned {}{}", global_type, base, offset),
GlobalValueData::IAddImm {
global_type,
base,
offset,
} => write!(f, "iadd_imm.{} {}, {}", global_type, base, offset),
GlobalValueData::Symbol {
ref name,
offset,
colocated,
} => {
if colocated {
write!(f, "colocated ")?;
}
write!(f, "globalsym {}", name)
write!(f, "symbol {}", name)?;
let offset_val: i64 = offset.into();
if offset_val > 0 {
write!(f, "+")?;
}
if offset_val != 0 {
write!(f, "{}", offset)?;
}
Ok(())
}
}
}