diff --git a/cranelift/docs/compare-llvm.rst b/cranelift/docs/compare-llvm.rst index abc47caaa3..4765cdc18b 100644 --- a/cranelift/docs/compare-llvm.rst +++ b/cranelift/docs/compare-llvm.rst @@ -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 diff --git a/cranelift/docs/langref.rst b/cranelift/docs/langref.rst index e6d944dcd8..707927f454 100644 --- a/cranelift/docs/langref.rst +++ b/cranelift/docs/langref.rst @@ -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. diff --git a/cranelift/docs/metaref.rst b/cranelift/docs/metaref.rst index 134628a8b1..70cc5ecc98 100644 --- a/cranelift/docs/metaref.rst +++ b/cranelift/docs/metaref.rst @@ -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. diff --git a/cranelift/filetests/isa/x86/legalize-memory.cton b/cranelift/filetests/isa/x86/legalize-memory.cton index 9762aa1f6c..0a35c841ba 100644 --- a/cranelift/filetests/isa/x86/legalize-memory.cton +++ b/cranelift/filetests/isa/x86/legalize-memory.cton @@ -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 diff --git a/cranelift/filetests/parser/memory.cton b/cranelift/filetests/parser/memory.cton index 1b36071243..8e01eb8cae 100644 --- a/cranelift/filetests/parser/memory.cton +++ b/cranelift/filetests/parser/memory.cton @@ -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 } diff --git a/lib/codegen/meta/base/entities.py b/lib/codegen/meta/base/entities.py index 996913471b..e8915a0f79 100644 --- a/lib/codegen/meta/base/entities.py +++ b/lib/codegen/meta/base/entities.py @@ -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. diff --git a/lib/codegen/meta/base/formats.py b/lib/codegen/meta/base/formats.py index 817ac0a87d..1c0d7284f2 100644 --- a/lib/codegen/meta/base/formats.py +++ b/lib/codegen/meta/base/formats.py @@ -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()) diff --git a/lib/codegen/meta/base/instructions.py b/lib/codegen/meta/base/instructions.py index 485de44c5e..5efd344c6f 100644 --- a/lib/codegen/meta/base/instructions.py +++ b/lib/codegen/meta/base/instructions.py @@ -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) diff --git a/lib/codegen/meta/base/legalize.py b/lib/codegen/meta/base/legalize.py index ad396af747..de196cc645 100644 --- a/lib/codegen/meta/base/legalize.py +++ b/lib/codegen/meta/base/legalize.py @@ -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. diff --git a/lib/codegen/meta/base/predicates.py b/lib/codegen/meta/base/predicates.py index 44f135e0d3..16ea856138 100644 --- a/lib/codegen/meta/base/predicates.py +++ b/lib/codegen/meta/base/predicates.py @@ -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): diff --git a/lib/codegen/meta/base/settings.py b/lib/codegen/meta/base/settings.py index 8e88a45abc..c3f9ae182b 100644 --- a/lib/codegen/meta/base/settings.py +++ b/lib/codegen/meta/base/settings.py @@ -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( diff --git a/lib/codegen/meta/cdsl/formats.py b/lib/codegen/meta/cdsl/formats.py index c8dd58fc7f..ebee96281e 100644 --- a/lib/codegen/meta/cdsl/formats.py +++ b/lib/codegen/meta/cdsl/formats.py @@ -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): diff --git a/lib/codegen/meta/cdsl/registers.py b/lib/codegen/meta/cdsl/registers.py index 6f57e380d9..4dccbc808a 100644 --- a/lib/codegen/meta/cdsl/registers.py +++ b/lib/codegen/meta/cdsl/registers.py @@ -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): diff --git a/lib/codegen/meta/isa/x86/recipes.py b/lib/codegen/meta/isa/x86/recipes.py index 1caf6136d1..2d6ac898a4 100644 --- a/lib/codegen/meta/isa/x86/recipes.py +++ b/lib/codegen/meta/isa/x86/recipes.py @@ -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); ''') diff --git a/lib/codegen/src/ir/entities.rs b/lib/codegen/src/ir/entities.rs index 73e0984245..d6461d47df 100644 --- a/lib/codegen/src/ir/entities.rs +++ b/lib/codegen/src/ir/entities.rs @@ -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 { 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 for AnyEntity { } } -impl From for AnyEntity { - fn from(r: GlobalVar) -> Self { - AnyEntity::GlobalVar(r) +impl From for AnyEntity { + fn from(r: GlobalValue) -> Self { + AnyEntity::GlobalValue(r) } } diff --git a/lib/codegen/src/ir/extfunc.rs b/lib/codegen/src/ir/extfunc.rs index a4abc8bfc4..98b6e4fb40 100644 --- a/lib/codegen/src/ir/extfunc.rs +++ b/lib/codegen/src/ir/extfunc.rs @@ -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. diff --git a/lib/codegen/src/ir/function.rs b/lib/codegen/src/ir/function.rs index f7773f2258..5d59e6f3ce 100644 --- a/lib/codegen/src/ir/function.rs +++ b/lib/codegen/src/ir/function.rs @@ -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, + pub stack_limit: Option, /// Global variables referenced. - pub global_vars: PrimaryMap, + pub global_values: PrimaryMap, /// Heaps referenced. pub heaps: PrimaryMap, @@ -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) -> Option { + pub fn set_stack_limit(&mut self, stack_limit: Option) -> Option { 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. diff --git a/lib/codegen/src/ir/globalvalue.rs b/lib/codegen/src/ir/globalvalue.rs new file mode 100644 index 0000000000..5d068a7583 --- /dev/null +++ b/lib/codegen/src/ir/globalvalue.rs @@ -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) + } + } + } +} diff --git a/lib/codegen/src/ir/globalvar.rs b/lib/codegen/src/ir/globalvar.rs index 399f3b7ae4..5d068a7583 100644 --- a/lib/codegen/src/ir/globalvar.rs +++ b/lib/codegen/src/ir/globalvar.rs @@ -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, } => { diff --git a/lib/codegen/src/ir/heap.rs b/lib/codegen/src/ir/heap.rs index b41565b25b..812ffa01d3 100644 --- a/lib/codegen/src/ir/heap.rs +++ b/lib/codegen/src/ir/heap.rs @@ -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)?; diff --git a/lib/codegen/src/ir/mod.rs b/lib/codegen/src/ir/mod.rs index daca83cc3a..71e56ec5a0 100644 --- a/lib/codegen/src/ir/mod.rs +++ b/lib/codegen/src/ir/mod.rs @@ -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; diff --git a/lib/codegen/src/legalizer/globalvar.rs b/lib/codegen/src/legalizer/globalvalue.rs similarity index 50% rename from lib/codegen/src/legalizer/globalvar.rs rename to lib/codegen/src/legalizer/globalvalue.rs index d8fd0b94b7..fbea36b9e6 100644 --- a/lib/codegen/src/legalizer/globalvar.rs +++ b/lib/codegen/src/legalizer/globalvalue.rs @@ -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); } diff --git a/lib/codegen/src/legalizer/heap.rs b/lib/codegen/src/legalizer/heap.rs index 3b0b5dfd1c..ab68976d57 100644 --- a/lib/codegen/src/legalizer/heap.rs +++ b/lib/codegen/src/legalizer/heap.rs @@ -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(); diff --git a/lib/codegen/src/legalizer/mod.rs b/lib/codegen/src/legalizer/mod.rs index 9dcc2dff2f..f099ca7447 100644 --- a/lib/codegen/src/legalizer/mod.rs +++ b/lib/codegen/src/legalizer/mod.rs @@ -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; diff --git a/lib/codegen/src/predicates.rs b/lib/codegen/src/predicates.rs index 74b6e1d8cd..96cf0f38c6 100644 --- a/lib/codegen/src/predicates.rs +++ b/lib/codegen/src/predicates.rs @@ -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"), } } diff --git a/lib/codegen/src/regalloc/solver.rs b/lib/codegen/src/regalloc/solver.rs index d5d000fa95..779396cc57 100644 --- a/lib/codegen/src/regalloc/solver.rs +++ b/lib/codegen/src/regalloc/solver.rs @@ -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 { diff --git a/lib/codegen/src/verifier/mod.rs b/lib/codegen/src/verifier/mod.rs index 12643fc61b..98766e233d 100644 --- a/lib/codegen/src/verifier/mod.rs +++ b/lib/codegen/src/verifier/mod.rs @@ -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) { diff --git a/lib/codegen/src/write.rs b/lib/codegen/src/write.rs index b99066ea53..124034b39a 100644 --- a/lib/codegen/src/write.rs +++ b/lib/codegen/src/write.rs @@ -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]), diff --git a/lib/faerie/src/backend.rs b/lib/faerie/src/backend.rs index 4c900c843a..0bb82efa9e 100644 --- a/lib/faerie/src/backend.rs +++ b/lib/faerie/src/backend.rs @@ -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!() diff --git a/lib/frontend/src/frontend.rs b/lib/frontend/src/frontend.rs index 453fc09c0e..fc2280623a 100644 --- a/lib/frontend/src/frontend.rs +++ b/lib/frontend/src/frontend.rs @@ -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. diff --git a/lib/module/src/backend.rs b/lib/module/src/backend.rs index 85ff12a849..ef8eef9713 100644 --- a/lib/module/src/backend.rs +++ b/lib/module/src/backend.rs @@ -84,7 +84,7 @@ where &mut self, data: &mut Self::CompiledData, offset: usize, - what: ir::GlobalVar, + what: ir::GlobalValue, addend: binemit::Addend, ); diff --git a/lib/module/src/data_context.rs b/lib/module/src/data_context.rs index 0fef3f6400..69cca4b5fe 100644 --- a/lib/module/src/data_context.rs +++ b/lib/module/src/data_context.rs @@ -52,11 +52,11 @@ pub struct DataDescription { /// External function declarations. pub function_decls: PrimaryMap, /// External data object declarations. - pub data_decls: PrimaryMap, + pub data_decls: PrimaryMap, /// 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); diff --git a/lib/module/src/module.rs b/lib/module/src/module.rs index 84188ccd75..76ac8926b9 100644 --- a/lib/module/src/module.rs +++ b/lib/module/src/module.rs @@ -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]; diff --git a/lib/reader/src/lexer.rs b/lib/reader/src/lexer.rs index 6c622ff64f..43bee2c399 100644 --- a/lib/reader/src/lexer.rs +++ b/lib/reader/src/lexer.rs @@ -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)), diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index 4fba2a19c8..996c7af6ca 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -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 { - if let Some(Token::GlobalVar(gv)) = self.token() { + // Match and consume a global valueiable reference. + fn match_gv(&mut self, err_msg: &str) -> ParseResult { + 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 { + /// stack-limit-decl ::= "stack_limit" "=" GlobalValue(gv) + fn parse_stack_limit_decl(&mut self) -> ParseResult { 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 => { diff --git a/lib/reader/src/sourcemap.rs b/lib/reader/src/sourcemap.rs index 6b9dc51d02..1bb6231596 100644 --- a/lib/reader/src/sourcemap.rs +++ b/lib/reader/src/sourcemap.rs @@ -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) } diff --git a/lib/simplejit/src/backend.rs b/lib/simplejit/src/backend.rs index 4df071efc9..5886b7ad76 100644 --- a/lib/simplejit/src/backend.rs +++ b/lib/simplejit/src/backend.rs @@ -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!(); diff --git a/lib/umbrella/src/lib.rs b/lib/umbrella/src/lib.rs index 11b773b7f5..1048b4d780 100644 --- a/lib/umbrella/src/lib.rs +++ b/lib/umbrella/src/lib.rs @@ -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}; diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index 07e912da1d..7f9d390399 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -74,7 +74,7 @@ pub fn translate_operator( 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( 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(); diff --git a/lib/wasm/src/environ/dummy.rs b/lib/wasm/src/environ/dummy.rs index 7b71f8b69e..0bd7fc1a94 100644 --- a/lib/wasm/src/environ/dummy.rs +++ b/lib/wasm/src/environ/dummy.rs @@ -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 { diff --git a/lib/wasm/src/environ/spec.rs b/lib/wasm/src/environ/spec.rs index 00882d035f..848f29747c 100644 --- a/lib/wasm/src/environ/spec.rs +++ b/lib/wasm/src/environ/spec.rs @@ -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; diff --git a/lib/wasm/src/sections_translator.rs b/lib/wasm/src/sections_translator.rs index 99a0051121..d3dc64496a 100644 --- a/lib/wasm/src/sections_translator.rs +++ b/lib/wasm/src/sections_translator.rs @@ -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}; diff --git a/lib/wasm/src/state.rs b/lib/wasm/src/state.rs index b0bb4f5c7a..372cd297b7 100644 --- a/lib/wasm/src/state.rs +++ b/lib/wasm/src/state.rs @@ -134,7 +134,7 @@ pub struct TranslationState { pub control_stack: Vec, 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, // 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( diff --git a/lib/wasm/src/translation_utils.rs b/lib/wasm/src/translation_utils.rs index 3ed13899e6..9257870264 100644 --- a/lib/wasm/src/translation_utils.rs +++ b/lib/wasm/src/translation_utils.rs @@ -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;