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::{Block, DataFlowGraph, Function, Inst, SigRef, Type, Value, ValueDef};
use crate::packed_option::ReservedValue;
use alloc::string::String;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::fmt::{self, Write};
@@ -530,7 +530,26 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt
FloatCondTrap {
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.

View File

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

View File

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

View File

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

View File

@@ -1073,9 +1073,13 @@ mod tests {
"reduction wasn't maximal for insts"
);
assert_eq!(
format!("{}", reduced_func),
expected_str.replace("\r\n", "\n")
let actual_ir = format!("{}", reduced_func);
let expected_ir = 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
v13 = vconst.i16x4 const1
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
}

View File

@@ -30,6 +30,6 @@ block0:
v990 -> v1052
v1051 -> 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
}