Change GlobalVar to GlobalValue
This commit is contained in:
committed by
Dan Gohman
parent
49cc693d64
commit
5c320a0d30
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
70
lib/codegen/src/ir/globalvalue.rs
Normal file
70
lib/codegen/src/ir/globalvalue.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
} => {
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]),
|
||||
|
||||
Reference in New Issue
Block a user