diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 3c301dea2..b1d9ac1be 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -49,71 +49,80 @@ public: }; //###################################################################### -// Subst state, as a visitor of each AstNode +// Class for each word of a multi-word variable + +class SubstVarWord { +private: + AstNodeAssign* m_assignp; // Last assignment to each word of this var + bool m_use; // True if each word was consumed + bool m_complex; // True if each word is complex + friend class SubstVarEntry; + // METHODS + void clear() { + m_assignp = NULL; + m_use = false; + m_complex = false; + } +}; + +//###################################################################### +// Class for every variable we may process class SubstVarEntry { AstVar* m_varp; // Variable this tracks - bool m_complexAssign;// True if assigned multiple times or in complex mannor - AstNodeAssign* m_wholeAssignp; // Last assignment to entire array - bool m_wholeUse; // True if used as entire wide array bool m_wordAssign; // True if any word assignments bool m_wordUse; // True if any individual word usage - vector m_wordAssignps; // Last assignment to each word of this var - vector m_wordUses; // True if each word was consumed - vector m_wordComplex; // True if each word is complex + SubstVarWord m_whole; // Data for whole vector used at once + vector m_words; // Data for every word, if multi word variable int debug() { return SubstBaseVisitor::debug(); } public: SubstVarEntry (AstVar* varp) { // Construction for when a var is used m_varp = varp; - m_complexAssign = false; - m_wholeAssignp = NULL; - m_wholeUse = false; + m_whole.m_use = false; m_wordAssign = false; m_wordUse = false; - m_wordAssignps.resize(varp->widthWords()); - m_wordUses.resize(varp->widthWords()); - m_wordComplex.resize(varp->widthWords()); + m_words.resize(varp->widthWords()); + m_whole.clear(); for (int i=0; iwidthWords(); i++) { - m_wordAssignps[i] = NULL; - m_wordUses[i] = false; - m_wordComplex[i] = false; + m_words[i].clear(); } } + ~SubstVarEntry() {} bool wordNumOk(int word) { return word < m_varp->widthWords(); } AstNodeAssign* getWordAssignp(int word) { if (!wordNumOk(word)) return NULL; - else return m_wordAssignps[word]; + else return m_words[word].m_assignp; } void assignWhole (AstNodeAssign* assp) { - if (m_wholeAssignp) m_complexAssign = true; - m_wholeAssignp = assp; + if (m_whole.m_assignp) m_whole.m_complex = true; + m_whole.m_assignp = assp; } void assignWord (int word, AstNodeAssign* assp) { - if (!wordNumOk(word) || getWordAssignp(word) || m_wordComplex[word]) m_complexAssign = true; + if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true; m_wordAssign = true; - if (wordNumOk(word)) m_wordAssignps[word] = assp; + if (wordNumOk(word)) m_words[word].m_assignp = assp; } void assignWordComplex (int word) { - if (!wordNumOk(word) || getWordAssignp(word) || m_wordComplex[word]) m_complexAssign = true; - m_wordComplex[word] = true; + if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true; + m_words[word].m_complex = true; } void assignComplex() { - m_complexAssign = true; + m_whole.m_complex = true; } void consumeWhole() { //==consumeComplex as we don't know the difference - m_wholeUse = true; + m_whole.m_use = true; } void consumeWord(int word) { - m_wordUses[word] = true; + m_words[word].m_use = true; m_wordUse = true; } // ACCESSORS AstNode* substWhole(AstNode* errp) { if (!m_varp->isWide() - && !m_complexAssign && m_wholeAssignp && !m_wordAssign) { - AstNodeAssign* assp = m_wholeAssignp; + && !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) { + AstNodeAssign* assp = m_whole.m_assignp; if (!assp) errp->v3fatalSrc("Reading whole that was never assigned"); return (assp->rhsp()); } else { @@ -121,7 +130,7 @@ public: } } AstNode* substWord(AstNode* errp, int word) { // Return what to substitute given word number for - if (!m_complexAssign && !m_wholeAssignp && !m_wordComplex[word]) { + if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) { AstNodeAssign* assp = getWordAssignp(word); if (!assp) errp->v3fatalSrc("Reading a word that was never assigned, or bad word #"); return (assp->rhsp()); @@ -135,18 +144,19 @@ public: } void deleteUnusedAssign() { // If there are unused assignments in this var, kill them - if (!m_wholeUse && !m_wordUse && m_wholeAssignp) { - deleteAssign (m_wholeAssignp); m_wholeAssignp=NULL; + if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) { + deleteAssign (m_whole.m_assignp); m_whole.m_assignp=NULL; } - for (unsigned i=0; i