[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:
@@ -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
|
||||||
|
|||||||
@@ -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, "}");
|
||||||
|
|
||||||
|
|||||||
@@ -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;");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Guard the actual expansion by `predicate`.
|
||||||
|
if has_extra_constraints {
|
||||||
|
fmt.line("if predicate {");
|
||||||
|
fmt.indent(|fmt| {
|
||||||
|
do_expand(fmt);
|
||||||
});
|
});
|
||||||
fmt.line("}");
|
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>(
|
||||||
|
|||||||
Reference in New Issue
Block a user