Change GlobalVar to GlobalValue

This commit is contained in:
Lachlan Sneff
2018-06-14 01:07:27 -04:00
committed by Dan Gohman
parent 49cc693d64
commit 5c320a0d30
44 changed files with 324 additions and 237 deletions

View File

@@ -110,7 +110,7 @@ Program structure
In LLVM IR, the largest representable unit is the *module* which corresponds
more or less to a C translation unit. It is a collection of functions and
global variables that may contain references to external symbols too.
global valueiables that may contain references to external symbols too.
In Cretonne IR, the largest representable unit is the *function*. This is so
that functions can easily be compiled in parallel without worrying about

View File

@@ -554,7 +554,7 @@ stack overflow checks in the prologue.
the stack pointer has reached or exceeded the limit, generate a trap with a
``stk_ovf`` code.
The global variable must be accessible and naturally aligned for a
The global valueiable must be accessible and naturally aligned for a
pointer-sized value.
Setting `stack_limit` is an alternative way to detect stack overflow, when using
@@ -563,12 +563,12 @@ stack overflow checks in the prologue.
Global variables
----------------
A *global variable* is an :term:`accessible` object in memory whose address is
A *global valueiable* is an :term:`accessible` object in memory whose address is
not known at compile time. The address is computed at runtime by
:inst:`global_addr`, possibly using information provided by the linker via
relocations. There are multiple kinds of global variables using different
:inst:`global_value`, possibly using information provided by the linker via
relocations. There are multiple kinds of global valueiables using different
methods for determining their address. Cretonne does not track the type or even
the size of global variables, they are just pointers to non-stack memory.
the size of global valueiables, they are just pointers to non-stack memory.
When Cretonne is generating code for a virtual machine environment, globals can
be used to access data structures in the VM's runtime. This requires functions
@@ -578,26 +578,26 @@ Cretonne functions.
.. inst:: GV = vmctx+Offset
Declare a global variable in the VM context struct.
Declare a global valueiable in the VM context struct.
This declares a global variable whose address is a constant offset from the
This declares a global valueiable whose address is a constant offset from the
VM context pointer which is passed as a hidden argument to all functions
JIT-compiled for the VM.
Typically, the VM context is a C struct, and the declared global variable
Typically, the VM context is a C struct, and the declared global valueiable
is a member of the struct.
:arg Offset: Byte offset from the VM context pointer to the global
variable.
:result GV: Global variable.
The address of a global variable can also be derived by treating another global
The address of a global valueiable can also be derived by treating another global
variable as a struct pointer. This makes it possible to chase pointers into VM
runtime data structures.
.. inst:: GV = deref(BaseGV)+Offset
Declare a global variable in a struct pointed to by BaseGV.
Declare a global valueiable in a struct pointed to by BaseGV.
The address of GV can be computed by first loading a pointer from BaseGV
and adding Offset to it.
@@ -605,7 +605,7 @@ runtime data structures.
It is assumed the BaseGV resides in readable memory with the appropriate
alignment for storing a pointer.
Chains of ``deref`` global variables are possible, but cycles are not
Chains of ``deref`` global valueiables are possible, but cycles are not
allowed. They will be caught by the IR verifier.
:arg BaseGV: Global variable containing the base pointer.
@@ -615,7 +615,7 @@ runtime data structures.
.. inst:: GV = [colocated] globalsym name
Declare a global variable at a symbolic address.
Declare a global valueiable at a symbolic address.
The address of GV is symbolic and will be assigned a relocation, so that
it can be resolved by a later linking phase.
@@ -627,7 +627,7 @@ runtime data structures.
:arg name: External name.
:result GV: Global variable.
.. autoinst:: global_addr
.. autoinst:: global_value
.. autoinst:: globalsym_addr
@@ -701,7 +701,7 @@ trap when accessed.
address space reserved for the heap, not including the guard pages.
:arg GuardBytes: Size of the guard pages in bytes.
When the base is a global variable, it must be :term:`accessible` and naturally
When the base is a global valueiable, it must be :term:`accessible` and naturally
aligned for a pointer value.
The ``reserved_reg`` option is not yet implemented.
@@ -711,7 +711,7 @@ Dynamic heaps
A *dynamic heap* can be relocated to a different base address when it is
resized, and its bound can move dynamically. The guard pages move when the heap
is resized. The bound of a dynamic heap is stored in a global variable.
is resized. The bound of a dynamic heap is stored in a global valueiable.
.. inst:: H = dynamic Base, min MinBytes, bound BoundGV, guard GuardBytes
@@ -724,7 +724,7 @@ is resized. The bound of a dynamic heap is stored in a global variable.
:arg BoundGV: Global variable containing the current heap bound in bytes.
:arg GuardBytes: Size of the guard pages in bytes.
When the base is a global variable, it must be :term:`accessible` and naturally
When the base is a global valueiable, it must be :term:`accessible` and naturally
aligned for a pointer value.
The ``reserved_reg`` option is not yet implemented.

View File

@@ -15,7 +15,7 @@ The meta language descriptions are Python modules under the
steps:
1. The Python modules are imported. This has the effect of building static data
structures in global variables in the modules. These static data structures
structures in global valueiables in the modules. These static data structures
in the :mod:`base` and :mod:`isa` packages use the classes in the
:mod:`cdsl` package to describe instruction sets and other properties.
@@ -81,7 +81,7 @@ open :class:`InstructionGroup`.
:members:
The basic Cretonne instruction set described in :doc:`langref` is defined by the
Python module :mod:`base.instructions`. This module has a global variable
Python module :mod:`base.instructions`. This module has a global valueiable
:data:`base.instructions.GROUP` which is an :class:`InstructionGroup` instance
containing all the base instructions.

View File

