Pass an ISA argument to legalization functions.

This lets them look at the ISA flags.
This commit is contained in:
Jakob Stoklund Olesen
2018-02-12 14:21:41 -08:00
parent 60e70da0e6
commit a73fcb2691
6 changed files with 74 additions and 15 deletions

View File

@@ -360,6 +360,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
fmt.line('inst: ir::Inst,') fmt.line('inst: ir::Inst,')
fmt.line('func: &mut ir::Function,') fmt.line('func: &mut ir::Function,')
fmt.line('cfg: &mut ::flowgraph::ControlFlowGraph,') fmt.line('cfg: &mut ::flowgraph::ControlFlowGraph,')
fmt.line('isa: &::isa::TargetIsa,')
with fmt.indented(') -> bool {', '}'): with fmt.indented(') -> bool {', '}'):
fmt.line('use ir::InstBuilder;') fmt.line('use ir::InstBuilder;')
fmt.line('use cursor::{Cursor, FuncCursor};') fmt.line('use cursor::{Cursor, FuncCursor};')
@@ -387,7 +388,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
with fmt.indented( with fmt.indented(
'ir::Opcode::{} => {{' 'ir::Opcode::{} => {{'
.format(inst.camel_name), '}'): .format(inst.camel_name), '}'):
fmt.format('{}(inst, pos.func, cfg);', funcname) fmt.format('{}(inst, pos.func, cfg, isa);', funcname)
fmt.line('return true;') fmt.line('return true;')
# We'll assume there are uncovered opcodes. # We'll assume there are uncovered opcodes.
@@ -395,7 +396,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
# If we fall through, nothing was expanded. Call the chain if any. # If we fall through, nothing was expanded. Call the chain if any.
if xgrp.chain: if xgrp.chain:
fmt.format('{}(inst, pos.func, cfg)', xgrp.chain.rust_name()) fmt.format('{}(inst, pos.func, cfg, isa)', xgrp.chain.rust_name())
else: else:
fmt.line('false') fmt.line('false')

View File

