From f540dead799aadc1e54ae03df670f1c435d73044 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 24 Dec 2019 12:47:27 -0500 Subject: [PATCH] Internals: new() support code, and misc stuff. --- src/V3AstNodes.h | 10 ++++++---- src/V3Clean.cpp | 1 + src/V3EmitC.cpp | 11 +++++++---- src/V3Width.cpp | 12 ++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 4eb5a3090..63304eb1a 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -6707,10 +6707,11 @@ public: class AstCMath : public AstNodeMath { private: bool m_cleanOut; + bool m_pure; // Pure optimizable public: // Emit C textual math function (like AstUCFunc) AstCMath(FileLine* fl, AstNode* exprsp) - : AstNodeMath(fl), m_cleanOut(true) { + : AstNodeMath(fl), m_cleanOut(true), m_pure(false) { addOp1p(exprsp); dtypeFrom(exprsp); } @@ -6720,8 +6721,8 @@ public: if (setwidth) { dtypeSetLogicSized(setwidth, AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(CMath) - virtual bool isGateOptimizable() const { return false; } - virtual bool isPredictOptimizable() const { return false; } + virtual bool isGateOptimizable() const { return m_pure; } + virtual bool isPredictOptimizable() const { return m_pure; } virtual bool cleanOut() const { return m_cleanOut; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } @@ -6729,9 +6730,10 @@ public: virtual bool same(const AstNode* samep) const { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p(); } // op1 = expressions to print + bool pure() const { return m_pure; } + void pure(bool flag) { m_pure = flag; } }; - class AstCReset : public AstNodeStmt { // Reset variable at startup public: diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 3ea3c435d..2236c2d66 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -88,6 +88,7 @@ private: if (!nodep->user2() && nodep->hasDType()) { if (VN_IS(nodep, Var) || VN_IS(nodep, NodeDType) // Don't want to change variable widths! || VN_IS(nodep->dtypep()->skipRefp(), AssocArrayDType) // Or arrays + || VN_IS(nodep->dtypep()->skipRefp(), ClassRefDType) || VN_IS(nodep->dtypep()->skipRefp(), QueueDType) || VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType) || VN_IS(nodep->dtypep()->skipRefp(), VoidDType)) { diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index c6ebe76fe..8d8640227 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -714,6 +714,11 @@ public: iterateAndNextNull(nodep->expr2p()); puts(")"); } } + virtual void visit(AstNew* nodep) { + puts("std::make_shared<" + nodep->dtypep()->nameProtect() + ">("); + iterateChildren(nodep); + puts(")"); + } virtual void visit(AstSel* nodep) { // Note ASSIGN checks for this on a LHS emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp()); @@ -2736,21 +2741,19 @@ void EmitCImp::emitInt(AstNodeModule* modp) { ofp()->putsPrivate(false); // public: puts("void "+protect("__Vserialize")+"(VerilatedSerialize& os);\n"); puts("void "+protect("__Vdeserialize")+"(VerilatedDeserialize& os);\n"); - puts("\n"); } puts("} VL_ATTR_ALIGNED(128);\n"); - puts("\n"); // Save/restore if (v3Global.opt.savable() && modp->isTop()) { - puts("inline VerilatedSerialize& operator<<(VerilatedSerialize& os, " + puts("\n"); + puts("inline VerilatedSerialize& operator<<(VerilatedSerialize& os, " +modClassName(modp)+"& rhs) {\n" "Verilated::quiesce(); rhs."+protect("__Vserialize")+"(os); return os; }\n"); puts("inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, " +modClassName(modp)+"& rhs) {\n" "Verilated::quiesce(); rhs."+protect("__Vdeserialize")+"(os); return os; }\n"); - puts("\n"); } // finish up h-file diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 256211832..55c796c2e 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2239,6 +2239,18 @@ private: } } + virtual void visit(AstNew* nodep) { + if (nodep->didWidthAndSet()) return; + userIterateChildren(nodep, WidthVP(SELF, BOTH).p()); + AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); + if (!refp) { // e.g. int a = new; + if (refp) UINFO(1, "Got refp "<v3error("new() not expected in this context"); + return; + } + nodep->dtypep(refp); + } + virtual void visit(AstPattern* nodep) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<