Add operand register constraints.

Every encoding recipe must specify register constraints on input and
output values.

Generate recipe constraint tables along with the other encoding tables.
This commit is contained in:
Jakob Stoklund Olesen
2017-01-24 11:19:31 -08:00
parent 3b83496edb
commit 2390e3e3f0
15 changed files with 299 additions and 14 deletions

View File

@@ -4,5 +4,6 @@ use ir::InstructionData;
use ir::instructions::InstructionFormat;
use ir::types;
use isa::enc_tables::{Level1Entry, Level2Entry};
use isa::constraints::*;
include!(concat!(env!("OUT_DIR"), "/encoding-arm32.rs"));

View File

@@ -7,7 +7,7 @@ mod registers;
use super::super::settings as shared_settings;
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
use isa::Builder as IsaBuilder;
use isa::{TargetIsa, RegInfo, Encoding, Legalize};
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
use ir::{InstructionData, DataFlowGraph};
#[allow(dead_code)]
@@ -70,4 +70,8 @@ impl TargetIsa for Isa {
fn recipe_names(&self) -> &'static [&'static str] {
&enc_tables::RECIPE_NAMES[..]
}
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
&enc_tables::RECIPE_CONSTRAINTS
}
}

View File

@@ -4,5 +4,6 @@ use ir::InstructionData;
use ir::instructions::InstructionFormat;
use ir::types;
use isa::enc_tables::{Level1Entry, Level2Entry};
use isa::constraints::*;
include!(concat!(env!("OUT_DIR"), "/encoding-arm64.rs"));

View File

@@ -7,7 +7,7 @@ mod registers;
use super::super::settings as shared_settings;
use isa::enc_tables::{lookup_enclist, general_encoding};
use isa::Builder as IsaBuilder;
use isa::{TargetIsa, RegInfo, Encoding, Legalize};
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
use ir::{InstructionData, DataFlowGraph};
#[allow(dead_code)]
@@ -63,4 +63,8 @@ impl TargetIsa for Isa {
fn recipe_names(&self) -> &'static [&'static str] {
&enc_tables::RECIPE_NAMES[..]
}
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
&enc_tables::RECIPE_CONSTRAINTS
}
}

View File

@@ -0,0 +1,66 @@
//! Register constraints for instruction operands.
//!
//! An encoding recipe specifies how an instruction is encoded as binary machine code, but it only
//! works if the operands and results satisfy certain constraints. Constraints on immediate
//! operands are checked by instruction predicates when the recipe is chosen.
//!
//! It is the register allocator's job to make sure that the register constraints on value operands
//! are satisfied.
use isa::{RegClass, RegUnit};
/// Register constraint for a single value operand or instruction result.
pub struct OperandConstraint {
/// The kind of constraint.
pub kind: ConstraintKind,
/// The register class of the operand.
///
/// This applies to all kinds of constraints, but with slightly different meaning.
pub regclass: RegClass,
}
/// The different kinds of operand constraints.
pub enum ConstraintKind {
/// This operand or result must be a register from the given register class.
Reg,
/// This operand or result must be a fixed register.
///
/// The constraint's `regclass` field is the top-level register class containing the fixed
/// register.
FixedReg(RegUnit),
/// This result value must use the same register as an input value operand. Input operands
/// can't be tied.
///
/// The associated number is the index of the input value operand this result is tied to.
///
/// The constraint's `regclass` field is the top-level register class containing the tied
/// operand's register class.
Tied(u8),
/// This operand must be a value in a stack slot.
///
/// The constraint's `regclass` field is the register class that would normally be used to load
/// and store values of this type.
Stack,
}
/// Constraints for an encoding recipe.
pub struct RecipeConstraints {
/// Constraints for the instruction's fixed value operands.
///
/// If the instruction takes a variable number of operands, the register constraints for those
/// operands must be computed dynamically.
///
/// - For branches and jumps, EBB arguments must match the expectations of the destination EBB.
/// - For calls and returns, the calling convention ABI specifies constraints.
pub ins: &'static [OperandConstraint],
/// Constraints for the instruction's fixed results.
///
/// If the instruction produces a variable number of results, it's probably a call and the
/// constraints must be derived from the calling convention ABI.
pub outs: &'static [OperandConstraint],
}

View File

@@ -4,5 +4,6 @@ use ir::InstructionData;
use ir::instructions::InstructionFormat;
use ir::types;
use isa::enc_tables::{Level1Entry, Level2Entry};
use isa::constraints::*;
include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs"));

View File

@@ -7,7 +7,7 @@ mod registers;
use super::super::settings as shared_settings;
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
use isa::Builder as IsaBuilder;
use isa::{TargetIsa, RegInfo, Encoding, Legalize};
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
use ir::{InstructionData, DataFlowGraph};
#[allow(dead_code)]
@@ -70,4 +70,8 @@ impl TargetIsa for Isa {
fn recipe_names(&self) -> &'static [&'static str] {
&enc_tables::RECIPE_NAMES[..]
}
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
&enc_tables::RECIPE_CONSTRAINTS
}
}

View File

@@ -42,6 +42,8 @@
pub use isa::encoding::Encoding;
pub use isa::registers::{RegInfo, RegUnit, RegClass};
pub use isa::constraints::RecipeConstraints;
use settings;
use ir::{InstructionData, DataFlowGraph};
@@ -52,6 +54,7 @@ pub mod arm64;
pub mod registers;
mod encoding;
mod enc_tables;
mod constraints;
/// Look for a supported ISA with the given `name`.
/// Return a builder that can create a corresponding `TargetIsa`.
@@ -140,11 +143,17 @@ pub trait TargetIsa {
fn encode(&self, dfg: &DataFlowGraph, inst: &InstructionData) -> Result<Encoding, Legalize>;
/// Get a static array of names associated with encoding recipes in this ISA. Encoding recipes
/// are numbered starting from 0, corresponding to indexes into th name array.
/// are numbered starting from 0, corresponding to indexes into the name array.
///
/// This is just used for printing and parsing encodings in the textual IL format.
fn recipe_names(&self) -> &'static [&'static str];
/// Get a static array of value operand constraints associated with encoding recipes in this
/// ISA.
///
/// The constraints describe which registers can be used with an encoding recipe.
fn recipe_constraints(&self) -> &'static [RecipeConstraints];
/// Create an object that can display an ISA-dependent encoding properly.
fn display_enc(&self, enc: Encoding) -> encoding::DisplayEncoding {
encoding::DisplayEncoding {

View File

@@ -5,6 +5,8 @@ use ir::instructions::InstructionFormat;
use ir::types;
use predicates;
use isa::enc_tables::{Level1Entry, Level2Entry};
use isa::constraints::*;
use super::registers::*;
// Include the generated encoding tables:
// - `LEVEL1_RV32`

View File

@@ -7,7 +7,7 @@ mod registers;
use super::super::settings as shared_settings;
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
use isa::Builder as IsaBuilder;
use isa::{TargetIsa, RegInfo, Encoding, Legalize};
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
use ir::{InstructionData, DataFlowGraph};
#[allow(dead_code)]
@@ -70,6 +70,10 @@ impl TargetIsa for Isa {
fn recipe_names(&self) -> &'static [&'static str] {
&enc_tables::RECIPE_NAMES[..]
}
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
&enc_tables::RECIPE_CONSTRAINTS
}
}
#[cfg(test)]