Add a stub implementation of the legalizer.

This basic version only fills in the encoding of already-legal
instructions. It doesn't have any way of transforming the illegal
instructions yet.
This commit is contained in:
Jakob Stoklund Olesen
2016-09-20 10:49:30 -07:00
parent ebadbdbe7e
commit de35e715fa
2 changed files with 55 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
//! Legalize instructions.
//!
//! A legal instruction is one that can be mapped directly to a machine code instruction for the
//! target ISA. The `legalize_function()` function takes as input any function and transforms it
//! into an equivalent function using only legal instructions.
//!
//! The characteristics of legal instructions depend on the target ISA, so any given instruction
//! can be legal for one ISA and illegal for another.
//!
//! Besides transforming instructions, the legalizer also fills out the `function.encodings` map
//! which provides a legal encoding recipe for every instruction.
//!
//! The legalizer does not deal with register allocation constraints. These constraints are derived
//! from the encoding recipes, and solved later by the register allocator.
use ir::Function;
use isa::TargetIsa;
/// Legalize `func` for `isa`.
///
/// - Transform any instructions that don't have a legal representation in `isa`.
/// - Fill out `func.encodings`.
///
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) {
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.
}
}
}
}
}

View File

@@ -16,6 +16,7 @@ pub mod dominator_tree;
pub mod entity_map;
pub mod settings;
pub mod verifier;
pub mod legalizer;
mod write;
mod constant_hash;