@@ -9,7 +9,7 @@ function %vmctx(i64 vmctx) -> i64 {
gv1 = vmctx-16
ebb1(v1: i64):
v2 = global_addr.i64 gv1
v2 = global_value.i64 gv1
; check: v2 = iadd_imm v1, -16
return v2
; check: return v2
@@ -20,7 +20,7 @@ function %deref(i64 vmctx) -> i64 {
gv2 = deref(gv1)+32
ebb1(v1: i64):
v2 = global_addr.i64 gv2
v2 = global_value.i64 gv2
; check: $(a1=$V) = iadd_imm v1, -16
; check: $(p1=$V) = load.i64 notrap aligned $a1
; check: v2 = iadd_imm $p1, 32
@@ -33,9 +33,9 @@ function %sym() -> i64 {
gv1 = globalsym u123:456
ebb1:
v0 = global_addr.i64 gv0
v0 = global_value.i64 gv0
; check: v0 = globalsym_addr.i64 gv0
v1 = global_addr.i64 gv1
v1 = global_value.i64 gv1
; check: v1 = globalsym_addr.i64 gv1
v2 = bxor v0, v1
return v2

View File

@@ -10,8 +10,8 @@ function %vmglobal() -> i32 {
gv5 = vmctx -256
; check: gv5 = vmctx-256
ebb0:
v1 = global_addr.i32 gv3
; check: v1 = global_addr.i32 gv3
v1 = global_value.i32 gv3
; check: v1 = global_value.i32 gv3
return v1
}
@@ -20,19 +20,19 @@ function %deref() -> i32 {
gv4 = deref(gv3)-32
; check: gv4 = deref(gv3)-32
ebb0:
v1 = global_addr.i32 gv4
; check: v1 = global_addr.i32 gv4
v1 = global_value.i32 gv4
; check: v1 = global_value.i32 gv4
return v1
}
; Refer to a global variable before it's been declared.
; Refer to a global valueiable before it's been declared.
function %backref() -> i32 {
gv1 = deref(gv2)-32
; check: gv1 = deref(gv2)-32
gv2 = vmctx+16
; check: gv2 = vmctx+16
ebb0:
v1 = global_addr.i32 gv1
v1 = global_value.i32 gv1
return v1
}
@@ -42,10 +42,10 @@ function %sym() -> i32 {
gv1 = globalsym u8:9
; check: gv1 = globalsym u8:9
ebb0:
v0 = global_addr.i32 gv0
; check: v0 = global_addr.i32 gv0
v1 = global_addr.i32 gv1
; check: v1 = global_addr.i32 gv1
v0 = global_value.i32 gv0
; check: v0 = global_value.i32 gv0
v1 = global_value.i32 gv1
; check: v1 = global_value.i32 gv1
v2 = bxor v0, v1
return v2
}

View File

@@ -16,8 +16,8 @@ ebb = EntityRefKind(
#: A reference to a stack slot declared in the function preamble.
stack_slot = EntityRefKind('stack_slot', 'A stack slot.')
#: A reference to a global variable.
global_var = EntityRefKind('global_var', 'A global variable.')
#: A reference to a global valueiable.
global_value = EntityRefKind('global_value', 'A global value.')
#: A reference to a function sugnature declared in the function preamble.
#: This is used to provide the call signature in a call_indirect instruction.

View File

@@ -18,7 +18,7 @@ UnaryImm = InstructionFormat(imm64)
UnaryIeee32 = InstructionFormat(ieee32)
UnaryIeee64 = InstructionFormat(ieee64)
UnaryBool = InstructionFormat(boolean)
UnaryGlobalVar = InstructionFormat(entities.global_var)
UnaryGlobalValue = InstructionFormat(entities.global_value)
Binary = InstructionFormat(VALUE, VALUE)
BinaryImm = InstructionFormat(VALUE, imm64)
@@ -79,5 +79,5 @@ CondTrap = InstructionFormat(VALUE, trapcode)
IntCondTrap = InstructionFormat(intcc, VALUE, trapcode)
FloatCondTrap = InstructionFormat(floatcc, VALUE, trapcode)
# Finally extract the names of global variables in this module.
# Finally extract the names of global valueiables in this module.
InstructionFormat.extract_names(globals())

View File

@@ -491,19 +491,19 @@ stack_addr = Instruction(
# Global variables.
#
GV = Operand('GV', entities.global_var)
GV = Operand('GV', entities.global_value)
global_addr = Instruction(
'global_addr', r"""
Compute the address of global variable GV.
global_value = Instruction(
'global_value', r"""
Compute the value of global GV.
""",
ins=GV, outs=addr)
# A specialized form of global_addr instructions that only handles
# A specialized form of global_value instructions that only handles
# symbolic names.
globalsym_addr = Instruction(
'globalsym_addr', r"""
Compute the address of global variable GV, which is a symbolic name.
Compute the address of global GV, which is a symbolic name.
""",
ins=GV, outs=addr)

View File

@@ -62,7 +62,7 @@ expand_flags = XFormGroup('expand_flags', """
# Custom expansions for memory objects.
expand.custom_legalize(insts.global_addr, 'expand_global_addr')
expand.custom_legalize(insts.global_value, 'expand_global_value')
expand.custom_legalize(insts.heap_addr, 'expand_heap_addr')
# Custom expansions for calls.

View File

@@ -2,7 +2,7 @@
Cretonne predicates that consider `Function` fields.
"""
from cdsl.predicates import FieldPredicate
from .formats import UnaryGlobalVar, InstructionFormat
from .formats import UnaryGlobalValue, InstructionFormat
try:
from typing import TYPE_CHECKING
@@ -32,7 +32,7 @@ class IsColocatedData(FieldPredicate):
def __init__(self):
# type: () -> None
super(IsColocatedData, self).__init__(
UnaryGlobalVar.global_var, 'is_colocated_data', ('func',))
UnaryGlobalValue.global_value, 'is_colocated_data', ('func',))
class LengthEquals(FieldPredicate):

View File

@@ -53,7 +53,7 @@ call_conv = EnumSetting(
# Note that Cretonne doesn't currently need an is_pie flag, because PIE is just
# PIC where symbols can't be pre-empted, which can be expressed with the
# `colocated` flag on external functions and global variables.
# `colocated` flag on external functions and global valueiables.
is_pic = BoolSetting("Enable Position-Independent Code generation")
colocated_libcalls = BoolSetting(

View File

@@ -208,7 +208,7 @@ class InstructionFormat(object):
"""
Given a dict mapping name -> object as returned by `globals()`, find
all the InstructionFormat objects and set their name from the dict key.
This is used to name a bunch of global variables in a module.
This is used to name a bunch of global valueiables in a module.
"""
for name, obj in globs.items():
if isinstance(obj, InstructionFormat):

View File

@@ -365,7 +365,7 @@ class RegClass(object):
"""
Given a dict mapping name -> object as returned by `globals()`, find
all the RegClass objects and set their name from the dict key.
This is used to name a bunch of global variables in a module.
This is used to name a bunch of global valueiables in a module.
"""
for name, obj in globs.items():
if isinstance(obj, RegClass):

View File

@@ -14,7 +14,7 @@ from base.formats import IntCompare, IntCompareImm, FloatCompare
from base.formats import IntCond, FloatCond
from base.formats import IntSelect, IntCondTrap, FloatCondTrap
from base.formats import Jump, Branch, BranchInt, BranchFloat
from base.formats import Ternary, FuncAddr, UnaryGlobalVar
from base.formats import Ternary, FuncAddr, UnaryGlobalValue
from base.formats import RegMove, RegSpill, RegFill, CopySpecial
from base.formats import LoadComplex, StoreComplex
from .registers import GPR, ABCD, FPR, GPR_DEREF_SAFE, GPR_ZERO_DEREF_SAFE
@@ -703,50 +703,50 @@ got_fnaddr8 = TailRecipe(
# XX+rd id with Abs4 globalsym relocation.
gvaddr4 = TailRecipe(
'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR,
'gvaddr4', UnaryGlobalValue, size=4, ins=(), outs=GPR,
emit='''
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(Reloc::Abs4,
&func.global_vars[global_var].symbol_name(),
&func.global_values[global_value].symbol_name(),
0);
sink.put4(0);
''')
# XX+rd iq with Abs8 globalsym relocation.
gvaddr8 = TailRecipe(
'gvaddr8', UnaryGlobalVar, size=8, ins=(), outs=GPR,
'gvaddr8', UnaryGlobalValue, size=8, ins=(), outs=GPR,
emit='''
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(Reloc::Abs8,
&func.global_vars[global_var].symbol_name(),
&func.global_values[global_value].symbol_name(),
0);
sink.put8(0);
''')
# XX+rd iq with PCRel4 globalsym relocation.
pcrel_gvaddr8 = TailRecipe(
'pcrel_gvaddr8', UnaryGlobalVar, size=5, ins=(), outs=GPR,
'pcrel_gvaddr8', UnaryGlobalValue, size=5, ins=(), outs=GPR,
emit='''
PUT_OP(bits, rex2(0, out_reg0), sink);
modrm_rm(5, out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(Reloc::X86PCRel4,
&func.global_vars[global_var].symbol_name(),
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);
''')
# XX+rd iq with Abs8 globalsym relocation.
got_gvaddr8 = TailRecipe(
'got_gvaddr8', UnaryGlobalVar, size=5, ins=(), outs=GPR,
'got_gvaddr8', UnaryGlobalValue, size=5, ins=(), outs=GPR,
emit='''
PUT_OP(bits, rex2(0, out_reg0), sink);
modrm_rm(5, out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(Reloc::X86GOTPCRel4,
&func.global_vars[global_var].symbol_name(),
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);
''')

View File

@@ -82,18 +82,18 @@ impl StackSlot {
}
}
/// An opaque reference to a global variable.
/// An opaque reference to a global valueiable.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct GlobalVar(u32);
entity_impl!(GlobalVar, "gv");
pub struct GlobalValue(u32);
entity_impl!(GlobalValue, "gv");
impl GlobalVar {
/// Create a new global variable reference from its number.
impl GlobalValue {
/// Create a new global valueiable reference from its number.
///
/// This method is for use by the parser.
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(GlobalVar(n))
Some(GlobalValue(n))
} else {
None
}
@@ -186,7 +186,7 @@ pub enum AnyEntity {
/// A stack slot.
StackSlot(StackSlot),
/// A Global variable.
GlobalVar(GlobalVar),
GlobalValue(GlobalValue),
/// A jump table.
JumpTable(JumpTable),
/// An external function.
@@ -205,7 +205,7 @@ impl fmt::Display for AnyEntity {
AnyEntity::Inst(r) => r.fmt(f),
AnyEntity::Value(r) => r.fmt(f),
AnyEntity::StackSlot(r) => r.fmt(f),
AnyEntity::GlobalVar(r) => r.fmt(f),
AnyEntity::GlobalValue(r) => r.fmt(f),
AnyEntity::JumpTable(r) => r.fmt(f),
AnyEntity::FuncRef(r) => r.fmt(f),
AnyEntity::SigRef(r) => r.fmt(f),
@@ -244,9 +244,9 @@ impl From<StackSlot> for AnyEntity {
}
}
impl From<GlobalVar> for AnyEntity {
fn from(r: GlobalVar) -> Self {
AnyEntity::GlobalVar(r)
impl From<GlobalValue> for AnyEntity {
fn from(r: GlobalValue) -> Self {
AnyEntity::GlobalValue(r)
}
}

View File

@@ -284,7 +284,7 @@ pub enum ArgumentPurpose {
/// A VM context pointer.
///
/// This is a pointer to a context struct containing details about the current sandbox. It is
/// used as a base pointer for `vmctx` global variables.
/// used as a base pointer for `vmctx` global valueiables.
VMContext,
/// A signature identifier.

View File

@@ -7,7 +7,7 @@ use binemit::CodeOffset;
use entity::{EntityMap, PrimaryMap};
use ir;
use ir::{DataFlowGraph, ExternalName, Layout, Signature};
use ir::{Ebb, ExtFuncData, FuncRef, GlobalVar, GlobalVarData, Heap, HeapData, JumpTable,
use ir::{Ebb, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap, HeapData, JumpTable,
JumpTableData, SigRef, StackSlot, StackSlotData};
use ir::{EbbOffsets, InstEncodings, JumpTables, SourceLocs, StackSlots, ValueLocations};
use isa::{EncInfo, Encoding, Legalize, TargetIsa};
@@ -32,10 +32,10 @@ pub struct Function {
/// If not `None`, represents the address that the stack pointer should
/// be checked against.
pub stack_limit: Option<ir::GlobalVar>,
pub stack_limit: Option<ir::GlobalValue>,
/// Global variables referenced.
pub global_vars: PrimaryMap<ir::GlobalVar, ir::GlobalVarData>,
pub global_values: PrimaryMap<ir::GlobalValue, ir::GlobalValueData>,
/// Heaps referenced.
pub heaps: PrimaryMap<ir::Heap, ir::HeapData>,
@@ -78,7 +78,7 @@ impl Function {
signature: sig,
stack_slots: StackSlots::new(),
stack_limit: None,
global_vars: PrimaryMap::new(),
global_values: PrimaryMap::new(),
heaps: PrimaryMap::new(),
jump_tables: PrimaryMap::new(),
dfg: DataFlowGraph::new(),
@@ -94,7 +94,7 @@ impl Function {
pub fn clear(&mut self) {
self.signature.clear(CallConv::Fast);
self.stack_slots.clear();
self.global_vars.clear();
self.global_values.clear();
self.heaps.clear();
self.jump_tables.clear();
self.dfg.clear();
@@ -129,7 +129,7 @@ impl Function {
/// Sets the stack limit for the function.
///
/// Returns previous one if any.
pub fn set_stack_limit(&mut self, stack_limit: Option<GlobalVar>) -> Option<GlobalVar> {
pub fn set_stack_limit(&mut self, stack_limit: Option<GlobalValue>) -> Option<GlobalValue> {
let prev = self.stack_limit.take();
self.stack_limit = stack_limit;
prev
@@ -145,9 +145,9 @@ impl Function {
self.dfg.ext_funcs.push(data)
}
/// Declares a global variable accessible to the function.
pub fn create_global_var(&mut self, data: GlobalVarData) -> GlobalVar {
self.global_vars.push(data)
/// Declares a global valueiable accessible to the function.
pub fn create_global_value(&mut self, data: GlobalValueData) -> GlobalValue {
self.global_values.push(data)
}
/// Declares a heap accessible to the function.

View File

@@ -0,0 +1,70 @@
//! Global variables.
use ir::immediates::Offset32;
use ir::{ExternalName, GlobalValue};
use std::fmt;
/// Information about a global valueiable declaration.
#[derive(Clone)]
pub enum GlobalValueData {
/// Variable is part of the VM context struct, it's address is a constant offset from the VM
/// context pointer.
VMContext {
/// Offset from the `vmctx` pointer to this global.
offset: Offset32,
},
/// Variable is part of a struct pointed to by another global valueiable.
///
/// The `base` global valueiable is assumed to contain a pointer to a struct. This global
/// variable lives at an offset into the struct. The memory must be accessible, and
/// naturally aligned to hold a pointer value.
Deref {
/// The base pointer global valueiable.
base: GlobalValue,
/// Byte offset to be added to the pointer loaded from `base`.
offset: Offset32,
},
/// Variable is at an address identified by a symbolic name. Cretonne itself
/// does not interpret this name; it's used by embedders to link with other
/// data structures.
Sym {
/// The symbolic name.
name: ExternalName,
/// Will this variable 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.
colocated: bool,
},
}
impl GlobalValueData {
/// Assume that `self` is an `GlobalValueData::Sym` and return its name.
pub fn symbol_name(&self) -> &ExternalName {
match *self {
GlobalValueData::Sym { ref name, .. } => name,
_ => panic!("only symbols have names"),
}
}
}
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 { base, offset } => write!(f, "deref({}){}", base, offset),
GlobalValueData::Sym {
ref name,
colocated,
} => {
if colocated {
write!(f, "colocated ")?;
}
write!(f, "globalsym {}", name)
}
}
}
}

View File

@@ -1,12 +1,12 @@
//! Global variables.
use ir::immediates::Offset32;
use ir::{ExternalName, GlobalVar};
use ir::{ExternalName, GlobalValue};
use std::fmt;
/// Information about a global variable declaration.
/// Information about a global valueiable declaration.
#[derive(Clone)]
pub enum GlobalVarData {
pub enum GlobalValueData {
/// Variable is part of the VM context struct, it's address is a constant offset from the VM
/// context pointer.
VMContext {
@@ -14,14 +14,14 @@ pub enum GlobalVarData {
offset: Offset32,
},
/// Variable is part of a struct pointed to by another global variable.
/// Variable is part of a struct pointed to by another global valueiable.
///
/// The `base` global variable is assumed to contain a pointer to a struct. This global
/// The `base` global valueiable is assumed to contain a pointer to a struct. This global
/// variable lives at an offset into the struct. The memory must be accessible, and
/// naturally aligned to hold a pointer value.
Deref {
/// The base pointer global variable.
base: GlobalVar,
/// The base pointer global valueiable.
base: GlobalValue,
/// Byte offset to be added to the pointer loaded from `base`.
offset: Offset32,
@@ -41,22 +41,22 @@ pub enum GlobalVarData {
},
}
impl GlobalVarData {
/// Assume that `self` is an `GlobalVarData::Sym` and return its name.
impl GlobalValueData {
/// Assume that `self` is an `GlobalValueData::Sym` and return its name.
pub fn symbol_name(&self) -> &ExternalName {
match *self {
GlobalVarData::Sym { ref name, .. } => name,
GlobalValueData::Sym { ref name, .. } => name,
_ => panic!("only symbols have names"),
}
}
}
impl fmt::Display for GlobalVarData {
impl fmt::Display for GlobalValueData {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
GlobalVarData::VMContext { offset } => write!(f, "vmctx{}", offset),
GlobalVarData::Deref { base, offset } => write!(f, "deref({}){}", base, offset),
GlobalVarData::Sym {
GlobalValueData::VMContext { offset } => write!(f, "vmctx{}", offset),
GlobalValueData::Deref { base, offset } => write!(f, "deref({}){}", base, offset),
GlobalValueData::Sym {
ref name,
colocated,
} => {

View File

@@ -1,7 +1,7 @@
//! Heaps.
use ir::immediates::Imm64;
use ir::GlobalVar;
use ir::GlobalValue;
use std::fmt;
/// Information about a heap declaration.
@@ -29,9 +29,9 @@ pub enum HeapBase {
/// This feature is not yet implemented.
ReservedReg,
/// The heap base is in a global variable. The variable must be accessible and naturally
/// The heap base is in a global valueiable. The variable must be accessible and naturally
/// aligned for a pointer.
GlobalVar(GlobalVar),
GlobalValue(GlobalValue),
}
/// Style of heap including style-specific information.
@@ -41,7 +41,7 @@ pub enum HeapStyle {
Dynamic {
/// Global variable holding the current bound of the heap in bytes. It is
/// required to be accessible and naturally aligned for a pointer-sized integer.
bound_gv: GlobalVar,
bound_gv: GlobalValue,
},
/// A static heap has a fixed base address and a number of not-yet-allocated pages before the
@@ -61,7 +61,7 @@ impl fmt::Display for HeapData {
match self.base {
HeapBase::ReservedReg => write!(f, " reserved_reg")?,
HeapBase::GlobalVar(gv) => write!(f, " {}", gv)?,
HeapBase::GlobalValue(gv) => write!(f, " {}", gv)?,
}
write!(f, ", min {}", self.min_size)?;

View File

@@ -7,7 +7,7 @@ pub mod entities;
mod extfunc;
mod extname;
pub mod function;
mod globalvar;
mod globalvalue;
mod heap;
pub mod immediates;
pub mod instructions;
@@ -24,11 +24,11 @@ mod valueloc;
pub use ir::builder::{InsertBuilder, InstBuilder, InstBuilderBase, InstInserterBase};
pub use ir::dfg::{DataFlowGraph, ValueDef};
pub use ir::entities::{Ebb, FuncRef, GlobalVar, Heap, Inst, JumpTable, SigRef, StackSlot, Value};
pub use ir::entities::{Ebb, FuncRef, GlobalValue, Heap, Inst, JumpTable, SigRef, StackSlot, Value};
pub use ir::extfunc::{AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature};
pub use ir::extname::ExternalName;
pub use ir::function::Function;
pub use ir::globalvar::GlobalVarData;
pub use ir::globalvalue::GlobalValueData;
pub use ir::heap::{HeapBase, HeapData, HeapStyle};
pub use ir::instructions::{InstructionData, Opcode, ValueList, ValueListPool, VariableArgs};
pub use ir::jumptable::JumpTableData;

View File

@@ -1,15 +1,15 @@
//! Legalization of global variables.
//! Legalization of global valueiables.
//!
//! This module exports the `expand_global_addr` function which transforms a `global_addr`
//! instruction into code that depends on the kind of global variable referenced.
//! This module exports the `expand_global_value` function which transforms a `global_value`
//! instruction into code that depends on the kind of global valueiable referenced.
use cursor::{Cursor, FuncCursor};
use flowgraph::ControlFlowGraph;
use ir::{self, InstBuilder};
use isa::TargetIsa;
/// Expand a `global_addr` instruction according to the definition of the global variable.
pub fn expand_global_addr(
/// Expand a `global_value` instruction according to the definition of the global valueiable.
pub fn expand_global_value(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
@@ -17,40 +17,43 @@ pub fn expand_global_addr(
) {
// Unpack the instruction.
let gv = match func.dfg[inst] {
ir::InstructionData::UnaryGlobalVar { opcode, global_var } => {
debug_assert_eq!(opcode, ir::Opcode::GlobalAddr);
global_var
ir::InstructionData::UnaryGlobalValue {
opcode,
global_value,
} => {
debug_assert_eq!(opcode, ir::Opcode::GlobalValue);
global_value
}
_ => panic!("Wanted global_addr: {}", func.dfg.display_inst(inst, None)),
_ => panic!("Wanted global_value: {}", func.dfg.display_inst(inst, None)),
};
match func.global_vars[gv] {
ir::GlobalVarData::VMContext { offset } => vmctx_addr(inst, func, offset.into()),
ir::GlobalVarData::Deref { base, offset } => deref_addr(inst, func, base, offset.into()),
ir::GlobalVarData::Sym { .. } => globalsym(inst, func, gv),
match func.global_values[gv] {
ir::GlobalValueData::VMContext { offset } => vmctx_addr(inst, func, offset.into()),
ir::GlobalValueData::Deref { base, offset } => deref_addr(inst, func, base, offset.into()),
ir::GlobalValueData::Sym { .. } => globalsym(inst, func, gv),
}
}
/// Expand a `global_addr` instruction for a vmctx global.
/// Expand a `global_value` instruction for a vmctx global.
fn vmctx_addr(inst: ir::Inst, func: &mut ir::Function, offset: i64) {
// Get the value representing the `vmctx` argument.
let vmctx = func.special_param(ir::ArgumentPurpose::VMContext)
.expect("Missing vmctx parameter");
// Simply replace the `global_addr` instruction with an `iadd_imm`, reusing the result value.
// Simply replace the `global_value` instruction with an `iadd_imm`, reusing the result value.
func.dfg.replace(inst).iadd_imm(vmctx, offset);
}
/// Expand a `global_addr` instruction for a deref global.
fn deref_addr(inst: ir::Inst, func: &mut ir::Function, base: ir::GlobalVar, offset: i64) {
// We need to load a pointer from the `base` global variable, so insert a new `global_addr`
/// Expand a `global_value` instruction for a deref global.
fn deref_addr(inst: ir::Inst, func: &mut ir::Function, base: ir::GlobalValue, offset: i64) {
// We need to load a pointer from the `base` global valueiable, so insert a new `global_value`
// instruction. This depends on the iterative legalization loop. Note that the IR verifier
// detects any cycles in the `deref` globals.
let ptr_ty = func.dfg.value_type(func.dfg.first_result(inst));
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let base_addr = pos.ins().global_addr(ptr_ty, base);
let base_addr = pos.ins().global_value(ptr_ty, base);
let mut mflags = ir::MemFlags::new();
// Deref globals are required to be accessible and aligned.
mflags.set_notrap();
@@ -59,8 +62,8 @@ fn deref_addr(inst: ir::Inst, func: &mut ir::Function, base: ir::GlobalVar, offs
pos.func.dfg.replace(inst).iadd_imm(base_ptr, offset);
}
/// Expand a `global_addr` instruction for a symbolic name global.
fn globalsym(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalVar) {
/// Expand a `global_value` instruction for a symbolic name global.
fn globalsym(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalValue) {
let ptr_ty = func.dfg.value_type(func.dfg.first_result(inst));
func.dfg.replace(inst).globalsym_addr(ptr_ty, gv);
}

View File

@@ -46,7 +46,7 @@ fn dynamic_addr(
heap: ir::Heap,
offset: ir::Value,
size: u32,
bound_gv: ir::GlobalVar,
bound_gv: ir::GlobalValue,
func: &mut ir::Function,
) {
let size = i64::from(size);
@@ -57,7 +57,7 @@ fn dynamic_addr(
pos.use_srcloc(inst);
// Start with the bounds check. Trap if `offset + size > bound`.
let bound_addr = pos.ins().global_addr(addr_ty, bound_gv);
let bound_addr = pos.ins().global_value(addr_ty, bound_gv);
let mut mflags = MemFlags::new();
// The bound variable is requied to be accessible and aligned.
mflags.set_notrap();
@@ -162,8 +162,8 @@ fn offset_addr(
// Add the heap base address base
match pos.func.heaps[heap].base {
ir::HeapBase::ReservedReg => unimplemented!(),
ir::HeapBase::GlobalVar(base_gv) => {
let base_addr = pos.ins().global_addr(addr_ty, base_gv);
ir::HeapBase::GlobalValue(base_gv) => {
let base_addr = pos.ins().global_value(addr_ty, base_gv);
let mut mflags = MemFlags::new();
// The base address variable is requied to be accessible and aligned.
mflags.set_notrap();

View File

@@ -22,13 +22,13 @@ use timing;
mod boundary;
mod call;
mod globalvar;
mod globalvalue;
mod heap;
mod libcall;
mod split;
use self::call::expand_call;
use self::globalvar::expand_global_addr;
use self::globalvalue::expand_global_value;
use self::heap::expand_heap_addr;
use self::libcall::expand_as_libcall;

View File

@@ -53,9 +53,9 @@ pub fn is_colocated_func(func_ref: ir::FuncRef, func: &ir::Function) -> bool {
}
#[allow(dead_code)]
pub fn is_colocated_data(global_var: ir::GlobalVar, func: &ir::Function) -> bool {
match func.global_vars[global_var] {
ir::GlobalVarData::Sym { colocated, .. } => colocated,
pub fn is_colocated_data(global_value: ir::GlobalValue, func: &ir::Function) -> bool {
match func.global_values[global_value] {
ir::GlobalValueData::Sym { colocated, .. } => colocated,
_ => panic!("is_colocated_data only makes sense for data with symbolic addresses"),
}
}

View File

@@ -777,7 +777,7 @@ impl Solver {
if is_global {
let mut new_var = Variable::new_live(value, rc, reg, true);
new_var.is_global = true;
dbg!("add_tied_input: new tied-global var: {}", new_var);
dbg!("add_tied_input: new tied-global value: {}", new_var);
self.vars.push(new_var);
self.regs_in.free(rc, reg);
} else {
@@ -920,7 +920,7 @@ impl Solver {
Some(reg) => reg,
None => {
// If `v` must avoid global interference, there is not point in requesting
// live registers be diverted. We need to make it a non-global variable.
// live registers be diverted. We need to make it a non-global valueiable.
if v.is_global && gregs.iter(rc).next().is_none() {
return Err(SolverError::Global(v.value));
} else {

View File

@@ -63,7 +63,7 @@ use flowgraph::ControlFlowGraph;
use ir;
use ir::entities::AnyEntity;
use ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint};
use ir::{types, ArgumentLoc, Ebb, FuncRef, Function, GlobalVar, Inst, JumpTable, Opcode, SigRef,
use ir::{types, ArgumentLoc, Ebb, FuncRef, Function, GlobalValue, Inst, JumpTable, Opcode, SigRef,
StackSlot, StackSlotKind, Type, Value, ValueDef, ValueList, ValueLoc};
use isa::TargetIsa;
use iterators::IteratorExtras;
@@ -168,16 +168,16 @@ impl<'a> Verifier<'a> {
}
}
// Check for cycles in the global variable declarations.
fn verify_global_vars(&self) -> VerifierResult<()> {
// Check for cycles in the global valueiable declarations.
fn verify_global_values(&self) -> VerifierResult<()> {
let mut seen = SparseSet::new();
for gv in self.func.global_vars.keys() {
for gv in self.func.global_values.keys() {
seen.clear();
seen.insert(gv);
let mut cur = gv;
while let ir::GlobalVarData::Deref { base, .. } = self.func.global_vars[cur] {
while let ir::GlobalValueData::Deref { base, .. } = self.func.global_values[cur] {
if seen.insert(base).is_some() {
return err!(gv, "deref cycle: {}", DisplayList(seen.as_slice()));
}
@@ -327,8 +327,8 @@ impl<'a> Verifier<'a> {
StackLoad { stack_slot, .. } | StackStore { stack_slot, .. } => {
self.verify_stack_slot(inst, stack_slot)?;
}
UnaryGlobalVar { global_var, .. } => {
self.verify_global_var(inst, global_var)?;
UnaryGlobalValue { global_value, .. } => {
self.verify_global_value(inst, global_value)?;
}
HeapAddr { heap, .. } => {
self.verify_heap(inst, heap)?;
@@ -413,9 +413,9 @@ impl<'a> Verifier<'a> {
}
}
fn verify_global_var(&self, inst: Inst, gv: GlobalVar) -> VerifierResult<()> {
if !self.func.global_vars.is_valid(gv) {
err!(inst, "invalid global variable {}", gv)
fn verify_global_value(&self, inst: Inst, gv: GlobalValue) -> VerifierResult<()> {
if !self.func.global_values.is_valid(gv) {
err!(inst, "invalid global valueiable {}", gv)
} else {
Ok(())
}
@@ -1124,7 +1124,7 @@ impl<'a> Verifier<'a> {
}
pub fn run(&self) -> VerifierResult<()> {
self.verify_global_vars()?;
self.verify_global_values()?;
self.typecheck_entry_block_params()?;
for ebb in self.func.layout.ebbs() {
for inst in self.func.layout.ebb_insts(ebb) {

View File

@@ -49,7 +49,7 @@ fn write_preamble(
writeln!(w, " {} = {}", ss, slot)?;
}
for (gv, gv_data) in &func.global_vars {
for (gv, gv_data) in &func.global_values {
any = true;
writeln!(w, " {} = {}", gv, gv_data)?;
}
@@ -285,7 +285,7 @@ pub fn write_operands(
UnaryIeee32 { imm, .. } => write!(w, " {}", imm),
UnaryIeee64 { imm, .. } => write!(w, " {}", imm),
UnaryBool { imm, .. } => write!(w, " {}", imm),
UnaryGlobalVar { global_var, .. } => write!(w, " {}", global_var),
UnaryGlobalValue { global_value, .. } => write!(w, " {}", global_value),
Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]),
BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm),
Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]),

View File

@@ -266,7 +266,7 @@ impl Backend for FaerieBackend {
&mut self,
_data: &mut FaerieCompiledData,
_offset: usize,
_what: ir::GlobalVar,
_what: ir::GlobalValue,
_usize: binemit::Addend,
) {
unimplemented!()

View File

@@ -3,10 +3,10 @@ use cretonne_codegen::cursor::{Cursor, FuncCursor};
use cretonne_codegen::entity::{EntityMap, EntityRef, EntitySet};
use cretonne_codegen::ir;
use cretonne_codegen::ir::function::DisplayFunction;
use cretonne_codegen::ir::{DataFlowGraph, Ebb, ExtFuncData, FuncRef, Function, GlobalVar,
GlobalVarData, Heap, HeapData, Inst, InstBuilderBase, InstructionData,
JumpTable, JumpTableData, SigRef, Signature, StackSlot, StackSlotData,
Type, Value};
use cretonne_codegen::ir::{DataFlowGraph, Ebb, ExtFuncData, FuncRef, Function, GlobalValue,
GlobalValueData, Heap, HeapData, Inst, InstBuilderBase,
InstructionData, JumpTable, JumpTableData, SigRef, Signature,
StackSlot, StackSlotData, Type, Value};
use cretonne_codegen::isa::TargetIsa;
use cretonne_codegen::packed_option::PackedOption;
use ssa::{Block, SSABuilder, SideEffects};
@@ -377,9 +377,9 @@ where
self.func.import_function(data)
}
/// Declares a global variable accessible to the function.
pub fn create_global_var(&mut self, data: GlobalVarData) -> GlobalVar {
self.func.create_global_var(data)
/// Declares a global valueiable accessible to the function.
pub fn create_global_value(&mut self, data: GlobalValueData) -> GlobalValue {
self.func.create_global_value(data)
}
/// Declares a heap accessible to the function.

View File

@@ -84,7 +84,7 @@ where
&mut self,
data: &mut Self::CompiledData,
offset: usize,
what: ir::GlobalVar,
what: ir::GlobalValue,
addend: binemit::Addend,
);

View File

@@ -52,11 +52,11 @@ pub struct DataDescription {
/// External function declarations.
pub function_decls: PrimaryMap<ir::FuncRef, ir::ExternalName>,
/// External data object declarations.
pub data_decls: PrimaryMap<ir::GlobalVar, ir::ExternalName>,
pub data_decls: PrimaryMap<ir::GlobalValue, ir::ExternalName>,
/// Function addresses to write at specified offsets.
pub function_relocs: Vec<(CodeOffset, ir::FuncRef)>,
/// Data addresses to write at specified offsets.
pub data_relocs: Vec<(CodeOffset, ir::GlobalVar, Addend)>,
pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>,
}
/// This is to data objects what cretonne_codegen::Context is to functions.
@@ -114,14 +114,14 @@ impl DataContext {
self.description.function_decls.push(name)
}
/// Declares a global variable import.
/// Declares a global valueiable import.
///
/// TODO: Rename to import_data?
///
/// Users of the `Module` API generally should call
/// `Module::declare_data_in_data` instead, as it takes care of generating
/// the appropriate `ExternalName`.
pub fn import_global_var(&mut self, name: ir::ExternalName) -> ir::GlobalVar {
pub fn import_global_value(&mut self, name: ir::ExternalName) -> ir::GlobalValue {
self.description.data_decls.push(name)
}
@@ -131,7 +131,7 @@ impl DataContext {
}
/// Write the address of `data` into the data at offset `offset`.
pub fn write_data_addr(&mut self, offset: CodeOffset, data: ir::GlobalVar, addend: Addend) {
pub fn write_data_addr(&mut self, offset: CodeOffset, data: ir::GlobalValue, addend: Addend) {
self.description.data_relocs.push((offset, data, addend))
}
@@ -168,8 +168,8 @@ mod tests {
let _func_a = data_ctx.import_function(ir::ExternalName::user(0, 0));
let func_b = data_ctx.import_function(ir::ExternalName::user(0, 1));
let func_c = data_ctx.import_function(ir::ExternalName::user(1, 0));
let _data_a = data_ctx.import_global_var(ir::ExternalName::user(2, 2));
let data_b = data_ctx.import_global_var(ir::ExternalName::user(2, 3));
let _data_a = data_ctx.import_global_value(ir::ExternalName::user(2, 2));
let data_b = data_ctx.import_global_value(ir::ExternalName::user(2, 3));
data_ctx.write_function_addr(8, func_b);
data_ctx.write_function_addr(16, func_c);

View File

@@ -2,7 +2,7 @@
// TODO: Should `ir::Function` really have a `name`?
// TODO: Factor out `ir::Function`'s `ext_funcs` and `global_vars` into a struct
// TODO: Factor out `ir::Function`'s `ext_funcs` and `global_values` into a struct
// shared with `DataContext`?
use cretonne_codegen::entity::{EntityRef, PrimaryMap};
@@ -440,10 +440,10 @@ where
/// Use this when you're building the IR of a function to reference a data object.
///
/// TODO: Same as above.
pub fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalVar {
pub fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
let decl = &self.contents.data_objects[data].decl;
let colocated = decl.linkage.is_final();
func.create_global_var(ir::GlobalVarData::Sym {
func.create_global_value(ir::GlobalValueData::Sym {
name: ir::ExternalName::user(1, data.index() as u32),
colocated,
})
@@ -455,8 +455,8 @@ where
}
/// TODO: Same as above.
pub fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalVar {
ctx.import_global_var(ir::ExternalName::user(1, data.index() as u32))
pub fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalValue {
ctx.import_global_value(ir::ExternalName::user(1, data.index() as u32))
}
/// Define a function, producing the function body from the given `Context`.
@@ -536,7 +536,7 @@ where
&mut self,
data: DataId,
offset: usize,
what: ir::GlobalVar,
what: ir::GlobalValue,
addend: binemit::Addend,
) {
let info = &mut self.contents.data_objects[data];

View File

@@ -34,7 +34,7 @@ pub enum Token<'a> {
Value(Value), // v12, v7
Ebb(Ebb), // ebb3
StackSlot(u32), // ss3
GlobalVar(u32), // gv3
GlobalValue(u32), // gv3
Heap(u32), // heap2
JumpTable(u32), // jt2
FuncRef(u32), // fn2
@@ -338,7 +338,7 @@ impl<'a> Lexer<'a> {
"v" => Value::with_number(number).map(Token::Value),
"ebb" => Ebb::with_number(number).map(Token::Ebb),
"ss" => Some(Token::StackSlot(number)),
"gv" => Some(Token::GlobalVar(number)),
"gv" => Some(Token::GlobalValue(number)),
"heap" => Some(Token::Heap(number)),
"jt" => Some(Token::JumpTable(number)),
"fn" => Some(Token::FuncRef(number)),

View File

@@ -7,7 +7,7 @@ use cretonne_codegen::ir::immediates::{Ieee32, Ieee64, Imm64, Offset32, Uimm32};
use cretonne_codegen::ir::instructions::{InstructionData, InstructionFormat, VariableArgs};
use cretonne_codegen::ir::types::VOID;
use cretonne_codegen::ir::{AbiParam, ArgumentExtension, ArgumentLoc, Ebb, ExtFuncData,
ExternalName, FuncRef, Function, GlobalVar, GlobalVarData, Heap,
ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Heap,
HeapBase, HeapData, HeapStyle, JumpTable, JumpTableData, MemFlags,
Opcode, SigRef, Signature, StackSlot, StackSlotData, StackSlotKind,
Type, Value, ValueLoc};
@@ -139,22 +139,27 @@ impl<'a> Context<'a> {
}
}
// Allocate a global variable slot.
fn add_gv(&mut self, gv: GlobalVar, data: GlobalVarData, loc: &Location) -> ParseResult<()> {
while self.function.global_vars.next_key().index() <= gv.index() {
self.function.create_global_var(GlobalVarData::Sym {
// Allocate a global valueiable slot.
fn add_gv(
&mut self,
gv: GlobalValue,
data: GlobalValueData,
loc: &Location,
) -> ParseResult<()> {
while self.function.global_values.next_key().index() <= gv.index() {
self.function.create_global_value(GlobalValueData::Sym {
name: ExternalName::testcase(""),
colocated: false,
});
}
self.function.global_vars[gv] = data;
self.function.global_values[gv] = data;
self.map.def_gv(gv, loc)
}
// Resolve a reference to a global variable.
fn check_gv(&self, gv: GlobalVar, loc: &Location) -> ParseResult<()> {
// Resolve a reference to a global valueiable.
fn check_gv(&self, gv: GlobalValue, loc: &Location) -> ParseResult<()> {
if !self.map.contains_gv(gv) {
err!(loc, "undefined global variable {}", gv)
err!(loc, "undefined global valueiable {}", gv)
} else {
Ok(())
}
@@ -245,7 +250,7 @@ impl<'a> Context<'a> {
}
// Assign the global for the stack limit.
fn set_stack_limit(&mut self, gv: GlobalVar, loc: &Location) -> ParseResult<()> {
fn set_stack_limit(&mut self, gv: GlobalValue, loc: &Location) -> ParseResult<()> {
if let Some(_) = self.function.set_stack_limit(Some(gv)) {
err!(loc, "multiple stack_limit declarations")
} else {
@@ -396,11 +401,11 @@ impl<'a> Parser<'a> {
err!(self.loc, err_msg)
}
// Match and consume a global variable reference.
fn match_gv(&mut self, err_msg: &str) -> ParseResult<GlobalVar> {
if let Some(Token::GlobalVar(gv)) = self.token() {
// Match and consume a global valueiable reference.
fn match_gv(&mut self, err_msg: &str) -> ParseResult<GlobalValue> {
if let Some(Token::GlobalValue(gv)) = self.token() {
self.consume();
if let Some(gv) = GlobalVar::with_number(gv) {
if let Some(gv) = GlobalValue::with_number(gv) {
return Ok(gv);
}
}
@@ -1000,9 +1005,9 @@ impl<'a> Parser<'a> {
self.parse_stack_slot_decl()
.and_then(|(ss, dat)| ctx.add_ss(ss, dat, &loc))
}
Some(Token::GlobalVar(..)) => {
Some(Token::GlobalValue(..)) => {
self.start_gathering_comments();
self.parse_global_var_decl()
self.parse_global_value_decl()
.and_then(|(gv, dat)| ctx.add_gv(gv, dat, &self.loc))
}
Some(Token::Heap(..)) => {
@@ -1072,36 +1077,45 @@ impl<'a> Parser<'a> {
Ok((ss, data))
}
// Parse a global variable decl.
// Parse a global valueiable decl.
//
// global-var-decl ::= * GlobalVar(gv) "=" global-var-desc
// global-var-decl ::= * GlobalValue(gv) "=" global-var-desc
// global-var-desc ::= "vmctx" offset32
// | "deref" "(" GlobalVar(base) ")" offset32
// | "deref" "(" GlobalValue(base) ")" offset32
// | globalsym ["colocated"] name
//
fn parse_global_var_decl(&mut self) -> ParseResult<(GlobalVar, GlobalVarData)> {
let gv = self.match_gv("expected global variable number: gv«n»")?;
fn parse_global_value_decl(&mut self) -> ParseResult<(GlobalValue, GlobalValueData)> {
let gv = self.match_gv("expected global valueiable number: gv«n»")?;
self.match_token(Token::Equal, "expected '=' in global variable declaration")?;
self.match_token(
Token::Equal,
"expected '=' in global valueiable declaration",
)?;
let data = match self.match_any_identifier("expected global variable kind")? {
let data = match self.match_any_identifier("expected global valueiable kind")? {
"vmctx" => {
let offset = self.optional_offset32()?;
GlobalVarData::VMContext { offset }
GlobalValueData::VMContext { offset }
}
"deref" => {
self.match_token(Token::LPar, "expected '(' in 'deref' global variable decl")?;
let base = self.match_gv("expected global variable: gv«n»")?;
self.match_token(Token::RPar, "expected ')' in 'deref' global variable decl")?;
self.match_token(
Token::LPar,
"expected '(' in 'deref' global valueiable decl",
)?;
let base = self.match_gv("expected global valueiable: gv«n»")?;
self.match_token(
Token::RPar,
"expected ')' in 'deref' global valueiable decl",
)?;
let offset = self.optional_offset32()?;
GlobalVarData::Deref { base, offset }
GlobalValueData::Deref { base, offset }
}
"globalsym" => {
let colocated = self.optional(Token::Identifier("colocated"));
let name = self.parse_external_name()?;
GlobalVarData::Sym { name, colocated }
GlobalValueData::Sym { name, colocated }
}
other => return err!(self.loc, "Unknown global variable kind '{}'", other),
other => return err!(self.loc, "Unknown global valueiable kind '{}'", other),
};
// Collect any trailing comments.
@@ -1117,7 +1131,7 @@ impl<'a> Parser<'a> {
// heap-desc ::= heap-style heap-base { "," heap-attr }
// heap-style ::= "static" | "dynamic"
// heap-base ::= "reserved_reg"
// | GlobalVar(base)
// | GlobalValue(base)
// heap-attr ::= "min" Imm64(bytes)
// | "max" Imm64(bytes)
// | "guard" Imm64(bytes)
@@ -1130,15 +1144,15 @@ impl<'a> Parser<'a> {
// heap-desc ::= heap-style * heap-base { "," heap-attr }
// heap-base ::= * "reserved_reg"
// | * GlobalVar(base)
// | * GlobalValue(base)
let base = match self.token() {
Some(Token::Identifier("reserved_reg")) => HeapBase::ReservedReg,
Some(Token::GlobalVar(base_num)) => {
let base_gv = match GlobalVar::with_number(base_num) {
Some(Token::GlobalValue(base_num)) => {
let base_gv = match GlobalValue::with_number(base_num) {
Some(gv) => gv,
None => return err!(self.loc, "invalid global variable number for heap base"),
None => return err!(self.loc, "invalid global valueiable number for heap base"),
};
HeapBase::GlobalVar(base_gv)
HeapBase::GlobalValue(base_gv)
}
_ => return err!(self.loc, "expected heap base"),
};
@@ -1309,11 +1323,11 @@ impl<'a> Parser<'a> {
}
}
/// stack-limit-decl ::= "stack_limit" "=" GlobalVar(gv)
fn parse_stack_limit_decl(&mut self) -> ParseResult<GlobalVar> {
/// stack-limit-decl ::= "stack_limit" "=" GlobalValue(gv)
fn parse_stack_limit_decl(&mut self) -> ParseResult<GlobalValue> {
self.consume();
self.match_token(Token::Equal, "expected '=' in stack limit declaration")?;
let gv = self.match_gv("expected global variable")?;
let gv = self.match_gv("expected global valueiable")?;
Ok(gv)
}
@@ -1889,12 +1903,12 @@ impl<'a> Parser<'a> {
opcode,
imm: self.match_bool("expected immediate boolean operand")?,
},
InstructionFormat::UnaryGlobalVar => {
let gv = self.match_gv("expected global variable")?;
InstructionFormat::UnaryGlobalValue => {
let gv = self.match_gv("expected global valueiable")?;
ctx.check_gv(gv, &self.loc)?;
InstructionData::UnaryGlobalVar {
InstructionData::UnaryGlobalValue {
opcode,
global_var: gv,
global_value: gv,
}
}
InstructionFormat::Binary => {

View File

@@ -7,7 +7,7 @@
//! to parser clients.
use cretonne_codegen::ir::entities::AnyEntity;
use cretonne_codegen::ir::{Ebb, FuncRef, GlobalVar, Heap, JumpTable, SigRef, StackSlot, Value};
use cretonne_codegen::ir::{Ebb, FuncRef, GlobalValue, Heap, JumpTable, SigRef, StackSlot, Value};
use error::{Location, ParseResult};
use lexer::split_entity_name;
use std::collections::HashMap;
@@ -36,8 +36,8 @@ impl SourceMap {
self.locations.contains_key(&ss.into())
}
/// Look up a global variable entity.
pub fn contains_gv(&self, gv: GlobalVar) -> bool {
/// Look up a global valueiable entity.
pub fn contains_gv(&self, gv: GlobalValue) -> bool {
self.locations.contains_key(&gv.into())
}
@@ -86,7 +86,7 @@ impl SourceMap {
Some(ss.into())
}
}),
"gv" => GlobalVar::with_number(num).and_then(|gv| {
"gv" => GlobalValue::with_number(num).and_then(|gv| {
if !self.contains_gv(gv) {
None
} else {
@@ -154,8 +154,8 @@ impl SourceMap {
self.def_entity(entity.into(), loc)
}
/// Define the global variable `entity`.
pub fn def_gv(&mut self, entity: GlobalVar, loc: &Location) -> ParseResult<()> {
/// Define the global valueiable `entity`.
pub fn def_gv(&mut self, entity: GlobalValue, loc: &Location) -> ParseResult<()> {
self.def_entity(entity.into(), loc)
}

View File

@@ -217,7 +217,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
&mut self,
_data: &mut Self::CompiledData,
_offset: usize,
_what: ir::GlobalVar,
_what: ir::GlobalValue,
_usize: Addend,
) {
unimplemented!();

View File

@@ -24,7 +24,7 @@ pub mod prelude {
pub use codegen::ir::condcodes::{FloatCC, IntCC};
pub use codegen::ir::immediates::{Ieee32, Ieee64, Imm64};
pub use codegen::ir::types;
pub use codegen::ir::{AbiParam, Ebb, ExtFuncData, GlobalVarData, InstBuilder, JumpTableData,
pub use codegen::ir::{AbiParam, Ebb, ExtFuncData, GlobalValueData, InstBuilder, JumpTableData,
MemFlags, Signature, StackSlotData, StackSlotKind, TrapCode, Type, Value};
pub use codegen::isa;
pub use codegen::settings::{self, CallConv, Configurable};

View File

@@ -74,7 +74,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let val = match state.get_global(builder.func, global_index, environ) {
GlobalValue::Const(val) => val,
GlobalValue::Memory { gv, ty } => {
let addr = builder.ins().global_addr(environ.native_pointer(), gv);
let addr = builder.ins().global_value(environ.native_pointer(), gv);
let mut flags = ir::MemFlags::new();
flags.set_notrap();
flags.set_aligned();
@@ -87,7 +87,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
match state.get_global(builder.func, global_index, environ) {
GlobalValue::Const(_) => panic!("global #{} is a constant", global_index),
GlobalValue::Memory { gv, .. } => {
let addr = builder.ins().global_addr(environ.native_pointer(), gv);
let addr = builder.ins().global_value(environ.native_pointer(), gv);
let mut flags = ir::MemFlags::new();
flags.set_notrap();
flags.set_aligned();

View File

@@ -159,7 +159,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalValue {
// Just create a dummy `vmctx` global.
let offset = ((index * 8) as i32 + 8).into();
let gv = func.create_global_var(ir::GlobalVarData::VMContext { offset });
let gv = func.create_global_value(ir::GlobalValueData::VMContext { offset });
GlobalValue::Memory {
gv,
ty: self.mod_info.globals[index].entity.ty,
@@ -168,10 +168,10 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> ir::Heap {
// Create a static heap whose base address is stored at `vmctx+0`.
let gv = func.create_global_var(ir::GlobalVarData::VMContext { offset: 0.into() });
let gv = func.create_global_value(ir::GlobalValueData::VMContext { offset: 0.into() });
func.create_heap(ir::HeapData {
base: ir::HeapBase::GlobalVar(gv),
base: ir::HeapBase::GlobalValue(gv),
min_size: 0.into(),
guard_size: 0x8000_0000.into(),
style: ir::HeapStyle::Static {

View File

@@ -9,17 +9,17 @@ use translation_utils::{FunctionIndex, Global, GlobalIndex, Memory, MemoryIndex,
Table, TableIndex};
use wasmparser::BinaryReaderError;
/// The value of a WebAssembly global variable.
/// The value of a WebAssembly global valueiable.
#[derive(Clone, Copy)]
pub enum GlobalValue {
/// This is a constant global with a value known at compile time.
Const(ir::Value),
/// This is a variable in memory that should be referenced as a `GlobalVar`.
/// This is a variable in memory that should be referenced as a `GlobalValue`.
Memory {
/// Which global variable should be referenced.
gv: ir::GlobalVar,
/// The global variable's type.
/// Which global valueiable should be referenced.
gv: ir::GlobalValue,
/// The global valueiable's type.
ty: ir::Type,
},
}
@@ -88,12 +88,12 @@ pub trait FuncEnvironment {
ir::Type::int(u16::from(self.triple().pointer_width().unwrap().bits())).unwrap()
}
/// Set up the necessary preamble definitions in `func` to access the global variable
/// Set up the necessary preamble definitions in `func` to access the global valueiable
/// identified by `index`.
///
/// The index space covers both imported globals and globals defined by the module.
///
/// Return the global variable reference that should be used to access the global and the
/// Return the global valueiable reference that should be used to access the global and the
/// WebAssembly type of the global.
fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalValue;

View File

@@ -4,7 +4,7 @@
//! The code of theses helper function is straightforward since it is only about reading metadata
//! about linear memories, tables, globals, etc. and storing them for later use.
//!
//! The special case of the initialize expressions for table elements offsets or global variables
//! The special case of the initialize expressions for table elements offsets or global valueiables
//! is handled, according to the semantics of WebAssembly, to only specific expressions that are
//! interpreted on the fly.
use cretonne_codegen::ir::{self, AbiParam, Signature};

View File

@@ -134,7 +134,7 @@ pub struct TranslationState {
pub control_stack: Vec<ControlStackFrame>,
pub reachable: bool,
// Map of global variables that have already been created by `FuncEnvironment::make_global`.
// Map of global valueiables that have already been created by `FuncEnvironment::make_global`.
globals: HashMap<GlobalIndex, GlobalValue>,
// Map of heaps that have been created by `FuncEnvironment::make_heap`.
@@ -272,7 +272,7 @@ impl TranslationState {
/// Methods for handling entity references.
impl TranslationState {
/// Get the `GlobalVar` reference that should be used to access the global variable `index`.
/// Get the `GlobalValue` reference that should be used to access the global valueiable `index`.
/// Create the reference if necessary.
/// Also return the WebAssembly type of the global.
pub fn get_global<FE: FuncEnvironment + ?Sized>(

View File

@@ -7,7 +7,7 @@ use wasmparser;
pub type FunctionIndex = usize;
/// Index of a table (imported or defined) inside the WebAssembly module.
pub type TableIndex = usize;
/// Index of a global variable (imported or defined) inside the WebAssembly module.
/// Index of a global valueiable (imported or defined) inside the WebAssembly module.
pub type GlobalIndex = usize;
/// Index of a linear memory (imported or defined) inside the WebAssembly module.
pub type MemoryIndex = usize;