Prepare legalizer codegen for SIMD features

Contains fixes from @bnjbvr to codegen as a part of https://github.com/bnjbvr/cranelift/pull/2; necessary for SIMD features to work
This commit is contained in:
Andrew Brown
2019-07-11 10:09:58 -07:00
committed by Dan Gohman
parent 67dd0b5015
commit 8378297f33

View File

@@ -51,7 +51,7 @@ fn unwrap_inst(
fmtln!( fmtln!(
fmt, fmt,
"let ({}, predicate) = if let ir::InstructionData::{} {{", "let ({}, predicate) = if let crate::ir::InstructionData::{} {{",
arg_names, arg_names,
iform.name iform.name
); );
@@ -135,11 +135,10 @@ fn unwrap_inst(
.to_comment_string(var_pool) .to_comment_string(var_pool)
)); ));
fmt.line("let results = pos.func.dfg.inst_results(inst);"); fmt.line("let r = pos.func.dfg.inst_results(inst);");
for (i, &var_index) in def.defined_vars.iter().enumerate() { for (i, &var_index) in def.defined_vars.iter().enumerate() {
let var = var_pool.get(var_index); let var = var_pool.get(var_index);
fmtln!(fmt, "let {} = &results[{}];", var.name, i); fmtln!(fmt, "let {} = &r[{}];", var.name, i);
if var.has_free_typevar() {
fmtln!( fmtln!(
fmt, fmt,
"let typeof_{} = pos.func.dfg.value_type(*{});", "let typeof_{} = pos.func.dfg.value_type(*{});",
@@ -147,7 +146,6 @@ fn unwrap_inst(
var.name var.name
); );
} }
}
replace_inst = true; replace_inst = true;
} else { } else {
@@ -187,11 +185,15 @@ fn build_derived_expr(tv: &TypeVar) -> String {
Some(base) => base, Some(base) => base,
None => { None => {
assert!(tv.name.starts_with("typeof_")); assert!(tv.name.starts_with("typeof_"));
return format!("{}", tv.name); return format!("Some({})", tv.name);
} }
}; };
let base_expr = build_derived_expr(&base.type_var); let base_expr = build_derived_expr(&base.type_var);
format!("{}.{}()", base_expr, base.derived_func.name()) format!(
"{}.map(|t: crate::ir::Type| t.{}())",
base_expr,
base.derived_func.name()
)
} }
/// Emit rust code for the given check. /// Emit rust code for the given check.
@@ -221,18 +223,29 @@ fn emit_runtime_typecheck<'a, 'b>(
Constraint::Eq(tv1, tv2) => { Constraint::Eq(tv1, tv2) => {
fmtln!( fmtln!(
fmt, fmt,
"let predicate = predicate && {} == {};", "let predicate = predicate && match ({}, {}) {{",
build_derived_expr(tv1), build_derived_expr(tv1),
build_derived_expr(tv2) build_derived_expr(tv2)
); );
fmt.indent(|fmt| {
fmt.line("(Some(a), Some(b)) => a == b,");
fmt.comment("On overflow, constraint doesn\'t apply");
fmt.line("_ => false,");
});
fmtln!(fmt, "};");
} }
Constraint::WiderOrEq(tv1, tv2) => { Constraint::WiderOrEq(tv1, tv2) => {
fmtln!( fmtln!(
fmt, fmt,
"let predicate = predicate && {}.wider_or_equal({});", "let predicate = predicate && match ({}, {}) {{",
build_derived_expr(tv1), build_derived_expr(tv1),
build_derived_expr(tv2) build_derived_expr(tv2)
); );
fmt.indent(|fmt| {
fmt.line("(Some(a), Some(b)) => a.wider_or_equal(b),");
fmt.comment("On overflow, constraint doesn\'t apply");
fmt.line("_ => false,");
});
fmtln!(fmt, "};"); fmtln!(fmt, "};");
} }
} }
@@ -290,7 +303,8 @@ fn emit_dst_inst(def: &Def, def_pool: &DefPool, var_pool: &VarPool, fmt: &mut Fo
// Unwrapping would have left the results intact. Replace the whole instruction. // Unwrapping would have left the results intact. Replace the whole instruction.
fmtln!( fmtln!(
fmt, fmt,
"pos.func.dfg.replace(inst).{};", "let {} = pos.func.dfg.replace(inst).{};",
defined_vars,
def.apply.rust_builder(&def.defined_vars, var_pool) def.apply.rust_builder(&def.defined_vars, var_pool)
); );
@@ -406,16 +420,17 @@ fn gen_transform_group<'a>(
// Function arguments. // Function arguments.
fmtln!(fmt, "pub fn {}(", group.name); fmtln!(fmt, "pub fn {}(", group.name);
fmt.indent(|fmt| { fmt.indent(|fmt| {
fmt.line("inst: ir::Inst,"); fmt.line("inst: crate::ir::Inst,");
fmt.line("func: &mut ir::Function,"); fmt.line("func: &mut crate::ir::Function,");
fmt.line("cfg: &mut ControlFlowGraph,"); fmt.line("cfg: &mut crate::flowgraph::ControlFlowGraph,");
fmt.line("isa: &dyn TargetIsa,"); fmt.line("isa: &dyn crate::isa::TargetIsa,");
}); });
fmtln!(fmt, ") -> bool {"); fmtln!(fmt, ") -> bool {");
// Function body. // Function body.
fmt.indent(|fmt| { fmt.indent(|fmt| {
fmt.line("use ir::InstBuilder;"); fmt.line("use crate::ir::InstBuilder;");
fmt.line("use crate::cursor::{Cursor, FuncCursor};");
fmt.line("let mut pos = FuncCursor::new(func).at_inst(inst);"); fmt.line("let mut pos = FuncCursor::new(func).at_inst(inst);");
fmt.line("pos.use_srcloc(inst);"); fmt.line("pos.use_srcloc(inst);");