No functional change; have V3Subst use a sub-structure.

git-svn-id: file://localhost/svn/verilator/trunk/verilator@814 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2006-10-11 14:13:37 +00:00
parent 710d7c0ee5
commit 3d4fe0364a

View File

@ -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<AstNodeAssign*> m_wordAssignps; // Last assignment to each word of this var
vector<bool> m_wordUses; // True if each word was consumed
vector<bool> m_wordComplex; // True if each word is complex
SubstVarWord m_whole; // Data for whole vector used at once
vector<SubstVarWord> 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; i<varp->widthWords(); 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<m_wordUses.size(); i++) {
if (!m_wholeUse && !m_wordUses[i] && m_wordAssignps[i] && !m_wordComplex[i]) {
deleteAssign (m_wordAssignps[i]); m_wordAssignps[i]=NULL;
for (unsigned i=0; i<m_words.size(); i++) {
if (!m_whole.m_use && !m_words[i].m_use && m_words[i].m_assignp && !m_words[i].m_complex) {
deleteAssign (m_words[i].m_assignp); m_words[i].m_assignp=NULL;
}
}
}
};
//######################################################################
// Subst state, as a visitor of each AstNode
class SubstVisitor : public SubstBaseVisitor {
private: