diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 0b1072cb2..9f14c65ee 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -210,6 +210,7 @@ William D. Jones Wilson Snyder Xi Zhang Yan Xu +Yangyu Chen Yinan Xu Yoda Lee Yossi Nivin diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index dc6393bbf..b2b26c502 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -445,8 +445,12 @@ void EmitCFunc::emitDereference(AstNode* nodep, const string& pointer) { putns(nodep, pointer.substr(2, pointer.length() - 3)); puts("."); } else { - putns(nodep, pointer); - puts("->"); + if (pointer == "vlSelf" && m_usevlSelfRef) { + puts("vlSelfRef."); + } else { + putns(nodep, pointer); + puts("->"); + } } } diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index fa2a102c7..6dea21240 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -148,6 +148,7 @@ class EmitCFunc VL_NOT_FINAL : public EmitCConstInit { protected: EmitCLazyDecls m_lazyDecls; // Visitor for emitting lazy declarations bool m_useSelfForThis = false; // Replace "this" with "vlSelf" + bool m_usevlSelfRef = false; // Use vlSelfRef reference instead of vlSelf pointer const AstNodeModule* m_modp = nullptr; // Current module being emitted const AstCFunc* m_cfuncp = nullptr; // Current function being emitted bool m_instantiatesOwnProcess = false; @@ -343,6 +344,21 @@ public: } } + if (m_useSelfForThis) { + m_usevlSelfRef = true; + /* + * Using reference to the vlSelf pointer will help the C++ + * compiler to have dereferenceable hints, which can help to + * reduce the need for branch instructions in the generated + * code to allow the compiler to generate load store after the + * if condition (including short-circuit evaluation) + * speculatively and also reduce the data cache pollution when + * executing in the wrong path to make verilator-generated code + * run faster. + */ + puts("auto &vlSelfRef = std::ref(*vlSelf).get();\n"); + } + if (nodep->initsp()) { putsDecoration(nodep, "// Init\n"); iterateAndNextConstNull(nodep->initsp()); @@ -358,6 +374,8 @@ public: iterateAndNextConstNull(nodep->finalsp()); } + m_usevlSelfRef = false; + puts("}\n"); if (nodep->ifdef() != "") puts("#endif // " + nodep->ifdef() + "\n"); }