diff --git a/cranelift/isle/isle/src/codegen.rs b/cranelift/isle/isle/src/codegen.rs index 6968302286..103c58eda7 100644 --- a/cranelift/isle/isle/src/codegen.rs +++ b/cranelift/isle/isle/src/codegen.rs @@ -651,7 +651,7 @@ impl<'a> Codegen<'a> { indent: &str, ctx: &mut BodyContext, ) -> bool { - log::trace!("generate_body: trie {:?}", trie); + log::trace!("generate_body:\n{}", trie.pretty()); let mut returned = false; match trie { &TrieNode::Empty => {} @@ -692,10 +692,16 @@ impl<'a> Codegen<'a> { let mut i = 0; while i < edges.len() { + // Gather adjacent match variants so that we can turn these + // into a `match` rather than a sequence of `if let`s. let mut last = i; let mut adjacent_variants = BTreeSet::new(); let mut adjacent_variant_input = None; - log::trace!("edge: {:?}", edges[i]); + log::trace!( + "edge: range = {:?}, symbol = {:?}", + edges[i].range, + edges[i].symbol + ); while last < edges.len() { match &edges[last].symbol { &TrieSymbol::Match { @@ -719,11 +725,11 @@ impl<'a> Codegen<'a> { } } - // edges[i..last] is a run of adjacent - // MatchVariants (possibly an empty one). Only use - // a `match` form if there are at least two - // adjacent options. + // Now `edges[i..last]` is a run of adjacent `MatchVariants` + // (possibly an empty one). Only use a `match` form if there + // are at least two adjacent options. if last - i > 1 { + eprintln!("FITZGEN: generating body matches"); self.generate_body_matches(code, depth, &edges[i..last], indent, ctx); i = last; continue; @@ -738,8 +744,13 @@ impl<'a> Codegen<'a> { match symbol { &TrieSymbol::EndOfMatch => { returned = self.generate_body(code, depth + 1, node, indent, ctx); + eprintln!( + "FITZGEN: generated end-of-match; returned = {:?}", + returned + ); } &TrieSymbol::Match { ref op } => { + eprintln!("FITZGEN: generating [if] let"); let id = InstId(depth); let infallible = self.generate_pattern_inst(code, id, op, indent, ctx); diff --git a/cranelift/isle/isle/src/ir.rs b/cranelift/isle/isle/src/ir.rs index b3daa2e7b3..caa0090864 100644 --- a/cranelift/isle/isle/src/ir.rs +++ b/cranelift/isle/isle/src/ir.rs @@ -31,15 +31,6 @@ pub enum Value { /// A single Pattern instruction. #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum PatternInst { - /// Get the Nth input argument, which corresponds to the Nth field - /// of the root term. - Arg { - /// The index of the argument to get. - index: usize, - /// The type of the argument. - ty: TypeId, - }, - /// Match a value as equal to another value. Produces no values. MatchEqual { /// The first value. @@ -83,6 +74,21 @@ pub enum PatternInst { variant: VariantId, }, + /// Evaluate an expression and provide the given value as the result of this + /// match instruction. The expression has access to the pattern-values up to + /// this point in the sequence. + Expr { + /// The expression to evaluate. + seq: ExprSequence, + /// The value produced by the expression. + output: Value, + /// The type of the output value. + output_ty: TypeId, + }, + + // NB: this has to come second-to-last, because it might be infallible, for + // the same reasons that `Arg` has to be last. + // /// Invoke an extractor, taking the given values as input (the first is the /// value to extract, the other are the `Input`-polarity extractor args) and /// producing an output value for each `Output`-polarity extractor arg. @@ -99,16 +105,17 @@ pub enum PatternInst { infallible: bool, }, - /// Evaluate an expression and provide the given value as the result of this - /// match instruction. The expression has access to the pattern-values up to - /// this point in the sequence. - Expr { - /// The expression to evaluate. - seq: ExprSequence, - /// The value produced by the expression. - output: Value, - /// The type of the output value. - output_ty: TypeId, + // NB: This has to go last, since it is infallible, so that when we sort + // edges in the trie, we visit infallible edges after first having tried the + // more-specific fallible options. + // + /// Get the Nth input argument, which corresponds to the Nth field + /// of the root term. + Arg { + /// The index of the argument to get. + index: usize, + /// The type of the argument. + ty: TypeId, }, }