diff --git a/lib/cretonne/src/constant_hash.rs b/lib/cretonne/src/constant_hash.rs index 08cc2944c8..a165654dce 100644 --- a/lib/cretonne/src/constant_hash.rs +++ b/lib/cretonne/src/constant_hash.rs @@ -24,8 +24,12 @@ pub trait Table { /// The provided `hash` value must have been computed from `key` using the same hash function that /// was used to construct the table. /// -/// Returns the table index containing the found entry, or `None` if no entry could be found. -pub fn probe + ?Sized>(table: &T, key: K, hash: usize) -> Option { +/// Returns `Ok(idx)` with the table index containing the found entry, or `Err(idx)` with the empty +/// sentinel entry if no entry could be found. +pub fn probe + ?Sized>(table: &T, + key: K, + hash: usize) + -> Result { debug_assert!(table.len().is_power_of_two()); let mask = table.len() - 1; @@ -36,8 +40,8 @@ pub fn probe + ?Sized>(table: &T, key: K, hash: usize) idx &= mask; match table.key(idx) { - None => return None, - Some(k) if k == key => return Some(idx), + None => return Err(idx), + Some(k) if k == key => return Ok(idx), _ => {} } diff --git a/lib/cretonne/src/ir/instructions.rs b/lib/cretonne/src/ir/instructions.rs index 808b7cc01a..279a7a37a9 100644 --- a/lib/cretonne/src/ir/instructions.rs +++ b/lib/cretonne/src/ir/instructions.rs @@ -85,10 +85,10 @@ impl FromStr for Opcode { } match probe::<&str, [Option]>(&OPCODE_HASH_TABLE, s, simple_hash(s)) { - None => Err("Unknown opcode"), + Err(_) => Err("Unknown opcode"), // We unwrap here because probe() should have ensured that the entry // at this index is not None. - Some(i) => Ok(OPCODE_HASH_TABLE[i].unwrap()), + Ok(i) => Ok(OPCODE_HASH_TABLE[i].unwrap()), } } } diff --git a/lib/cretonne/src/isa/enc_tables.rs b/lib/cretonne/src/isa/enc_tables.rs index 3467a2bdfd..b53e80036e 100644 --- a/lib/cretonne/src/isa/enc_tables.rs +++ b/lib/cretonne/src/isa/enc_tables.rs @@ -5,6 +5,7 @@ use ir::{Type, Opcode, InstructionData}; use isa::{Encoding, Legalize}; use constant_hash::{Table, probe}; +use std::ops::Range; /// Level 1 hash table entry. /// @@ -27,6 +28,14 @@ pub struct Level1Entry + Copy> { pub offset: OffT, } +impl + Copy> Level1Entry { + /// Get the level 2 table range indicated by this entry. + fn range(&self) -> Range { + let b = self.offset.into() as usize; + b..b + (1 << self.log2len) + } +} + impl + Copy> Table for [Level1Entry] { fn len(&self) -> usize { self.len() @@ -83,20 +92,23 @@ pub fn lookup_enclist(ctrl_typevar: Type, OffT2: Into + Copy { // TODO: The choice of legalization actions here is naive. This needs to be configurable. - probe(level1_table, ctrl_typevar, ctrl_typevar.index()) - .ok_or_else(|| if ctrl_typevar.lane_type().bits() > 32 { - Legalize::Narrow - } else { - Legalize::Expand - }) - .and_then(|l1idx| { - let l1ent = &level1_table[l1idx]; - let l2off = l1ent.offset.into() as usize; - let l2tab = &level2_table[l2off..l2off + (1 << l1ent.log2len)]; - probe(l2tab, opcode, opcode as usize) - .map(|l2idx| l2tab[l2idx].offset.into() as usize) - .ok_or(Legalize::Expand) - }) + match probe(level1_table, ctrl_typevar, ctrl_typevar.index()) { + Err(_) => { + // No level 1 entry for the type. + Err(if ctrl_typevar.lane_type().bits() > 32 { + Legalize::Narrow + } else { + Legalize::Expand + }) + } + Ok(l1idx) => { + let l1ent = &level1_table[l1idx]; + let l2tab = &level2_table[l1ent.range()]; + probe(l2tab, opcode, opcode as usize) + .map(|l2idx| l2tab[l2idx].offset.into() as usize) + .map_err(|_| Legalize::Expand) + } + } } /// Encoding list entry. diff --git a/lib/cretonne/src/settings.rs b/lib/cretonne/src/settings.rs index 19b9fafc21..be5140ef34 100644 --- a/lib/cretonne/src/settings.rs +++ b/lib/cretonne/src/settings.rs @@ -83,8 +83,8 @@ impl Builder { /// Look up a descriptor by name. fn lookup(&self, name: &str) -> Result<(usize, detail::Detail)> { match probe(self.template, name, simple_hash(name)) { - None => Err(Error::BadName), - Some(entry) => { + Err(_) => Err(Error::BadName), + Ok(entry) => { let d = &self.template.descriptors[self.template.hash_table[entry] as usize]; Ok((d.offset as usize, d.detail)) }