Return a Result from the TargetIsa::encode() method.

When an instruction can't be encoded, provide a viable legalization
action in the form of a Legalize enum.
This commit is contained in:
Jakob Stoklund Olesen
2016-11-03 18:59:32 -07:00
parent 9c02fe3553
commit e59b47c41a
4 changed files with 64 additions and 40 deletions

View File

@@ -15,7 +15,7 @@
use ir::{Function, Cursor, DataFlowGraph, InstructionData, Opcode, Inst, InstBuilder};
use ir::condcodes::IntCC;
use isa::TargetIsa;
use isa::{TargetIsa, Legalize};
/// Legalize `func` for `isa`.
///
@@ -25,30 +25,35 @@ use isa::TargetIsa;
pub fn legalize_function(func: &mut Function, isa: &TargetIsa) {
// TODO: This is very simplified and incomplete.
func.encodings.resize(func.dfg.num_insts());
for ebb in func.layout.ebbs() {
for inst in func.layout.ebb_insts(ebb) {
let mut pos = Cursor::new(&mut func.layout);
while let Some(_ebb) = pos.next_ebb() {
while let Some(inst) = pos.next_inst() {
match isa.encode(&func.dfg, &func.dfg[inst]) {
Some(encoding) => func.encodings[inst] = encoding,
None => {
// TODO: We should transform the instruction into legal equivalents.
// Possible strategies are:
// 1. Expand instruction into sequence of legal instructions. Possibly
// iteratively.
// 2. Split the controlling type variable into high and low parts. This applies
// both to SIMD vector types which can be halved and to integer types such
// as `i64` used on a 32-bit ISA.
// 3. Promote the controlling type variable to a larger type. This typically
// means expressing `i8` and `i16` arithmetic in terms if `i32` operations
// on RISC targets. (It may or may not be beneficial to promote small vector
// types versus splitting them.)
// 4. Convert to library calls. For example, floating point operations on an
// ISA with no IEEE 754 support.
//
// The iteration scheme used here is not going to cut it. Transforming
// instructions involves changing `function.layout` which is impossiblr while
// it is referenced by the two iterators. We need a layout cursor that can
// maintain a position *and* permit inserting and replacing instructions.
Ok(encoding) => func.encodings[inst] = encoding,
Err(Legalize::Expand) => {
expand(&mut pos, &mut func.dfg);
}
Err(Legalize::Narrow) => {
narrow(&mut pos, &mut func.dfg);
}
// TODO: We should transform the instruction into legal equivalents.
// Possible strategies are:
// 1. Expand instruction into sequence of legal instructions. Possibly
// iteratively.
// 2. Split the controlling type variable into high and low parts. This applies
// both to SIMD vector types which can be halved and to integer types such
// as `i64` used on a 32-bit ISA.
// 3. Promote the controlling type variable to a larger type. This typically
// means expressing `i8` and `i16` arithmetic in terms if `i32` operations
// on RISC targets. (It may or may not be beneficial to promote small vector
// types versus splitting them.)
// 4. Convert to library calls. For example, floating point operations on an
// ISA with no IEEE 754 support.
//
// The iteration scheme used here is not going to cut it. Transforming
// instructions involves changing `function.layout` which is impossiblr while
// it is referenced by the two iterators. We need a layout cursor that can
// maintain a position *and* permit inserting and replacing instructions.
}
}
}