diff --git a/cranelift/src/libcretonne/legalizer.rs b/cranelift/src/libcretonne/legalizer.rs new file mode 100644 index 0000000000..3358f77bb0 --- /dev/null +++ b/cranelift/src/libcretonne/legalizer.rs @@ -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. + } + } + } + } +} diff --git a/cranelift/src/libcretonne/lib.rs b/cranelift/src/libcretonne/lib.rs index de6cf109b5..7285f95602 100644 --- a/cranelift/src/libcretonne/lib.rs +++ b/cranelift/src/libcretonne/lib.rs @@ -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;