Change GlobalVar to GlobalValue
This commit is contained in:
committed by
Dan Gohman
parent
49cc693d64
commit
5c320a0d30
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user