Print constants in a comment in CLIF output (#4725)

When trying to read generated CLIF, it's nice to be able to see at a
glance that some of the operands are defined by `iconst` and similar
instructions, without having to go find each operand's definition
manually.
This commit is contained in:
Jamey Sharp
2022-08-17 09:00:20 -07:00
committed by GitHub
parent 2696462ccb
commit 3629bbbd55
7 changed files with 110 additions and 82 deletions

View File

@@ -7,7 +7,7 @@ use crate::entity::SecondaryMap;
use crate::ir::entities::AnyEntity; use crate::ir::entities::AnyEntity;
use crate::ir::{Block, DataFlowGraph, Function, Inst, SigRef, Type, Value, ValueDef}; use crate::ir::{Block, DataFlowGraph, Function, Inst, SigRef, Type, Value, ValueDef};
use crate::packed_option::ReservedValue; use crate::packed_option::ReservedValue;
use alloc::string::String; use alloc::string::{String, ToString};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::fmt::{self, Write}; use core::fmt::{self, Write};
@@ -530,7 +530,26 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt
FloatCondTrap { FloatCondTrap {
cond, arg, code, .. cond, arg, code, ..
} => write!(w, " {} {}, {}", cond, arg, code), } => write!(w, " {} {}, {}", cond, arg, code),
}?;
let mut sep = " ; ";
for &arg in dfg.inst_args(inst) {
if let ValueDef::Result(src, _) = dfg.value_def(arg) {
let imm = match dfg[src] {
UnaryImm { imm, .. } => imm.to_string(),
UnaryIeee32 { imm, .. } => imm.to_string(),
UnaryIeee64 { imm, .. } => imm.to_string(),
UnaryBool { imm, .. } => imm.to_string(),
UnaryConst {
constant_handle, ..
} => constant_handle.to_string(),
_ => continue,
};
write!(w, "{}{} = {}", sep, arg, imm)?;
sep = ", ";
} }
}
Ok(())
} }
/// Write block args using optional parantheses. /// Write block args using optional parantheses.

View File

@@ -48,11 +48,9 @@ function %fn_call_too_few_args() {
return return
} }
function %fn_call_too_many_args() { function %fn_call_too_many_args(i64, f32) {
fn5 = %best_fn() fn5 = %best_fn()
block0: block0(v0: i64, v1: f32):
v0 = iconst.i64 56
v1 = f32const 0.0
call fn5(v0, v1) ; error: mismatched argument count for `call fn5(v0, v1)`: got 2, expected 0 call fn5(v0, v1) ; error: mismatched argument count for `call fn5(v0, v1)`: got 2, expected 0
return return
} }

View File

