diff --git a/src/V3DfgAstToDfg.cpp b/src/V3DfgAstToDfg.cpp index 58b6166ee..e9379dca0 100644 --- a/src/V3DfgAstToDfg.cpp +++ b/src/V3DfgAstToDfg.cpp @@ -50,38 +50,11 @@ DfgArraySel* makeVertex(const AstArraySel* nodep, DfgG // Some earlier passes create malformed ArraySels, just bail on those... // See t_bitsel_wire_array_bad if (VN_IS(nodep->fromp(), Const)) return nullptr; - AstUnpackArrayDType* const fromDtypep - = VN_CAST(nodep->fromp()->dtypep()->skipRefp(), UnpackArrayDType); - if (!fromDtypep) return nullptr; + if (!VN_IS(nodep->fromp()->dtypep()->skipRefp(), UnpackArrayDType)) return nullptr; return new DfgArraySel{dfg, nodep->fileline(), DfgVertex::dtypeFor(nodep)}; } -//====================================================================== -// Currently unhandled nodes -// LCOV_EXCL_START -// AstCCast changes width, but should not exists where DFG optimization is currently invoked -template <> -DfgCCast* makeVertex(const AstCCast*, DfgGraph&) { - return nullptr; -} -// Unhandled in DfgToAst, but also operates on strings which we don't optimize anyway -template <> -DfgAtoN* makeVertex(const AstAtoN*, DfgGraph&) { - return nullptr; -} -// Unhandled in DfgToAst, but also operates on strings which we don't optimize anyway -template <> -DfgCompareNN* makeVertex(const AstCompareNN*, DfgGraph&) { - return nullptr; -} -// Unhandled in DfgToAst, but also operates on unpacked arrays which we don't optimize anyway -template <> -DfgSliceSel* makeVertex(const AstSliceSel*, DfgGraph&) { - return nullptr; -} -// LCOV_EXCL_STOP - -} // namespace +} //namespace // Visitor that can convert combinational Ast logic constructs/assignments to Dfg template diff --git a/src/V3DfgDfgToAst.cpp b/src/V3DfgDfgToAst.cpp index 6a557e088..a96af5864 100644 --- a/src/V3DfgDfgToAst.cpp +++ b/src/V3DfgDfgToAst.cpp @@ -52,15 +52,6 @@ T_Node* makeNode(const T_Vertex* vtxp, Ops... ops) { //====================================================================== // Vertices needing special conversion -template <> -AstCountOnes* makeNode( // - const DfgCountOnes* vtxp, AstNodeExpr* op1) { - AstCountOnes* const nodep = new AstCountOnes{vtxp->fileline(), op1}; - // Set dtype same as V3Width - nodep->dtypeSetLogicSized(32, VSigning::UNSIGNED); - return nodep; -} - template <> AstExtend* makeNode( // const DfgExtend* vtxp, AstNodeExpr* op1) { @@ -91,38 +82,6 @@ AstShiftRS* makeNode( // return new AstShiftRS{vtxp->fileline(), op1, op2, static_cast(vtxp->width())}; } -//====================================================================== -// Currently unhandled nodes - see corresponding AstToDfg functions -// LCOV_EXCL_START -template <> -AstCCast* makeNode(const DfgCCast* vtxp, AstNodeExpr*) { - vtxp->v3fatalSrc("not implemented"); - VL_UNREACHABLE; - return nullptr; // LCOV_EXCL_LINE -} -template <> -AstAtoN* makeNode(const DfgAtoN* vtxp, AstNodeExpr*) { - vtxp->v3fatalSrc("not implemented"); - VL_UNREACHABLE; - return nullptr; // LCOV_EXCL_LINE -} -template <> -AstCompareNN* -makeNode(const DfgCompareNN* vtxp, - AstNodeExpr*, AstNodeExpr*) { - vtxp->v3fatalSrc("not implemented"); - VL_UNREACHABLE; - return nullptr; // LCOV_EXCL_LINE -} -template <> -AstSliceSel* makeNode( - const DfgSliceSel* vtxp, AstNodeExpr*, AstNodeExpr*, AstNodeExpr*) { - vtxp->v3fatalSrc("not implemented"); - VL_UNREACHABLE; - return nullptr; // LCOV_EXCL_LINE -} -// LCOV_EXCL_STOP - } // namespace template diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index a6e990029..deadbf96f 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -79,15 +79,11 @@ using BitwiseToReduction = typename BitwiseToReductionImpl::type; namespace { template void foldOp(V3Number& out, const V3Number& src); -template <> void foldOp (V3Number& out, const V3Number& src) { out.opCLog2(src); } -template <> void foldOp (V3Number& out, const V3Number& src) { out.opCountOnes(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opAssign(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opExtendS(src, src.width()); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opLogNot(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opNegate(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opNot(src); } -template <> void foldOp (V3Number& out, const V3Number& src) { out.opOneHot(src); } -template <> void foldOp (V3Number& out, const V3Number& src) { out.opOneHot0(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedAnd(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedOr(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedXor(src); } @@ -665,14 +661,6 @@ class V3DfgPeephole final : public DfgVisitor { // DfgVertexUnary //========================================================================= - void visit(DfgCLog2* vtxp) override { - if (foldUnary(vtxp)) return; - } - - void visit(DfgCountOnes* vtxp) override { - if (foldUnary(vtxp)) return; - } - void visit(DfgExtend* vtxp) override { UASSERT_OBJ(vtxp->width() > vtxp->srcp()->width(), vtxp, "Invalid zero extend"); @@ -768,14 +756,6 @@ class V3DfgPeephole final : public DfgVisitor { } } - void visit(DfgOneHot* vtxp) override { - if (foldUnary(vtxp)) return; - } - - void visit(DfgOneHot0* vtxp) override { - if (foldUnary(vtxp)) return; - } - void visit(DfgRedOr* vtxp) override { if (optimizeReduction(vtxp)) return; } diff --git a/src/astgen b/src/astgen index 8d64b12c7..9af3a1746 100755 --- a/src/astgen +++ b/src/astgen @@ -1356,6 +1356,116 @@ DfgVertices["Vertex"].addSubClass(DfgVertices["VertexTernary"]) DfgVertices["VertexVariadic"] = Node("VertexVariadic", DfgVertices["Vertex"]) DfgVertices["Vertex"].addSubClass(DfgVertices["VertexVariadic"]) +# AstNodeExpr that are not representable in Dfg +DfgIgnored = ( + # Floating point operations + "AcosD", + "AcoshD", + "AddD", + "AsinD", + "AsinhD", + "Atan2D", + "AtanD", + "AtanhD", + "BitsToRealD", + "CeilD", + "CosD", + "CoshD", + "DivD", + "EqD", + "ExpD", + "FloorD", + "GtD", + "GteD", + "HypotD", + "ISToRD", + "IToRD", + "Log10D", + "LogD", + "LtD", + "LteD", + "MulD", + "NegateD", + "NeqD", + "PowD", + "RealToBits", + "RToIRoundS", + "RToIS", + "SinD", + "SinhD", + "SqrtD", + "SubD", + "TanD", + "TanhD", + # String operations + "AtoN", + "CompareNN", + "ConcatN", + "CvtPackString", + "EqN", + "GetcN", + "GetcRefN", + "GteN", + "GtN", + "LenN", + "LteN", + "LtN", + "NeqN", + "NToI", + "PutcN", + "ReplicateN", + "SubstrN", + "ToLowerN", + "ToUpperN", + # Effectful + "PostAdd", + "PostSub", + "PreAdd", + "PreSub", + # Only used after DFG + "ShiftLOvr", + "ShiftROvr", + "ShiftRSOvr", + "WordSel", + # File operations + "FEof", + "FGetC", + "FGetS", + "FUngetC", + # Dynamic array operations + "AssocSel", + "IsUnbounded", + "WildcardSel", + # Type comparison + "EqT", + "NeqT", + # Distributions + "DistChiSquare", + "DistErlang", + "DistExponential", + "DistNormal", + "DistPoisson", + "DistT", + "DistUniform", + # Specials + "CastDynamic", + "CastWrap", + "CAwait", + "CCast", + "CLog2", + "CountOnes", + "IsUnknown", + "NullCheck", + "OneHot", + "OneHot0", + "ResizeLValue", + "Signed", + "SliceSel", + "TimeImport", + "Unsigned", + "URandomRange", +) + # Read DfgVertex definitions for filename in Args.dfgdef: read_types(os.path.join(Args.I, filename), DfgVertices, "Dfg") @@ -1370,6 +1480,10 @@ for node in AstNodeList: if node.name in DfgVertices: continue + # Ignore expressions types that DFG cannot handle + if node.name in DfgIgnored: + continue + if node.isSubClassOf(AstNodes["NodeUniop"]): base = DfgVertices["VertexUnary"] elif node.isSubClassOf(AstNodes["NodeBiop"]): diff --git a/test_regress/t/t_dfg_4104.py b/test_regress/t/t_dfg_4104.py deleted file mode 100755 index 0b27c3dc0..000000000 --- a/test_regress/t/t_dfg_4104.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2024 by Wilson Snyder. This program is free software; you -# can redistribute it and/or modify it under the terms of either the GNU -# Lesser General Public License Version 3 or the Perl Artistic License -# Version 2.0. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -import vltest_bootstrap - -test.scenarios('vlt') - -test.compile() - -test.passes() diff --git a/test_regress/t/t_dfg_4104.v b/test_regress/t/t_dfg_4104.v deleted file mode 100644 index 508f93a57..000000000 --- a/test_regress/t/t_dfg_4104.v +++ /dev/null @@ -1,12 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2023 by Geza Lore. -// SPDX-License-Identifier: CC0-1.0 - -module v(input logic t); -endmodule - -module top(input logic [2:0] c); - v v1((int'(c) + int'($countones(c))) > 2); -endmodule diff --git a/test_regress/t/t_dfg_peephole.v b/test_regress/t/t_dfg_peephole.v index 1789a7b9d..6392ded77 100644 --- a/test_regress/t/t_dfg_peephole.v +++ b/test_regress/t/t_dfg_peephole.v @@ -43,14 +43,9 @@ module t ( array[2][7:4] = rand_a[7:4]; end - `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); diff --git a/test_regress/t/t_dfg_unhandled.py b/test_regress/t/t_dfg_unhandled.py deleted file mode 100755 index 1bb7d5c4a..000000000 --- a/test_regress/t/t_dfg_unhandled.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2024 by Wilson Snyder. This program is free software; you -# can redistribute it and/or modify it under the terms of either the GNU -# Lesser General Public License Version 3 or the Perl Artistic License -# Version 2.0. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -import vltest_bootstrap - -test.scenarios('vlt') - -test.compile(verilator_flags2=["--stats"]) - -test.file_grep(test.stats, - r'Optimizations, DFG pre inline AstToDfg, non-representable \(impure\)\s+(\d+)', 1) - -test.passes() diff --git a/test_regress/t/t_dfg_unhandled.v b/test_regress/t/t_dfg_unhandled.v deleted file mode 100644 index f01edfeff..000000000 --- a/test_regress/t/t_dfg_unhandled.v +++ /dev/null @@ -1,16 +0,0 @@ -// 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 - -module t ( - input wire clk, - output wire [31:0] o0 - ); - - int file; - - assign o0 = $fgetc(file); // Impure - -endmodule