Change GlobalVar to GlobalValue

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

View File

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

View File

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

View File

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