diff --git a/cranelift/codegen/meta/src/cdsl/instructions.rs b/cranelift/codegen/meta/src/cdsl/instructions.rs index a62cf39e05..699e30cb3f 100644 --- a/cranelift/codegen/meta/src/cdsl/instructions.rs +++ b/cranelift/codegen/meta/src/cdsl/instructions.rs @@ -1169,17 +1169,18 @@ impl InstructionPredicate { self } - pub fn rust_predicate(&self, func_str: &str) -> String { - match &self.node { - Some(root) => root.rust_predicate(func_str), - None => "true".into(), - } + pub fn rust_predicate(&self, func_str: &str) -> Option { + self.node.as_ref().map(|root| root.rust_predicate(func_str)) } - /// Returns true if the predicate only depends on type parameters (and not on an instruction - /// format). - pub fn is_type_predicate(&self) -> bool { - self.node.as_ref().unwrap().is_type_predicate() + /// Returns the type predicate if this is one, or None otherwise. + pub fn type_predicate(&self, func_str: &str) -> Option { + let node = self.node.as_ref().unwrap(); + if node.is_type_predicate() { + Some(node.rust_predicate(func_str)) + } else { + None + } } /// Returns references to all the nodes that are leaves in the condition (i.e. by flattening diff --git a/cranelift/codegen/meta/src/gen_encodings.rs b/cranelift/codegen/meta/src/gen_encodings.rs index 1a1a439c49..86046cfde1 100644 --- a/cranelift/codegen/meta/src/gen_encodings.rs +++ b/cranelift/codegen/meta/src/gen_encodings.rs @@ -76,9 +76,9 @@ use crate::unique_table::UniqueSeqTable; /// The generated code is an `if let` pattern match that falls through if the instruction has an /// unexpected format. This should lead to a panic. fn emit_instp(instp: &InstructionPredicate, has_func: bool, fmt: &mut Formatter) { - if instp.is_type_predicate() { + if let Some(type_predicate) = instp.type_predicate("func") { fmt.line("let args = inst.arguments(&func.dfg.value_lists);"); - fmt.line(instp.rust_predicate("func")); + fmt.line(type_predicate); return; } @@ -127,7 +127,7 @@ fn emit_instp(instp: &InstructionPredicate, has_func: bool, fmt: &mut Formatter) // Silence dead argument. fmt.line("let _ = func;"); } - fmtln!(fmt, "return {};", instp.rust_predicate("func")); + fmtln!(fmt, "return {};", instp.rust_predicate("func").unwrap()); }); fmtln!(fmt, "}"); diff --git a/cranelift/codegen/meta/src/gen_legalizer.rs b/cranelift/codegen/meta/src/gen_legalizer.rs index ac79f8af33..d71f97b10d 100644 --- a/cranelift/codegen/meta/src/gen_legalizer.rs +++ b/cranelift/codegen/meta/src/gen_legalizer.rs @@ -452,7 +452,11 @@ fn gen_transform<'a>( if has_extra_constraints { // Extra constraints rely on the predicate being a variable that we can rebind as we add // more constraint predicates. - fmt.multi_line(&format!("let predicate = {};", inst_predicate)); + if let Some(pred) = &inst_predicate { + fmt.multi_line(&format!("let predicate = {};", pred)); + } else { + fmt.line("let predicate = true;"); + } } // Emit any runtime checks; these will rebind `predicate` emitted right above. @@ -460,13 +464,7 @@ fn gen_transform<'a>( emit_runtime_typecheck(constraint, type_sets, fmt); } - // Guard the actual expansion by `predicate`. - if has_extra_constraints { - fmt.line("if predicate {"); - } else { - fmt.multi_line(&format!("if {} {{", inst_predicate)) - } - fmt.indent(|fmt| { + let do_expand = |fmt: &mut Formatter| { // Emit any constants that must be created before use. for (name, value) in transform.const_pool.iter() { fmtln!( @@ -538,8 +536,25 @@ fn gen_transform<'a>( } fmt.line("return true;"); - }); - fmt.line("}"); + }; + + // Guard the actual expansion by `predicate`. + if has_extra_constraints { + fmt.line("if predicate {"); + fmt.indent(|fmt| { + do_expand(fmt); + }); + fmt.line("}"); + } else if let Some(pred) = &inst_predicate { + fmt.multi_line(&format!("if {} {{", pred)); + fmt.indent(|fmt| { + do_expand(fmt); + }); + fmt.line("}"); + } else { + // Unconditional transform (there was no predicate), just emit it. + do_expand(fmt); + } } fn gen_transform_group<'a>(