cranelift-isle: Helpers to get type/term by name (#5241)

This is a common pattern in sema, so factor it out.

Since this version uses `intern` instead of `intern_mut`, it might be a
tiny bit faster when errors occur due to not writing names into maps
then. When no error occurs, ISLE should do exactly the same work with or
without this commit.
This commit is contained in:
Jamey Sharp
2022-11-10 09:51:49 -08:00
committed by GitHub
parent 2be457c295
commit f0fccbd18a

View File

@@ -14,7 +14,6 @@
//! the opposite). //! the opposite).
use crate::ast; use crate::ast;
use crate::ast::Ident;
use crate::error::*; use crate::error::*;
use crate::lexer::Pos; use crate::lexer::Pos;
use crate::log; use crate::log;
@@ -947,9 +946,8 @@ impl TypeEnv {
ref ty, ref ty,
pos, pos,
}) => { }) => {
let ty = tyenv.intern_mut(ty); let ty = match tyenv.get_type_by_name(ty) {
let ty = match tyenv.type_map.get(&ty) { Some(ty) => ty,
Some(ty) => *ty,
None => { None => {
tyenv.report_error(pos, "Unknown type for constant"); tyenv.report_error(pos, "Unknown type for constant");
continue; continue;
@@ -1022,9 +1020,8 @@ impl TypeEnv {
); );
return None; return None;
} }
let field_ty = self.intern_mut(&field.ty); let field_tid = match self.get_type_by_name(&field.ty) {
let field_tid = match self.type_map.get(&field_ty) { Some(tid) => tid,
Some(tid) => *tid,
None => { None => {
self.report_error( self.report_error(
field.ty.1, field.ty.1,
@@ -1091,7 +1088,13 @@ impl TypeEnv {
} }
fn intern(&self, ident: &ast::Ident) -> Option<Sym> { fn intern(&self, ident: &ast::Ident) -> Option<Sym> {
self.sym_map.get(&ident.0).cloned() self.sym_map.get(&ident.0).copied()
}
fn get_type_by_name(&self, sym: &ast::Ident) -> Option<TypeId> {
self.intern(sym)
.and_then(|sym| self.type_map.get(&sym))
.copied()
} }
} }
@@ -1167,8 +1170,7 @@ impl TermEnv {
.arg_tys .arg_tys
.iter() .iter()
.map(|id| { .map(|id| {
let sym = tyenv.intern_mut(id); tyenv.get_type_by_name(id).ok_or_else(|| {
tyenv.type_map.get(&sym).cloned().ok_or_else(|| {
tyenv.report_error(id.1, format!("Unknown arg type: '{}'", id.0)); tyenv.report_error(id.1, format!("Unknown arg type: '{}'", id.0));
() ()
}) })
@@ -1180,9 +1182,7 @@ impl TermEnv {
continue; continue;
} }
}; };
let ret_ty = { let ret_ty = match tyenv.get_type_by_name(&decl.ret_ty) {
let sym = tyenv.intern_mut(&decl.ret_ty);
match tyenv.type_map.get(&sym).cloned() {
Some(t) => t, Some(t) => t,
None => { None => {
tyenv.report_error( tyenv.report_error(
@@ -1191,7 +1191,6 @@ impl TermEnv {
); );
continue; continue;
} }
}
}; };
let tid = TermId(self.terms.len()); let tid = TermId(self.terms.len());
@@ -1271,9 +1270,8 @@ impl TermEnv {
continue; continue;
} }
}; };
let sym = tyenv.intern_mut(&term); let term = match self.get_term_by_name(tyenv, &term) {
let term = match self.term_map.get(&sym) { Some(tid) => tid,
Some(&tid) => tid,
None => { None => {
tyenv tyenv
.report_error(pos, "Rule LHS root term is not defined".to_string()); .report_error(pos, "Rule LHS root term is not defined".to_string());
@@ -1324,8 +1322,7 @@ impl TermEnv {
for def in &defs.defs { for def in &defs.defs {
if let &ast::Def::Extractor(ref ext) = def { if let &ast::Def::Extractor(ref ext) = def {
let sym = tyenv.intern_mut(&ext.term); let term = match self.get_term_by_name(tyenv, &ext.term) {
let term = match self.term_map.get(&sym) {
Some(x) => x, Some(x) => x,
None => { None => {
tyenv.report_error( tyenv.report_error(
@@ -1341,8 +1338,7 @@ impl TermEnv {
let mut callees = BTreeSet::new(); let mut callees = BTreeSet::new();
template.terms(&mut |pos, t| { template.terms(&mut |pos, t| {
let sym = tyenv.intern_mut(t); if let Some(term) = self.get_term_by_name(tyenv, t) {
if let Some(term) = self.term_map.get(&sym) {
callees.insert(term); callees.insert(term);
} else { } else {
tyenv.report_error( tyenv.report_error(
@@ -1454,9 +1450,8 @@ impl TermEnv {
ref outer_ty, ref outer_ty,
pos, pos,
}) => { }) => {
let inner_ty_sym = tyenv.intern_mut(inner_ty); let inner_ty_id = match tyenv.get_type_by_name(inner_ty) {
let inner_ty_id = match tyenv.type_map.get(&inner_ty_sym) { Some(ty) => ty,
Some(ty) => *ty,
None => { None => {
tyenv.report_error( tyenv.report_error(
inner_ty.1, inner_ty.1,
@@ -1466,9 +1461,8 @@ impl TermEnv {
} }
}; };
let outer_ty_sym = tyenv.intern_mut(outer_ty); let outer_ty_id = match tyenv.get_type_by_name(outer_ty) {
let outer_ty_id = match tyenv.type_map.get(&outer_ty_sym) { Some(ty) => ty,
Some(ty) => *ty,
None => { None => {
tyenv.report_error( tyenv.report_error(
outer_ty.1, outer_ty.1,
@@ -1478,9 +1472,8 @@ impl TermEnv {
} }
}; };
let term_sym = tyenv.intern_mut(term); let term_id = match self.get_term_by_name(tyenv, term) {
let term_id = match self.term_map.get(&term_sym) { Some(term_id) => term_id,
Some(term_id) => *term_id,
None => { None => {
tyenv.report_error( tyenv.report_error(
term.1, term.1,
@@ -1519,9 +1512,8 @@ impl TermEnv {
ref func, ref func,
pos, pos,
}) => { }) => {
let term_sym = tyenv.intern_mut(term);
let func_sym = tyenv.intern_mut(func); let func_sym = tyenv.intern_mut(func);
let term_id = match self.term_map.get(&term_sym) { let term_id = match self.get_term_by_name(tyenv, term) {
Some(term) => term, Some(term) => term,
None => { None => {
tyenv.report_error( tyenv.report_error(
@@ -1573,9 +1565,8 @@ impl TermEnv {
pos, pos,
infallible, infallible,
}) => { }) => {
let term_sym = tyenv.intern_mut(term);
let func_sym = tyenv.intern_mut(func); let func_sym = tyenv.intern_mut(func);
let term_id = match self.term_map.get(&term_sym) { let term_id = match self.get_term_by_name(tyenv, term) {
Some(term) => term, Some(term) => term,
None => { None => {
tyenv.report_error( tyenv.report_error(
@@ -1644,10 +1635,8 @@ impl TermEnv {
let mut bindings = Bindings::default(); let mut bindings = Bindings::default();
let rule_term = match rule.pattern.root_term() { let rule_term = match rule.pattern.root_term() {
Some(name) => { Some(name) => match self.get_term_by_name(tyenv, name) {
let sym = tyenv.intern_mut(name); Some(term) => term,
match self.term_map.get(&sym) {
Some(term) => *term,
None => { None => {
tyenv.report_error( tyenv.report_error(
pos, pos,
@@ -1655,8 +1644,7 @@ impl TermEnv {
); );
continue; continue;
} }
} },
}
None => { None => {
tyenv.report_error( tyenv.report_error(
pos, pos,
@@ -1720,8 +1708,7 @@ impl TermEnv {
fn check_for_undefined_decls(&self, tyenv: &mut TypeEnv, defs: &ast::Defs) { fn check_for_undefined_decls(&self, tyenv: &mut TypeEnv, defs: &ast::Defs) {
for def in &defs.defs { for def in &defs.defs {
if let ast::Def::Decl(decl) = def { if let ast::Def::Decl(decl) = def {
let sym = tyenv.intern_mut(&decl.term); let term = self.get_term_by_name(tyenv, &decl.term).unwrap();
let term = self.term_map[&sym];
let term = &self.terms[term.index()]; let term = &self.terms[term.index()];
if !term.has_constructor() && !term.has_extractor() { if !term.has_constructor() && !term.has_extractor() {
tyenv.report_error( tyenv.report_error(
@@ -1740,8 +1727,7 @@ impl TermEnv {
for def in &defs.defs { for def in &defs.defs {
if let ast::Def::Rule(rule) = def { if let ast::Def::Rule(rule) = def {
rule.expr.terms(&mut |pos, ident| { rule.expr.terms(&mut |pos, ident| {
let sym = tyenv.intern_mut(ident); let term = match self.get_term_by_name(tyenv, ident) {
let term = match self.term_map.get(&sym) {
None => { None => {
debug_assert!(!tyenv.errors.is_empty()); debug_assert!(!tyenv.errors.is_empty());
return; return;
@@ -1778,7 +1764,7 @@ impl TermEnv {
// re-resolved. The pos doesn't matter // re-resolved. The pos doesn't matter
// as it shouldn't result in a lookup // as it shouldn't result in a lookup
// failure. // failure.
let converter_term_ident = Ident( let converter_term_ident = ast::Ident(
tyenv.syms[self.terms[converter_term.index()].name.index()].clone(), tyenv.syms[self.terms[converter_term.index()].name.index()].clone(),
pattern.pos(), pattern.pos(),
); );
@@ -1953,9 +1939,8 @@ impl TermEnv {
ref args, ref args,
pos, pos,
} => { } => {
let name = tyenv.intern_mut(&sym);
// Look up the term. // Look up the term.
let tid = match self.term_map.get(&name) { let tid = match self.get_term_by_name(tyenv, sym) {
Some(t) => t, Some(t) => t,
None => { None => {
tyenv.report_error(pos, format!("Unknown term in pattern: '{}'", sym.0)); tyenv.report_error(pos, format!("Unknown term in pattern: '{}'", sym.0));
@@ -2019,7 +2004,7 @@ impl TermEnv {
TermKind::Decl { TermKind::Decl {
constructor_kind: Some(ConstructorKind::InternalConstructor), constructor_kind: Some(ConstructorKind::InternalConstructor),
.. ..
} if is_root && *tid == rule_term => {} } if is_root && tid == rule_term => {}
TermKind::EnumVariant { .. } => {} TermKind::EnumVariant { .. } => {}
TermKind::Decl { TermKind::Decl {
extractor_kind: Some(ExtractorKind::ExternalExtractor { .. }), extractor_kind: Some(ExtractorKind::ExternalExtractor { .. }),
@@ -2079,7 +2064,7 @@ impl TermEnv {
subpats.push(subpat); subpats.push(subpat);
} }
Some((Pattern::Term(ty, *tid, subpats), ty)) Some((Pattern::Term(ty, tid, subpats), ty))
} }
&ast::Pattern::MacroArg { .. } => unreachable!(), &ast::Pattern::MacroArg { .. } => unreachable!(),
} }
@@ -2126,9 +2111,8 @@ impl TermEnv {
} => { } => {
// Look up the term. // Look up the term.
let name = tyenv.intern_mut(&sym); let name = tyenv.intern_mut(&sym);
// Look up the term.
let tid = match self.term_map.get(&name) { let tid = match self.term_map.get(&name) {
Some(t) => t, Some(&t) => t,
None => { None => {
// Maybe this was actually a variable binding and the user has placed // Maybe this was actually a variable binding and the user has placed
// parens around it by mistake? (See #4775.) // parens around it by mistake? (See #4775.)
@@ -2183,7 +2167,7 @@ impl TermEnv {
pos, pos,
format!( format!(
"Used non-pure constructor '{}' in pure expression context", "Used non-pure constructor '{}' in pure expression context",
tyenv.syms[name.index()] sym.0
), ),
); );
} }
@@ -2219,7 +2203,7 @@ impl TermEnv {
subexprs.push(subexpr); subexprs.push(subexpr);
} }
Some(Expr::Term(ty, *tid, subexprs)) Some(Expr::Term(ty, tid, subexprs))
} }
&ast::Expr::Var { ref name, pos } => { &ast::Expr::Var { ref name, pos } => {
let sym = tyenv.intern_mut(name); let sym = tyenv.intern_mut(name);
@@ -2313,18 +2297,8 @@ impl TermEnv {
let name = tyenv.intern_mut(&def.var); let name = tyenv.intern_mut(&def.var);
// Look up the type. // Look up the type.
let tysym = match tyenv.intern(&def.ty) { let tid = match tyenv.get_type_by_name(&def.ty) {
Some(ty) => ty, Some(tid) => tid,
None => {
tyenv.report_error(
pos,
format!("Unknown type {} for variable '{}'", def.ty.0, def.var.0),
);
continue;
}
};
let tid = match tyenv.type_map.get(&tysym) {
Some(tid) => *tid,
None => { None => {
tyenv.report_error( tyenv.report_error(
pos, pos,
@@ -2402,6 +2376,13 @@ impl TermEnv {
Some(IfLet { lhs, rhs }) Some(IfLet { lhs, rhs })
} }
fn get_term_by_name(&self, tyenv: &TypeEnv, sym: &ast::Ident) -> Option<TermId> {
tyenv
.intern(sym)
.and_then(|sym| self.term_map.get(&sym))
.copied()
}
} }
#[cfg(test)] #[cfg(test)]