@@ -1232,6 +1232,17 @@ mod tests {
sample_function(true) sample_function(true)
} }
#[track_caller]
fn check(func: &Function, expected_ir: &str) {
let actual_ir = func.display().to_string();
assert!(
expected_ir == actual_ir,
"Expected:\n{}\nGot:\n{}",
expected_ir,
actual_ir
);
}
/// Helper function to construct a fixed frontend configuration. /// Helper function to construct a fixed frontend configuration.
fn systemv_frontend_config() -> TargetFrontendConfig { fn systemv_frontend_config() -> TargetFrontendConfig {
TargetFrontendConfig { TargetFrontendConfig {
@@ -1271,8 +1282,8 @@ mod tests {
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
sig0 = (i64, i64, i64) system_v sig0 = (i64, i64, i64) system_v
fn0 = %Memcpy sig0 fn0 = %Memcpy sig0
@@ -1282,10 +1293,10 @@ block0:
v1 -> v3 v1 -> v3
v2 = iconst.i64 0 v2 = iconst.i64 0
v0 -> v2 v0 -> v2
call fn0(v1, v0, v1) call fn0(v1, v0, v1) ; v1 = 0, v0 = 0, v1 = 0
return v1 return v1 ; v1 = 0
} }
" ",
); );
} }
@@ -1327,19 +1338,19 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
block0: block0:
v4 = iconst.i64 0 v4 = iconst.i64 0
v1 -> v4 v1 -> v4
v3 = iconst.i64 0 v3 = iconst.i64 0
v0 -> v3 v0 -> v3
v2 = load.i64 aligned v0 v2 = load.i64 aligned v0 ; v0 = 0
store aligned v2, v1 store aligned v2, v1 ; v1 = 0
return v1 return v1 ; v1 = 0
} }
" ",
); );
} }
@@ -1381,8 +1392,8 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
sig0 = (i64, i64, i64) system_v sig0 = (i64, i64, i64) system_v
fn0 = %Memcpy sig0 fn0 = %Memcpy sig0
@@ -1393,10 +1404,10 @@ block0:
v3 = iconst.i64 0 v3 = iconst.i64 0
v0 -> v3 v0 -> v3
v2 = iconst.i64 8192 v2 = iconst.i64 8192
call fn0(v1, v0, v2) call fn0(v1, v0, v2) ; v1 = 0, v0 = 0, v2 = 8192
return v1 return v1 ; v1 = 0
} }
" ",
); );
} }
@@ -1426,17 +1437,17 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
block0: block0:
v2 = iconst.i64 0 v2 = iconst.i64 0
v0 -> v2 v0 -> v2
v1 = iconst.i64 0x0101_0101_0101_0101 v1 = iconst.i64 0x0101_0101_0101_0101
store aligned v1, v0 store aligned v1, v0 ; v1 = 0x0101_0101_0101_0101, v0 = 0
return v0 return v0 ; v0 = 0
} }
" ",
); );
} }
@@ -1466,8 +1477,8 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
sig0 = (i64, i32, i64) system_v sig0 = (i64, i32, i64) system_v
fn0 = %Memset sig0 fn0 = %Memset sig0
@@ -1477,11 +1488,11 @@ block0:
v0 -> v4 v0 -> v4
v1 = iconst.i8 1 v1 = iconst.i8 1
v2 = iconst.i64 8192 v2 = iconst.i64 8192
v3 = uextend.i32 v1 v3 = uextend.i32 v1 ; v1 = 1
call fn0(v0, v3, v2) call fn0(v0, v3, v2) ; v0 = 0, v2 = 8192
return v0 return v0 ; v0 = 0
} }
" ",
); );
} }
@@ -1530,8 +1541,8 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i32 system_v { "function %sample() -> i32 system_v {
sig0 = (i64, i64, i64) -> i32 system_v sig0 = (i64, i64, i64) -> i32 system_v
fn0 = %Memcmp sig0 fn0 = %Memcmp sig0
@@ -1543,10 +1554,10 @@ block0:
v1 -> v5 v1 -> v5
v4 = iconst.i64 0 v4 = iconst.i64 0
v0 -> v4 v0 -> v4
v3 = call fn0(v0, v1, v2) v3 = call fn0(v0, v1, v2) ; v0 = 0, v1 = 0, v2 = 0
return v3 return v3
} }
" ",
); );
} }
@@ -1561,7 +1572,7 @@ block0:
v3 = iconst.i64 0 v3 = iconst.i64 0
v0 -> v3 v0 -> v3
v2 = bconst.b1 true v2 = bconst.b1 true
return v2", return v2 ; v2 = true",
|builder, target, x, y| { |builder, target, x, y| {
builder.emit_small_memory_compare( builder.emit_small_memory_compare(
target.frontend_config(), target.frontend_config(),
@@ -1587,8 +1598,8 @@ block0:
v1 -> v6 v1 -> v6
v5 = iconst.i64 0 v5 = iconst.i64 0
v0 -> v5 v0 -> v5
v2 = load.i8 aligned v0 v2 = load.i8 aligned v0 ; v0 = 0
v3 = load.i8 aligned v1 v3 = load.i8 aligned v1 ; v1 = 0
v4 = icmp ugt v2, v3 v4 = icmp ugt v2, v3
return v4", return v4",
|builder, target, x, y| { |builder, target, x, y| {
@@ -1616,8 +1627,8 @@ block0:
v1 -> v6 v1 -> v6
v5 = iconst.i64 0 v5 = iconst.i64 0
v0 -> v5 v0 -> v5
v2 = load.i32 aligned v0 v2 = load.i32 aligned v0 ; v0 = 0
v3 = load.i32 aligned v1 v3 = load.i32 aligned v1 ; v1 = 0
v4 = icmp eq v2, v3 v4 = icmp eq v2, v3
return v4", return v4",
|builder, target, x, y| { |builder, target, x, y| {
@@ -1645,8 +1656,8 @@ block0:
v1 -> v6 v1 -> v6
v5 = iconst.i64 0 v5 = iconst.i64 0
v0 -> v5 v0 -> v5
v2 = load.i128 v0 v2 = load.i128 v0 ; v0 = 0
v3 = load.i128 v1 v3 = load.i128 v1 ; v1 = 0
v4 = icmp ne v2, v3 v4 = icmp ne v2, v3
return v4", return v4",
|builder, target, x, y| { |builder, target, x, y| {
@@ -1678,7 +1689,7 @@ block0:
v5 = iconst.i64 0 v5 = iconst.i64 0
v0 -> v5 v0 -> v5
v2 = iconst.i64 3 v2 = iconst.i64 3
v3 = call fn0(v0, v1, v2) v3 = call fn0(v0, v1, v2) ; v0 = 0, v1 = 0, v2 = 3
v4 = icmp_imm sge v3, 0 v4 = icmp_imm sge v3, 0
return v4", return v4",
|builder, target, x, y| { |builder, target, x, y| {
@@ -1740,13 +1751,9 @@ block0:
builder.finalize(); builder.finalize();
} }
let actual_ir = func.display().to_string(); check(
let expected_ir = format!("function %sample() -> b1 system_v {{{}\n}}\n", expected); &func,
assert!( &format!("function %sample() -> b1 system_v {{{}\n}}\n", expected),
expected_ir == actual_ir,
"Expected\n{}, but got\n{}",
expected_ir,
actual_ir
); );
} }
@@ -1780,22 +1787,22 @@ block0:
builder.finalize(); builder.finalize();
} }
assert_eq!( check(
func.display().to_string(), &func,
"function %sample() -> i8x16, b8x16, f32x4 system_v { "function %sample() -> i8x16, b8x16, f32x4 system_v {
const0 = 0x00000000000000000000000000000000 const0 = 0x00000000000000000000000000000000
block0: block0:
v5 = f32const 0.0 v5 = f32const 0.0
v6 = splat.f32x4 v5 v6 = splat.f32x4 v5 ; v5 = 0.0
v2 -> v6 v2 -> v6
v4 = vconst.b8x16 const0 v4 = vconst.b8x16 const0
v1 -> v4 v1 -> v4
v3 = vconst.i8x16 const0 v3 = vconst.i8x16 const0
v0 -> v3 v0 -> v3
return v0, v1, v2 return v0, v1, v2 ; v0 = const0, v1 = const0
} }
" ",
); );
} }

View File

@@ -391,7 +391,7 @@ mod tests {
func, func,
"block0: "block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
brz v0, block1 brz v0, block1 ; v0 = 0
jump block0" jump block0"
); );
} }
@@ -403,7 +403,7 @@ mod tests {
func, func,
"block0: "block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm eq v0, 1 v1 = icmp_imm eq v0, 1 ; v0 = 0
brnz v1, block1 brnz v1, block1
jump block0" jump block0"
); );
@@ -421,7 +421,7 @@ block0:
jump block3 jump block3
block3: block3:
v1 = uextend.i32 v0 v1 = uextend.i32 v0 ; v0 = 0
br_table v1, block0, jt0" br_table v1, block0, jt0"
); );
} }
@@ -433,12 +433,12 @@ block3:
func, func,
"block0: "block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm eq v0, 2 v1 = icmp_imm eq v0, 2 ; v0 = 0
brnz v1, block2 brnz v1, block2
jump block3 jump block3
block3: block3:
brz.i8 v0, block1 brz.i8 v0, block1 ; v0 = 0
jump block0" jump block0"
); );
} }
@@ -453,31 +453,31 @@ block3:
block0: block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm uge v0, 7 v1 = icmp_imm uge v0, 7 ; v0 = 0
brnz v1, block9 brnz v1, block9
jump block8 jump block8
block9: block9:
v2 = icmp_imm.i8 uge v0, 10 v2 = icmp_imm.i8 uge v0, 10 ; v0 = 0
brnz v2, block10 brnz v2, block10
jump block11 jump block11
block11: block11:
v3 = icmp_imm.i8 eq v0, 7 v3 = icmp_imm.i8 eq v0, 7 ; v0 = 0
brnz v3, block4 brnz v3, block4
jump block0 jump block0
block8: block8:
v4 = icmp_imm.i8 eq v0, 5 v4 = icmp_imm.i8 eq v0, 5 ; v0 = 0
brnz v4, block3 brnz v4, block3
jump block12 jump block12
block12: block12:
v5 = uextend.i32 v0 v5 = uextend.i32 v0 ; v0 = 0
br_table v5, block0, jt0 br_table v5, block0, jt0
block10: block10:
v6 = iadd_imm.i8 v0, -10 v6 = iadd_imm.i8 v0, -10 ; v0 = 0
v7 = uextend.i32 v6 v7 = uextend.i32 v6
br_table v7, block0, jt1" br_table v7, block0, jt1"
); );
@@ -490,12 +490,12 @@ block10:
func, func,
"block0: "block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm eq v0, 128 v1 = icmp_imm eq v0, 128 ; v0 = 0
brnz v1, block1 brnz v1, block1
jump block3 jump block3
block3: block3:
v2 = icmp_imm.i8 eq v0, 1 v2 = icmp_imm.i8 eq v0, 1 ; v0 = 0
brnz v2, block2 brnz v2, block2
jump block0" jump block0"
); );
@@ -508,12 +508,12 @@ block3:
func, func,
"block0: "block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm eq v0, 127 v1 = icmp_imm eq v0, 127 ; v0 = 0
brnz v1, block1 brnz v1, block1
jump block3 jump block3
block3: block3:
v2 = icmp_imm.i8 eq v0, 1 v2 = icmp_imm.i8 eq v0, 1 ; v0 = 0
brnz v2, block2 brnz v2, block2
jump block0" jump block0"
) )
@@ -528,12 +528,12 @@ block3:
block0: block0:
v0 = iconst.i8 0 v0 = iconst.i8 0
v1 = icmp_imm eq v0, 255 v1 = icmp_imm eq v0, 255 ; v0 = 0
brnz v1, block1 brnz v1, block1
jump block4 jump block4
block4: block4:
v2 = uextend.i32 v0 v2 = uextend.i32 v0 ; v0 = 0
br_table v2, block0, jt0" br_table v2, block0, jt0"
); );
} }
@@ -626,12 +626,12 @@ block0:
jump block4 jump block4
block4: block4:
v1 = icmp_imm.i64 ugt v0, 0xffff_ffff v1 = icmp_imm.i64 ugt v0, 0xffff_ffff ; v0 = 0
brnz v1, block3 brnz v1, block3
jump block5 jump block5
block5: block5:
v2 = ireduce.i32 v0 v2 = ireduce.i32 v0 ; v0 = 0
br_table v2, block3, jt0" br_table v2, block3, jt0"
); );
} }
@@ -667,12 +667,12 @@ block0:
jump block4 jump block4
block4: block4:
v1 = icmp_imm.i128 ugt v0, 0xffff_ffff v1 = icmp_imm.i128 ugt v0, 0xffff_ffff ; v0 = 0
brnz v1, block3 brnz v1, block3
jump block5 jump block5
block5: block5:
v2 = ireduce.i32 v0 v2 = ireduce.i32 v0 ; v0 = 0
br_table v2, block3, jt0" br_table v2, block3, jt0"
); );
} }

