Add a PredicateView type to abstract the predicate bit vector a bit.

The encoding tables contain references to numbered ISA predicates.

- Give the ISA Flags types a predicate_view() method which returns a
  PredicateView.
- Delete the old predicate_bytes() method which returned a raw &[u8].
- Use a 'static lifetime for the encoding list slice in the Encodings
  iterator, and a single 'a lifetime for everything else.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-21 13:48:18 -07:00
parent 4142a9ca9c
commit f651ec4f78
8 changed files with 78 additions and 54 deletions

View File

@@ -87,15 +87,19 @@ def gen_getters(sgrp, fmt):
""" """
fmt.doc_comment("User-defined settings.") fmt.doc_comment("User-defined settings.")
with fmt.indented('impl Flags {', '}'): with fmt.indented('impl Flags {', '}'):
fmt.doc_comment('Returns inner slice of bytes.') fmt.doc_comment('Get a view of the boolean predicates.')
fmt.doc_comment('The byte-sized settings are not included.') with fmt.indented(
with fmt.indented('pub fn predicate_bytes(&self) -> &[u8] {', '}'): 'pub fn predicate_view(&self) -> ::settings::PredicateView {',
fmt.line('&self.bytes[{}..]'.format(sgrp.boolean_offset)) '}'):
fmt.format(
'::settings::PredicateView::new(&self.bytes[{}..])',
sgrp.boolean_offset)
if sgrp.settings:
fmt.doc_comment('Dynamic numbered predicate getter.') fmt.doc_comment('Dynamic numbered predicate getter.')
with fmt.indented( with fmt.indented(
'pub fn numbered_predicate(&self, p: usize) -> bool {', '}'): 'fn numbered_predicate(&self, p: usize) -> bool {', '}'):
fmt.line( fmt.line(
'self.bytes[{} + p/8] & (1 << (p%8)) != 0' 'self.bytes[{} + p / 8] & (1 << (p % 8)) != 0'
.format(sgrp.boolean_offset)) .format(sgrp.boolean_offset))
for setting in sgrp.settings: for setting in sgrp.settings:
gen_getter(setting, sgrp, fmt) gen_getter(setting, sgrp, fmt)

View File

@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
enc_tables::INFO.clone() enc_tables::INFO.clone()
} }
fn legal_encodings<'a, 'b>(&'a self, fn legal_encodings<'a>(&'a self,
_dfg: &'b ir::DataFlowGraph, _dfg: &'a ir::DataFlowGraph,
inst: &'b ir::InstructionData, inst: &'a ir::InstructionData,
ctrl_typevar: ir::Type) ctrl_typevar: ir::Type)
-> Result<Encodings<'a, 'b>, Legalize> { -> Result<Encodings<'a>, Legalize> {
lookup_enclist(ctrl_typevar, lookup_enclist(ctrl_typevar,
inst.opcode(), inst.opcode(),
self.cpumode, self.cpumode,
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
&enc_tables::ENCLISTS[..], &enc_tables::ENCLISTS[..],
inst, inst,
enc_tables::check_instp, enc_tables::check_instp,
self.isa_flags.predicate_bytes())) self.isa_flags.predicate_view()))
}) })
} }

View File

@@ -54,11 +54,11 @@ impl TargetIsa for Isa {
enc_tables::INFO.clone() enc_tables::INFO.clone()
} }
fn legal_encodings<'a, 'b>(&'a self, fn legal_encodings<'a>(&'a self,
_dfg: &'b ir::DataFlowGraph, _dfg: &'a ir::DataFlowGraph,
inst: &'b ir::InstructionData, inst: &'a ir::InstructionData,
ctrl_typevar: ir::Type) ctrl_typevar: ir::Type)
-> Result<Encodings<'a, 'b>, Legalize> { -> Result<Encodings<'a>, Legalize> {
lookup_enclist(ctrl_typevar, lookup_enclist(ctrl_typevar,
inst.opcode(), inst.opcode(),
&enc_tables::LEVEL1_A64[..], &enc_tables::LEVEL1_A64[..],
@@ -68,7 +68,7 @@ impl TargetIsa for Isa {
&enc_tables::ENCLISTS[..], &enc_tables::ENCLISTS[..],
inst, inst,
enc_tables::check_instp, enc_tables::check_instp,
self.isa_flags.predicate_bytes())) self.isa_flags.predicate_view()))
}) })
} }

