Limit type inference for controlling type variables in write.rs

This commit is contained in:
Keith Yeung
2017-03-22 06:02:07 +08:00
committed by Jakob Stoklund Olesen
parent 098a48e332
commit 07740b5e3c
2 changed files with 14 additions and 11 deletions

View File

@@ -62,7 +62,7 @@ ebb1:
; nextln: brz vx0, ebb1 ; nextln: brz vx0, ebb1
; nextln: ; nextln:
; nextln: ebb1: ; nextln: ebb1:
; nextln: brnz vx0, ebb1 ; nextln: brnz.i32 vx0, ebb1
; nextln: } ; nextln: }
function twoargs(i32, f32) { function twoargs(i32, f32) {
@@ -77,7 +77,7 @@ ebb1(vx2: i32, vx3: f32):
; nextln: brz vx0, ebb1(vx0, vx1) ; nextln: brz vx0, ebb1(vx0, vx1)
; nextln: ; nextln:
; nextln: ebb1(vx2: i32, vx3: f32): ; nextln: ebb1(vx2: i32, vx3: f32):
; nextln: brnz vx0, ebb0(vx2, vx3) ; nextln: brnz.i32 vx0, ebb0(vx2, vx3)
; nextln: } ; nextln: }
function jumptable(i32) { function jumptable(i32) {

View File

@@ -4,7 +4,7 @@
//! equivalent textual representation. This textual representation can be read back by the //! equivalent textual representation. This textual representation can be read back by the
//! `cretonne-reader` crate. //! `cretonne-reader` crate.
use ir::{Function, DataFlowGraph, Ebb, Inst, Value, Type}; use ir::{Function, DataFlowGraph, Ebb, Inst, Value, ValueDef, Type};
use isa::{TargetIsa, RegInfo}; use isa::{TargetIsa, RegInfo};
use std::fmt::{self, Result, Error, Write}; use std::fmt::{self, Result, Error, Write};
use std::result; use std::result;
@@ -132,7 +132,8 @@ pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: E
// if it can't be trivially inferred. // if it can't be trivially inferred.
// //
fn type_suffix(func: &Function, inst: Inst) -> Option<Type> { fn type_suffix(func: &Function, inst: Inst) -> Option<Type> {
let constraints = func.dfg[inst].opcode().constraints(); let inst_data = &func.dfg[inst];
let constraints = inst_data.opcode().constraints();
if !constraints.is_polymorphic() { if !constraints.is_polymorphic() {
return None; return None;
@@ -140,16 +141,18 @@ fn type_suffix(func: &Function, inst: Inst) -> Option<Type> {
// If the controlling type variable can be inferred from the type of the designated value input // If the controlling type variable can be inferred from the type of the designated value input
// operand, we don't need the type suffix. // operand, we don't need the type suffix.
// TODO: Should we include the suffix when the input value is defined in another block? The
// parser needs to know the type of the value, so it must be defined in a block that lexically
// comes before this one.
if constraints.use_typevar_operand() { if constraints.use_typevar_operand() {
return None; let ctrl_var = inst_data.typevar_operand(&func.dfg.value_lists).unwrap();
let def_ebb = match func.dfg.value_def(ctrl_var) {
ValueDef::Res(instr, _) => func.layout.inst_ebb(instr),
ValueDef::Arg(ebb, _) => Some(ebb),
};
if def_ebb.is_some() && def_ebb == func.layout.inst_ebb(inst) {
return None;
}
} }
// This polymorphic instruction doesn't support basic type inference. let rtype = inst_data.ctrl_typevar(&func.dfg);
// The controlling type variable is required to be the type of the first result.
let rtype = func.dfg.value_type(func.dfg.first_result(inst));
assert!(!rtype.is_void(), assert!(!rtype.is_void(),
"Polymorphic instruction must produce a result"); "Polymorphic instruction must produce a result");
Some(rtype) Some(rtype)