View File

@@ -1073,9 +1073,13 @@ mod tests {
"reduction wasn't maximal for insts" "reduction wasn't maximal for insts"
); );
assert_eq!( let actual_ir = format!("{}", reduced_func);
format!("{}", reduced_func), let expected_ir = expected_str.replace("\r\n", "\n");
expected_str.replace("\r\n", "\n") assert!(
expected_ir == actual_ir,
"Expected:\n{}\nGot:\n{}",
expected_ir,
actual_ir,
); );
} }
} }

View File

@@ -21,6 +21,6 @@ block1:
v12 = vconst.b8x16 const2 v12 = vconst.b8x16 const2
v13 = vconst.i16x4 const1 v13 = vconst.i16x4 const1
v14 = vconst.f32x16 const0 v14 = vconst.f32x16 const0
call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) ; v0 = 0.0, v1 = 0.0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0, v7 = false, v8 = false, v9 = false, v12 = const2, v13 = const1, v14 = const0
trap user0 trap user0
} }

View File

@@ -30,6 +30,6 @@ block0:
v990 -> v1052 v990 -> v1052
v1051 -> v1052 v1051 -> v1052
v1055 -> v1052 v1055 -> v1052
call fn0(v0, v105, v1052, v883, v829, v987, v951, v842) call fn0(v0, v105, v1052, v883, v829, v987, v951, v842) ; v0 = 0, v105 = 0, v1052 = 0, v883 = 0, v829 = 0, v987 = 0, v951 = 0, v842 = 0
trap user0 trap user0
} }