View File

@@ -2,9 +2,11 @@
//! //!
//! This module contains types and functions for working with the encoding tables generated by //! This module contains types and functions for working with the encoding tables generated by
//! `lib/cretonne/meta/gen_encoding.py`. //! `lib/cretonne/meta/gen_encoding.py`.
use constant_hash::{Table, probe};
use ir::{Type, Opcode, InstructionData}; use ir::{Type, Opcode, InstructionData};
use isa::{Encoding, Legalize}; use isa::{Encoding, Legalize};
use constant_hash::{Table, probe}; use settings::PredicateView;
use std::ops::Range; use std::ops::Range;
/// Level 1 hash table entry. /// Level 1 hash table entry.
@@ -127,15 +129,15 @@ const CODE_ALWAYS: EncListEntry = PRED_MASK;
const CODE_FAIL: EncListEntry = 0xffff; const CODE_FAIL: EncListEntry = 0xffff;
/// An iterator over legal encodings for the instruction. /// An iterator over legal encodings for the instruction.
pub struct Encodings<'a, 'b> { pub struct Encodings<'a> {
offset: usize, offset: usize,
enclist: &'b [EncListEntry], enclist: &'static [EncListEntry],
inst: &'b InstructionData, inst: &'a InstructionData,
instp: fn(&InstructionData, EncListEntry) -> bool, instp: fn(&InstructionData, EncListEntry) -> bool,
isa_predicate_bytes: &'a [u8], isa_predicates: PredicateView<'a>,
} }
impl<'a, 'b> Encodings<'a, 'b> { impl<'a> Encodings<'a> {
/// Creates a new instance of `Encodings`. /// Creates a new instance of `Encodings`.
/// ///
/// # Parameters /// # Parameters
@@ -151,29 +153,25 @@ impl<'a, 'b> Encodings<'a, 'b> {
/// encoding lists are laid out such that first call to `next` returns valid entry in the list /// encoding lists are laid out such that first call to `next` returns valid entry in the list
/// or `None`. /// or `None`.
pub fn new(offset: usize, pub fn new(offset: usize,
enclist: &'b [EncListEntry], enclist: &'static [EncListEntry],
inst: &'b InstructionData, inst: &'a InstructionData,
instp: fn(&InstructionData, EncListEntry) -> bool, instp: fn(&InstructionData, EncListEntry) -> bool,
isa_predicate_bytes: &'a [u8]) isa_predicates: PredicateView<'a>)
-> Self { -> Self {
Encodings { Encodings {
offset, offset,
enclist, enclist,
inst, inst,
instp, instp,
isa_predicate_bytes, isa_predicates,
} }
} }
} }
impl<'a, 'b> Iterator for Encodings<'a, 'b> { impl<'a> Iterator for Encodings<'a> {
type Item = Encoding; type Item = Encoding;
fn next(&mut self) -> Option<Encoding> { fn next(&mut self) -> Option<Encoding> {
fn numbered_predicate(bytes: &[u8], p: usize) -> bool {
bytes[p / 8] & (1 << (p % 8)) != 0
}
while self.enclist[self.offset] != CODE_FAIL { while self.enclist[self.offset] != CODE_FAIL {
let pred = self.enclist[self.offset]; let pred = self.enclist[self.offset];
if pred <= CODE_ALWAYS { if pred <= CODE_ALWAYS {
@@ -189,7 +187,7 @@ impl<'a, 'b> Iterator for Encodings<'a, 'b> {
} else { } else {
// This is an ISA predicate entry. // This is an ISA predicate entry.
self.offset += 1; self.offset += 1;
if !numbered_predicate(self.isa_predicate_bytes, (pred & PRED_MASK) as usize) { if !self.isa_predicates.test((pred & PRED_MASK) as usize) {
// ISA predicate failed, skip the next N entries. // ISA predicate failed, skip the next N entries.
self.offset += 3 * (pred >> PRED_BITS) as usize; self.offset += 3 * (pred >> PRED_BITS) as usize;
} }

View File

@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
enc_tables::INFO.clone() enc_tables::INFO.clone()
} }
fn legal_encodings<'a, 'b>(&'a self, fn legal_encodings<'a>(&'a self,
_dfg: &'b ir::DataFlowGraph, _dfg: &'a ir::DataFlowGraph,
inst: &'b ir::InstructionData, inst: &'a ir::InstructionData,
ctrl_typevar: ir::Type) ctrl_typevar: ir::Type)
-> Result<Encodings<'a, 'b>, Legalize> { -> Result<Encodings<'a>, Legalize> {
lookup_enclist(ctrl_typevar, lookup_enclist(ctrl_typevar,
inst.opcode(), inst.opcode(),
self.cpumode, self.cpumode,
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
&enc_tables::ENCLISTS[..], &enc_tables::ENCLISTS[..],
inst, inst,
enc_tables::check_instp, enc_tables::check_instp,
self.isa_flags.predicate_bytes())) self.isa_flags.predicate_view()))
}) })
} }

View File

@@ -138,11 +138,11 @@ pub trait TargetIsa {
fn register_info(&self) -> RegInfo; fn register_info(&self) -> RegInfo;
/// Returns an iterartor over legal encodings for the instruction. /// Returns an iterartor over legal encodings for the instruction.
fn legal_encodings<'a, 'b>(&'a self, fn legal_encodings<'a>(&'a self,
dfg: &'b ir::DataFlowGraph, dfg: &'a ir::DataFlowGraph,
inst: &'b ir::InstructionData, inst: &'a ir::InstructionData,
ctrl_typevar: ir::Type) ctrl_typevar: ir::Type)
-> Result<Encodings<'a, 'b>, Legalize>; -> Result<Encodings<'a>, Legalize>;
/// Encode an instruction after determining it is legal. /// Encode an instruction after determining it is legal.
/// ///

View File

@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
enc_tables::INFO.clone() enc_tables::INFO.clone()
} }
fn legal_encodings<'a, 'b>(&'a self, fn legal_encodings<'a>(&'a self,
_dfg: &'b ir::DataFlowGraph, _dfg: &'a ir::DataFlowGraph,
inst: &'b ir::InstructionData, inst: &'a ir::InstructionData,
ctrl_typevar: ir::Type) ctrl_typevar: ir::Type)
-> Result<Encodings<'a, 'b>, Legalize> { -> Result<Encodings<'a>, Legalize> {
lookup_enclist(ctrl_typevar, lookup_enclist(ctrl_typevar,
inst.opcode(), inst.opcode(),
self.cpumode, self.cpumode,
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
&enc_tables::ENCLISTS[..], &enc_tables::ENCLISTS[..],
inst, inst,
enc_tables::check_instp, enc_tables::check_instp,
self.isa_flags.predicate_bytes())) self.isa_flags.predicate_view()))
}) })
} }

View File

@@ -162,6 +162,28 @@ pub enum Error {
/// A result returned when changing a setting. /// A result returned when changing a setting.
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
/// A reference to just the boolean predicates of a settings object.
///
/// The settings objects themselves are generated and appear in the `isa/*/settings.rs` modules.
/// Each settings object provides a `predicate_view()` method that makes it possible to query
/// ISA predicates by number.
#[derive(Clone, Copy)]
pub struct PredicateView<'a>(&'a [u8]);
impl<'a> PredicateView<'a> {
/// Create a new view of a precomputed predicate vector.
///
/// See the `predicate_view()` method on the various `Flags` types defined for each ISA.
pub fn new(bits: &'a [u8]) -> PredicateView {
PredicateView(bits)
}
/// Check a numbered predicate.
pub fn test(self, p: usize) -> bool {
self.0[p / 8] & (1 << (p % 8)) != 0
}
}
/// Implementation details for generated code. /// Implementation details for generated code.
/// ///
/// This module holds definitions that need to be public so the can be instantiated by generated /// This module holds definitions that need to be public so the can be instantiated by generated