[meta] Legalization: don't emit a spurious if true for transforms that always apply;

This enhances readability of the generated legalizer code by replacing
`if true { body }` with `body`.
This commit is contained in:
Benjamin Bouvier
2019-07-04 19:48:10 +02:00
parent 350b3b2406
commit 687604d33a
3 changed files with 38 additions and 22 deletions

View File

@@ -1169,17 +1169,18 @@ impl InstructionPredicate {
self self
} }
pub fn rust_predicate(&self, func_str: &str) -> String { pub fn rust_predicate(&self, func_str: &str) -> Option<String> {
match &self.node { self.node.as_ref().map(|root| root.rust_predicate(func_str))
Some(root) => root.rust_predicate(func_str),
None => "true".into(),
}
} }
/// Returns true if the predicate only depends on type parameters (and not on an instruction /// Returns the type predicate if this is one, or None otherwise.
/// format). pub fn type_predicate(&self, func_str: &str) -> Option<String> {
pub fn is_type_predicate(&self) -> bool { let node = self.node.as_ref().unwrap();
self.node.as_ref().unwrap().is_type_predicate() 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 /// Returns references to all the nodes that are leaves in the condition (i.e. by flattening

View File

@@ -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 /// 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. /// unexpected format. This should lead to a panic.
fn emit_instp(instp: &InstructionPredicate, has_func: bool, fmt: &mut Formatter) { 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("let args = inst.arguments(&func.dfg.value_lists);");
fmt.line(instp.rust_predicate("func")); fmt.line(type_predicate);
return; return;
} }
@@ -127,7 +127,7 @@ fn emit_instp(instp: &InstructionPredicate, has_func: bool, fmt: &mut Formatter)
// Silence dead argument. // Silence dead argument.
fmt.line("let _ = func;"); fmt.line("let _ = func;");
} }
fmtln!(fmt, "return {};", instp.rust_predicate("func")); fmtln!(fmt, "return {};", instp.rust_predicate("func").unwrap());
}); });
fmtln!(fmt, "}"); fmtln!(fmt, "}");

View File

@@ -452,7 +452,11 @@ fn gen_transform<'a>(
if has_extra_constraints { if has_extra_constraints {
// Extra constraints rely on the predicate being a variable that we can rebind as we add // Extra constraints rely on the predicate being a variable that we can rebind as we add
// more constraint predicates. // 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. // 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); emit_runtime_typecheck(constraint, type_sets, fmt);
} }
// Guard the actual expansion by `predicate`. let do_expand = |fmt: &mut Formatter| {
if has_extra_constraints {
fmt.line("if predicate {");
} else {
fmt.multi_line(&format!("if {} {{", inst_predicate))
}
fmt.indent(|fmt| {
// Emit any constants that must be created before use. // Emit any constants that must be created before use.
for (name, value) in transform.const_pool.iter() { for (name, value) in transform.const_pool.iter() {
fmtln!( fmtln!(
@@ -538,8 +536,25 @@ fn gen_transform<'a>(
} }
fmt.line("return true;"); 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>( fn gen_transform_group<'a>(