@@ -15,7 +15,12 @@ include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs"));
include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs")); include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs"));
/// Expand the `srem` instruction using `x86_sdivmodx`. /// Expand the `srem` instruction using `x86_sdivmodx`.
fn expand_srem(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_srem(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &isa::TargetIsa,
) {
use ir::condcodes::IntCC; use ir::condcodes::IntCC;
let (x, y) = match func.dfg[inst] { let (x, y) = match func.dfg[inst] {
@@ -70,7 +75,12 @@ fn expand_srem(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGra
/// Expand the `fmin` and `fmax` instructions using the Intel `x86_fmin` and `x86_fmax` /// Expand the `fmin` and `fmax` instructions using the Intel `x86_fmin` and `x86_fmax`
/// instructions. /// instructions.
fn expand_minmax(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_minmax(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &isa::TargetIsa,
) {
use ir::condcodes::FloatCC; use ir::condcodes::FloatCC;
let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] { let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] {
@@ -159,7 +169,12 @@ fn expand_minmax(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowG
/// Intel has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to /// Intel has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to
/// i64 with a pattern, the rest needs more code. /// i64 with a pattern, the rest needs more code.
fn expand_fcvt_from_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_fcvt_from_uint(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &isa::TargetIsa,
) {
use ir::condcodes::IntCC; use ir::condcodes::IntCC;
let x; let x;
@@ -227,7 +242,12 @@ fn expand_fcvt_from_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut Cont
cfg.recompute_ebb(pos.func, done); cfg.recompute_ebb(pos.func, done);
} }
fn expand_fcvt_to_sint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_fcvt_to_sint(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &isa::TargetIsa,
) {
use ir::condcodes::{IntCC, FloatCC}; use ir::condcodes::{IntCC, FloatCC};
use ir::immediates::{Ieee32, Ieee64}; use ir::immediates::{Ieee32, Ieee64};
@@ -303,7 +323,12 @@ fn expand_fcvt_to_sint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut Contro
cfg.recompute_ebb(pos.func, done); cfg.recompute_ebb(pos.func, done);
} }
fn expand_fcvt_to_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_fcvt_to_uint(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &isa::TargetIsa,
) {
use ir::condcodes::{IntCC, FloatCC}; use ir::condcodes::{IntCC, FloatCC};
use ir::immediates::{Ieee32, Ieee64}; use ir::immediates::{Ieee32, Ieee64};

View File

@@ -144,7 +144,8 @@ impl settings::Configurable for Builder {
/// The `Encodings` iterator returns a legalization function to call. /// The `Encodings` iterator returns a legalization function to call.
pub type Legalize = fn(ir::Inst, pub type Legalize = fn(ir::Inst,
&mut ir::Function, &mut ir::Function,
&mut flowgraph::ControlFlowGraph) &mut flowgraph::ControlFlowGraph,
&TargetIsa)
-> bool; -> bool;
/// Methods that are specialized to a target ISA. Implies a Display trait that shows the /// Methods that are specialized to a target ISA. Implies a Display trait that shows the

View File

@@ -6,9 +6,15 @@
use cursor::{Cursor, FuncCursor}; use cursor::{Cursor, FuncCursor};
use flowgraph::ControlFlowGraph; use flowgraph::ControlFlowGraph;
use ir::{self, InstBuilder}; use ir::{self, InstBuilder};
use isa::TargetIsa;
/// Expand a `global_addr` instruction according to the definition of the global variable. /// Expand a `global_addr` instruction according to the definition of the global variable.
pub fn expand_global_addr(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlowGraph) { pub fn expand_global_addr(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
// Unpack the instruction. // Unpack the instruction.
let gv = match func.dfg[inst] { let gv = match func.dfg[inst] {
ir::InstructionData::UnaryGlobalVar { opcode, global_var } => { ir::InstructionData::UnaryGlobalVar { opcode, global_var } => {

View File

@@ -7,9 +7,15 @@ use cursor::{Cursor, FuncCursor};
use flowgraph::ControlFlowGraph; use flowgraph::ControlFlowGraph;
use ir::{self, InstBuilder, MemFlags}; use ir::{self, InstBuilder, MemFlags};
use ir::condcodes::IntCC; use ir::condcodes::IntCC;
use isa::TargetIsa;
/// Expand a `heap_addr` instruction according to the definition of the heap. /// Expand a `heap_addr` instruction according to the definition of the heap.
pub fn expand_heap_addr(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { pub fn expand_heap_addr(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
// Unpack the instruction. // Unpack the instruction.
let (heap, offset, size) = match func.dfg[inst] { let (heap, offset, size) = match func.dfg[inst] {
ir::InstructionData::HeapAddr { ir::InstructionData::HeapAddr {

View File

@@ -80,7 +80,7 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
Ok(encoding) => pos.func.encodings[inst] = encoding, Ok(encoding) => pos.func.encodings[inst] = encoding,
Err(action) => { Err(action) => {
// We should transform the instruction into legal equivalents. // We should transform the instruction into legal equivalents.
let changed = action(inst, pos.func, cfg); let changed = action(inst, pos.func, cfg, isa);
// If the current instruction was replaced, we need to double back and revisit // If the current instruction was replaced, we need to double back and revisit
// the expanded sequence. This is both to assign encodings and possible to // the expanded sequence. This is both to assign encodings and possible to
// expand further. // expand further.
@@ -114,7 +114,12 @@ include!(concat!(env!("OUT_DIR"), "/legalizer.rs"));
/// Custom expansion for conditional trap instructions. /// Custom expansion for conditional trap instructions.
/// TODO: Add CFG support to the Python patterns so we won't have to do this. /// TODO: Add CFG support to the Python patterns so we won't have to do this.
fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_cond_trap(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
// Parse the instruction. // Parse the instruction.
let trapz; let trapz;
let (arg, code) = match func.dfg[inst] { let (arg, code) = match func.dfg[inst] {
@@ -159,7 +164,12 @@ fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFl
} }
/// Jump tables. /// Jump tables.
fn expand_br_table(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_br_table(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
use ir::condcodes::IntCC; use ir::condcodes::IntCC;
let (arg, table) = match func.dfg[inst] { let (arg, table) = match func.dfg[inst] {
@@ -194,7 +204,12 @@ fn expand_br_table(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlo
/// ///
/// Conditional moves are available in some ISAs for some register classes. The remaining selects /// Conditional moves are available in some ISAs for some register classes. The remaining selects
/// are handled by a branch. /// are handled by a branch.
fn expand_select(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { fn expand_select(
inst: ir::Inst,
func: &mut ir::Function,
cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
let (ctrl, tval, fval) = match func.dfg[inst] { let (ctrl, tval, fval) = match func.dfg[inst] {
ir::InstructionData::Ternary { ir::InstructionData::Ternary {
opcode: ir::Opcode::Select, opcode: ir::Opcode::Select,
@@ -226,7 +241,12 @@ fn expand_select(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowG
/// Expand illegal `f32const` and `f64const` instructions. /// Expand illegal `f32const` and `f64const` instructions.
fn expand_fconst(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlowGraph) { fn expand_fconst(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
_isa: &TargetIsa,
) {
let ty = func.dfg.value_type(func.dfg.first_result(inst)); let ty = func.dfg.value_type(func.dfg.first_result(inst));
assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty); assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);