verilator/test_regress/t/t_dfg_peephole.v
Geza Lore 0fed5f8b3e
Avoid creating redundant vertices in V3DfgPeephole (#4944)
Add a new data-structure V3DfgCache, which can be used to retrieve
existing vertices with some given inputs vertices. Use this in
V3DfgPeephole to eliminate the creation of redundant vertices.

Overall this is performance neutral, but is in prep for some future
work.
2024-03-06 18:01:52 +00:00

214 lines
11 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Geza Lore.
// SPDX-License-Identifier: CC0-1.0
`define signal(name, expr) wire [$bits(expr)-1:0] ``name = expr
module t (
`include "portlist.vh" // Boilerplate generated by t_dfg_peephole.pl
rand_a, rand_b, srand_a, srand_b
);
`include "portdecl.vh" // Boilerplate generated by t_dfg_peephole.pl
input rand_a;
input rand_b;
input srand_a;
input srand_b;
wire logic [63:0] rand_a;
wire logic [63:0] rand_b;
wire logic signed [63:0] srand_a;
wire logic signed [63:0] srand_b;
wire logic randbit_a = rand_a[0];
wire logic [127:0] rand_ba = {rand_b, rand_a};
wire logic [127:0] rand_aa = {2{rand_a}};
wire logic [63:0] const_a;
wire logic [63:0] const_b;
wire logic signed [63:0] sconst_a;
wire logic signed [63:0] sconst_b;
wire logic [63:0] array [3:0];
assign array[0] = (rand_a << 32) | (rand_a >> 32);
assign array[1] = (rand_a << 16) | (rand_a >> 48);
`signal(FOLD_UNARY_CLog2, $clog2(const_a));
`signal(FOLD_UNARY_CountOnes, $countones(const_a));
`signal(FOLD_UNARY_IsUnknown, $isunknown(const_a));
`signal(FOLD_UNARY_LogNot, !const_a[0]);
`signal(FOLD_UNARY_Negate, -const_a);
`signal(FOLD_UNARY_Not, ~const_a);
`signal(FOLD_UNARY_OneHot, $onehot(const_a));
`signal(FOLD_UNARY_OneHot0, $onehot0(const_a));
`signal(FOLD_UNARY_RedAnd, &const_a);
`signal(FOLD_UNARY_RedOr, |const_a);
`signal(FOLD_UNARY_RedXor, ^const_a);
// verilator lint_off WIDTH
wire logic [79:0] tmp_FOLD_UNARY_Extend = const_a;
wire logic signed [79:0] tmp_FOLD_UNARY_ExtendS = sconst_a;
//verilator lint_on WIDTH
`signal(FOLD_UNARY_Extend, tmp_FOLD_UNARY_Extend);
`signal(FOLD_UNARY_ExtendS, tmp_FOLD_UNARY_ExtendS);
`signal(FOLD_BINARY_Add, const_a + const_b);
`signal(FOLD_BINARY_And, const_a & const_b);
`signal(FOLD_BINARY_Concat, {const_a, const_b});
`signal(FOLD_BINARY_Div, const_a / 64'd3);
`signal(FOLD_BINARY_DivS, sconst_a / 64'sd3);
`signal(FOLD_BINARY_Eq, const_a == const_b);
`signal(FOLD_BINARY_Gt, const_a > const_b);
`signal(FOLD_BINARY_GtS, sconst_a > sconst_b);
`signal(FOLD_BINARY_Gte, const_a >= const_b);
`signal(FOLD_BINARY_GteS, sconst_a >= sconst_b);
`signal(FOLD_BINARY_LogAnd, const_a[0] && const_b[0]);
`signal(FOLD_BINARY_LogEq, const_a[0] <-> const_b[0]);
`signal(FOLD_BINARY_LogIf, const_a[0] -> const_b[0]);
`signal(FOLD_BINARY_LogOr, const_a[0] || const_b[0]);
`signal(FOLD_BINARY_Lt, const_a < const_b);
`signal(FOLD_BINARY_LtS, sconst_a < sconst_b);
`signal(FOLD_BINARY_Lte, const_a <= const_b);
`signal(FOLD_BINARY_LteS, sconst_a <= sconst_b);
`signal(FOLD_BINARY_ModDiv, const_a % 64'd3);
`signal(FOLD_BINARY_ModDivS, sconst_a % 64'sd3);
`signal(FOLD_BINARY_Mul, const_a * 64'd3);
`signal(FOLD_BINARY_MulS, sconst_a * 64'sd3);
`signal(FOLD_BINARY_Neq, const_a != const_b);
`signal(FOLD_BINARY_Or, const_a | const_b);
`signal(FOLD_BINARY_Pow, const_a ** 64'd2);
`signal(FOLD_BINARY_PowSS, sconst_a ** 64'sd2);
`signal(FOLD_BINARY_PowSU, sconst_a ** 64'd2);
`signal(FOLD_BINARY_PowUS, const_a ** 64'sd2);
`signal(FOLD_BINARY_Replicate, {2{const_a}});
`signal(FOLD_BINARY_ShiftL, const_a << 2);
`signal(FOLD_BINARY_ShiftR, const_a >> 2);
`signal(FOLD_BINARY_ShiftRS, sconst_a >>> 2);
`signal(FOLD_BINARY_Sub, const_a - const_b);
`signal(FOLD_BINARY_Xor, const_a ^ const_b);
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_And, (const_a & (const_b & rand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Or, (const_a | (const_b | rand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Xor, (const_a ^ (const_b ^ rand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Add, (const_a + (const_b + rand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Mul, (const_a * (const_b * rand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_MulS, (sconst_a * (sconst_b * srand_a)));
`signal(FOLD_ASSOC_BINARY_LHS_OF_RHS_Concat, {const_a, {const_b, rand_a}});
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_And, ((rand_a & const_b) & const_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Or, ((rand_a | const_b) | const_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Xor, ((rand_a ^ const_b) ^ const_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Add, ((rand_a + const_b) + const_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Mul, ((rand_a * const_b) * const_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_MulS, ((srand_a * sconst_b) * sconst_a));
`signal(FOLD_ASSOC_BINARY_RHS_OF_LHS_Concat, {{rand_a, const_b}, const_a});
`signal(FOLD_SEL, const_a[3:1]);
`signal(SWAP_CONST_IN_COMMUTATIVE_BINARY, rand_a + const_a);
`signal(SWAP_NOT_IN_COMMUTATIVE_BINARY, rand_a + ~rand_a);
`signal(SWAP_VAR_IN_COMMUTATIVE_BINARY, rand_b + rand_a);
`signal(PUSH_BITWISE_OP_THROUGH_CONCAT, 32'h12345678 ^ {8'h0, rand_a[23:0]});
`signal(PUSH_BITWISE_OP_THROUGH_CONCAT_2, 32'h12345678 ^ {rand_b[7:0], rand_a[23:0]});
`signal(PUSH_COMPARE_OP_THROUGH_CONCAT, 4'b1011 == {2'b10, rand_a[1:0]});
`signal(PUSH_REDUCTION_THROUGH_COND_WITH_CONST_BRANCH, |(rand_a[32] ? rand_a[3:0] : 4'h0));
`signal(REPLACE_REDUCTION_OF_CONST_AND, &const_a);
`signal(REPLACE_REDUCTION_OF_CONST_OR, |const_a);
`signal(REPLACE_REDUCTION_OF_CONST_XOR, ^const_a);
`signal(REPLACE_EXTEND, 4'(rand_a[0]));
`signal(PUSH_NOT_THROUGH_COND, ~(rand_a[0] ? rand_a[4:0] : 5'hb));
`signal(REMOVE_NOT_NOT, ~~rand_a);
`signal(REPLACE_NOT_NEQ, ~(rand_a != rand_b));
`signal(REPLACE_NOT_EQ, ~(srand_a == srand_b));
`signal(REPLACE_NOT_OF_CONST, ~4'd0);
`signal(REPLACE_AND_OF_NOT_AND_NOT, ~rand_a[1] & ~rand_b[1]);
`signal(REPLACE_AND_OF_NOT_AND_NEQ, ~rand_a[2] & (rand_b != 64'd2));
`signal(REPLACE_AND_OF_CONST_AND_CONST, const_a & const_b);
`signal(REPLACE_AND_WITH_ZERO, 64'd0 & rand_a);
`signal(REMOVE_AND_WITH_ONES, -64'd1 & rand_a);
`signal(REPLACE_CONTRADICTORY_AND, rand_a & ~rand_a);
`signal(REPLACE_OR_OF_NOT_AND_NOT, ~rand_a[3] | ~rand_b[3]);
`signal(REPLACE_OR_OF_NOT_AND_NEQ, ~rand_a[4] | (rand_b != 64'd3));
`signal(REPLACE_OR_OF_CONCAT_ZERO_LHS_AND_CONCAT_RHS_ZERO, {2'd0, rand_a[1:0]} | {rand_b[1:0], 2'd0});
`signal(REPLACE_OR_OF_CONCAT_LHS_ZERO_AND_CONCAT_ZERO_RHS, {rand_a[1:0], 2'd0} | {2'd0, rand_b[1:0]});
`signal(REPLACE_OR_OF_CONST_AND_CONST, const_a | const_b);
`signal(REMOVE_OR_WITH_ZERO, 64'd0 | rand_a);
`signal(REPLACE_OR_WITH_ONES, -64'd1 | rand_a);
`signal(REPLACE_TAUTOLOGICAL_OR, rand_a | ~rand_a);
`signal(REMOVE_SUB_ZERO, rand_a - 64'd0);
`signal(REPLACE_SUB_WITH_NOT, rand_a[0] - 1'b1);
`signal(REMOVE_REDUNDANT_ZEXT_ON_RHS_OF_SHIFT, rand_a << {2'b0, rand_a[2:0]});
`signal(REPLACE_EQ_OF_CONST_AND_CONST, 4'd0 == 4'd1);
`signal(REMOVE_FULL_WIDTH_SEL, rand_a[63:0]);
`signal(REMOVE_SEL_FROM_RHS_OF_CONCAT, rand_ba[63:0]);
`signal(REMOVE_SEL_FROM_LHS_OF_CONCAT, rand_ba[127:64]);
`signal(PUSH_SEL_THROUGH_CONCAT, rand_ba[120:0]);
`signal(PUSH_SEL_THROUGH_REPLICATE, rand_aa[0]);
`signal(REPLACE_SEL_FROM_CONST, const_a[2]);
`signal(REPLACE_CONCAT_OF_CONSTS, {const_a, const_b});
`signal(REPLACE_CONCAT_ZERO_AND_SEL_TOP_WITH_SHIFTR, {62'd0, rand_a[63:62]});
`signal(REPLACE_CONCAT_SEL_BOTTOM_AND_ZERO_WITH_SHIFTL, {rand_a[1:0], 62'd0});
`signal(PUSH_CONCAT_THROUGH_NOTS, {~(rand_a+64'd101), ~(rand_b+64'd101)} );
`signal(REMOVE_CONCAT_OF_ADJOINING_SELS, {rand_a[10:3], rand_a[2:1]});
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_LHS_CAT, {rand_a[2:1], rand_b});
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS_CAT, {rand_b, rand_a[10:3]});
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_LHS, {rand_a[10:3], {rand_a[2:1], rand_b}});
`signal(REPLACE_NESTED_CONCAT_OF_ADJOINING_SELS_ON_RHS, {{rand_b, rand_a[10:3]}, rand_a[2:1]});
`signal(REMOVE_COND_WITH_FALSE_CONDITION, 1'd0 ? rand_a : rand_b);
`signal(REMOVE_COND_WITH_TRUE_CONDITION, 1'd1 ? rand_a : rand_b);
`signal(SWAP_COND_WITH_NOT_CONDITION, (~rand_a[0] & 1'd1) ? rand_a : rand_b);
`signal(SWAP_COND_WITH_NEQ_CONDITION, rand_b != rand_a ? rand_a : rand_b);
`signal(PULL_NOTS_THROUGH_COND, rand_a[0] ? ~rand_a[4:0] : ~rand_b[4:0]);
`signal(REPLACE_COND_WITH_THEN_BRANCH_ZERO, rand_a[0] ? 1'd0 : rand_a[1]);
`signal(REPLACE_COND_WITH_THEN_BRANCH_ONES, rand_a[0] ? 1'd1 : rand_a[1]);
`signal(REPLACE_COND_WITH_ELSE_BRANCH_ZERO, rand_a[0] ? rand_a[1] : 1'd0);
`signal(REPLACE_COND_WITH_ELSE_BRANCH_ONES, rand_a[0] ? rand_a[1] : 1'd1);
`signal(INLINE_ARRAYSEL, array[0]);
`signal(PUSH_BITWISE_THROUGH_REDUCTION_AND, (&(rand_a + 64'd105)) & (&(rand_b + 64'd108)));
`signal(PUSH_BITWISE_THROUGH_REDUCTION_OR, (|(rand_a + 64'd106)) | (|(rand_b + 64'd109)));
`signal(PUSH_BITWISE_THROUGH_REDUCTION_XOR, (^(rand_a + 64'd107)) ^ (^(rand_b + 64'd110)));
`signal(PUSH_REDUCTION_THROUGH_CONCAT_AND, &{1'd1, rand_b});
`signal(PUSH_REDUCTION_THROUGH_CONCAT_OR, |{1'd1, rand_b});
`signal(PUSH_REDUCTION_THROUGH_CONCAT_XOR, ^{1'd1, rand_b});
`signal(REMOVE_WIDTH_ONE_REDUCTION_AND, &rand_a[0]);
`signal(REMOVE_WIDTH_ONE_REDUCTION_OR, |rand_a[0]);
`signal(REMOVE_WIDTH_ONE_REDUCTION_XOR, ^rand_a[0]);
`signal(REMOVE_XOR_WITH_ZERO, 64'd0 ^ rand_a);
`signal(REMOVE_XOR_WITH_ONES, -64'd1 ^ rand_a);
`signal(REPLACE_COND_DEC, randbit_a ? rand_b - 64'b1 : rand_b);
`signal(REPLACE_COND_INC, randbit_a ? rand_b + 64'b1 : rand_b);
`signal(NO_REPLACE_COND_DEC, randbit_a ? rand_b - 64'hf000000000000000 : rand_b);
`signal(NO_REPLACE_COND_INC, randbit_a ? rand_b + 64'hf000000000000000 : rand_b);
`signal(RIGHT_LEANING_ASSOC, (((rand_a + rand_b) + rand_a) + rand_b));
`signal(RIGHT_LEANING_CONCET, {{{rand_a, rand_b}, rand_a}, rand_b});
// Operators that should work wiht mismatched widths
`signal(MISMATCHED_ShiftL,const_a << 4'd2);
`signal(MISMATCHED_ShiftR,const_a >> 4'd2);
`signal(MISMATCHED_ShiftRS, const_a >> 4'd2);
`signal(MISMATCHED_PowUU, rand_a ** 4'd5);
`signal(MISMATCHED_PowSS, srand_a ** 4'sd5);
`signal(MISMATCHED_PowSU, srand_b ** 4'd5);
`signal(MISMATCHED_PowUS, rand_b ** 4'sd5);
// Some selects need extra temporaries
wire [63:0] sel_from_cond = rand_a[0] ? rand_a : const_a;
wire [63:0] sel_from_shiftl = rand_a << 10;
wire [31:0] sel_from_sel = rand_a[10+:32];
`signal(PUSH_SEL_THROUGH_COND, sel_from_cond[2]);
`signal(PUSH_SEL_THROUGH_SHIFTL, sel_from_shiftl[20:0]);
`signal(REPLACE_SEL_FROM_SEL, sel_from_sel[4:3]);
// Sel from not requires the operand to have a sinle sink, so can't use
// the chekc due to the raw expression referencing the operand
wire [63:0] sel_from_not_tmp = ~(rand_a >> rand_b[2:0] << rand_a[3:0]);
wire sel_from_not = sel_from_not_tmp[2];
always @(posedge randbit_a) if ($c(0)) $display(sel_from_not); // Do not remove signal
// Assigned at the end to avoid inlining by other passes
assign const_a = 64'h0123456789abcdef;
assign const_b = 64'h98badefc10325647;
assign sconst_a = 64'hfedcba9876543210;
assign sconst_b = 64'hba0123456789cdef;
endmodule