Internals: Detab and fix spacing style issues. No functional change.

When diff, recommend using "git diff --ignore-all-space"
When merging, recommend using "git merge -Xignore-all-space"
This commit is contained in:
Wilson Snyder
2019-05-19 16:13:13 -04:00
parent 59d7d9e8c3
commit b83b606267
184 changed files with 33256 additions and 32136 deletions
+245 -238
View File
@@ -20,11 +20,11 @@
// V3Inline's Transformations:
//
// Each module:
// Look for CELL... PRAGMA INLINE_MODULE
// Replicate the cell's module
// Convert pins to wires that make assignments
// Rename vars to include cell name
// Insert cell's module statements into the upper module
// Look for CELL... PRAGMA INLINE_MODULE
// Replicate the cell's module
// Convert pins to wires that make assignments
// Rename vars to include cell name
// Insert cell's module statements into the upper module
//
//*************************************************************************
@@ -44,7 +44,7 @@
#include VL_INCLUDE_UNORDERED_SET
// CONFIG
static const int INLINE_MODS_SMALLER = 100; // If a mod is < this # nodes, can always inline it
static const int INLINE_MODS_SMALLER = 100; // If a mod is < this # nodes, can always inline it
//######################################################################
// Inline state, as a visitor of each AstNode
@@ -53,13 +53,13 @@ class InlineMarkVisitor : public AstNVisitor {
private:
// NODE STATE
// Output
// AstNodeModule::user1() // OUTPUT: bool. User request to inline this module
// AstNodeModule::user1() // OUTPUT: bool. User request to inline this module
// Internal state (can be cleared after this visit completes)
// AstNodeModule::user2() // CIL_*. Allowed to automatically inline module
// AstNodeModule::user3() // int. Number of cells referencing this module
// AstNodeModule::user2() // CIL_*. Allowed to automatically inline module
// AstNodeModule::user3() // int. Number of cells referencing this module
// AstNodeModule::user4() // int. Statements in module
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
AstUser4InUse m_inuser4;
// For the user2 field:
@@ -70,10 +70,10 @@ private:
// STATE
AstNodeModule* m_modp; // Current module
V3Double0 m_statUnsup; // Statistic tracking
V3Double0 m_statUnsup; // Statistic tracking
typedef std::vector<AstNodeModule*> ModVec;
ModVec m_allMods; // All modules, in top-down order.
ModVec m_allMods; // All modules, in top-down order.
// Within the context of a given module, LocalInstanceMap maps
// from child modules to the count of each child's local instantiations.
@@ -85,35 +85,35 @@ private:
// METHODS
VL_DEBUG_FUNC; // Declare debug()
void cantInline(const char* reason, bool hard) {
if (hard) {
if (m_modp->user2() != CIL_NOTHARD) {
UINFO(4," No inline hard: "<<reason<<" "<<m_modp<<endl);
m_modp->user2(CIL_NOTHARD);
++m_statUnsup;
}
} else {
if (m_modp->user2() == CIL_MAYBE) {
UINFO(4," No inline soft: "<<reason<<" "<<m_modp<<endl);
m_modp->user2(CIL_NOTSOFT);
}
}
if (hard) {
if (m_modp->user2() != CIL_NOTHARD) {
UINFO(4," No inline hard: "<<reason<<" "<<m_modp<<endl);
m_modp->user2(CIL_NOTHARD);
++m_statUnsup;
}
} else {
if (m_modp->user2() == CIL_MAYBE) {
UINFO(4," No inline soft: "<<reason<<" "<<m_modp<<endl);
m_modp->user2(CIL_NOTSOFT);
}
}
}
// VISITORS
virtual void visit(AstNodeModule* nodep) {
m_modp = nodep;
m_modp = nodep;
m_allMods.push_back(nodep);
m_modp->user2(CIL_MAYBE);
m_modp->user4(0); // statement count
m_modp->user2(CIL_MAYBE);
m_modp->user4(0); // statement count
if (VN_IS(m_modp, Iface)) {
// Inlining an interface means we no longer have a cell handle to resolve to.
// If inlining moves post-scope this can perhaps be relaxed.
cantInline("modIface",true);
}
if (m_modp->modPublic()) cantInline("modPublic",false);
// Inlining an interface means we no longer have a cell handle to resolve to.
// If inlining moves post-scope this can perhaps be relaxed.
cantInline("modIface", true);
}
if (m_modp->modPublic()) cantInline("modPublic", false);
iterateChildren(nodep);
m_modp = NULL;
m_modp = NULL;
}
virtual void visit(AstCell* nodep) {
nodep->modp()->user3Inc(); // Inc refs
@@ -121,42 +121,42 @@ private:
iterateChildren(nodep);
}
virtual void visit(AstPragma* nodep) {
if (nodep->pragType() == AstPragmaType::INLINE_MODULE) {
//UINFO(0,"PRAG MARK "<<m_modp<<endl);
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
if (nodep->pragType() == AstPragmaType::INLINE_MODULE) {
//UINFO(0,"PRAG MARK "<<m_modp<<endl);
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
} else if (m_modp->user2() == CIL_MAYBE
|| m_modp->user2() == CIL_NOTSOFT) {
m_modp->user2(CIL_USER);
}
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
} else {
cantInline("Pragma NO_INLINE_MODULE",false);
}
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else {
}
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
} else {
cantInline("Pragma NO_INLINE_MODULE", false);
}
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else {
iterateChildren(nodep);
}
}
}
virtual void visit(AstVarXRef* nodep) {
// Cleanup link until V3LinkDot can correct it
nodep->varp(NULL);
// Cleanup link until V3LinkDot can correct it
nodep->varp(NULL);
}
virtual void visit(AstNodeFTaskRef* nodep) {
// Cleanup link until V3LinkDot can correct it
if (!nodep->packagep()) nodep->taskp(NULL);
// Cleanup link until V3LinkDot can correct it
if (!nodep->packagep()) nodep->taskp(NULL);
iterateChildren(nodep);
}
virtual void visit(AstAlways* nodep) {
iterateChildren(nodep);
m_modp->user4Inc(); // statement count
m_modp->user4Inc(); // statement count
}
virtual void visit(AstNodeAssign* nodep) {
// Don't count assignments, as they'll likely flatten out
// Still need to iterate though to nullify VarXRefs
// Don't count assignments, as they'll likely flatten out
// Still need to iterate though to nullify VarXRefs
int oldcnt = m_modp->user4();
iterateChildren(nodep);
m_modp->user4(oldcnt);
@@ -208,20 +208,20 @@ private:
iterateChildren(nodep);
if (m_modp) {
m_modp->user4Inc(); // Inc statement count
}
}
}
public:
// CONSTUCTORS
explicit InlineMarkVisitor(AstNode* nodep) {
m_modp = NULL;
m_modp = NULL;
iterate(nodep);
}
virtual ~InlineMarkVisitor() {
V3Stats::addStat("Optimizations, Inline unsupported", m_statUnsup);
// Done with these, are not outputs
AstNode::user2ClearTree();
AstNode::user3ClearTree();
V3Stats::addStat("Optimizations, Inline unsupported", m_statUnsup);
// Done with these, are not outputs
AstNode::user2ClearTree();
AstNode::user3ClearTree();
AstNode::user4ClearTree();
}
};
@@ -234,14 +234,14 @@ class InlineCollectVisitor : public AstNVisitor {
private:
// NODE STATE
// Output:
// AstCell::user4p() // AstCell* of the created clone
// AstCell::user4p() // AstCell* of the created clone
// METHODS
VL_DEBUG_FUNC; // Declare debug()
// VISITORS
virtual void visit(AstCell* nodep) {
nodep->user4p(nodep->clonep());
nodep->user4p(nodep->clonep());
}
// Accelerate
virtual void visit(AstNodeStmt* nodep) {}
@@ -271,52 +271,52 @@ private:
// STATE
StringSet m_renamedInterfaces; // Name of renamed interface variables
AstNodeModule* m_modp; // Current module
AstCell* m_cellp; // Cell being cloned
AstNodeModule* m_modp; // Current module
AstCell* m_cellp; // Cell being cloned
// METHODS
VL_DEBUG_FUNC; // Declare debug()
// VISITORS
virtual void visit(AstCellInline* nodep) {
// Inlined cell under the inline cell, need to move to avoid conflicts
nodep->unlinkFrBack();
m_modp->addInlinesp(nodep);
// Rename
string name = m_cellp->name() + "__DOT__" + nodep->name();
nodep->name(name);
UINFO(6, " Inline "<<nodep<<endl);
// Do CellInlines under this, but don't move them
// Inlined cell under the inline cell, need to move to avoid conflicts
nodep->unlinkFrBack();
m_modp->addInlinesp(nodep);
// Rename
string name = m_cellp->name() + "__DOT__" + nodep->name();
nodep->name(name);
UINFO(6, " Inline "<<nodep<<endl);
// Do CellInlines under this, but don't move them
iterateChildren(nodep);
}
virtual void visit(AstCell* nodep) {
// Cell under the inline cell, need to rename to avoid conflicts
string name = m_cellp->name() + "__DOT__" + nodep->name();
nodep->name(name);
// Cell under the inline cell, need to rename to avoid conflicts
string name = m_cellp->name() + "__DOT__" + nodep->name();
nodep->name(name);
iterateChildren(nodep);
}
virtual void visit(AstModule* nodep) {
m_renamedInterfaces.clear();
m_renamedInterfaces.clear();
iterateChildren(nodep);
}
virtual void visit(AstVar* nodep) {
if (nodep->user2p()) {
// Make an assignment, so we'll trace it properly
// user2p is either a const or a var.
if (nodep->user2p()) {
// Make an assignment, so we'll trace it properly
// user2p is either a const or a var.
AstConst* exprconstp = VN_CAST(nodep->user2p(), Const);
AstVarRef* exprvarrefp = VN_CAST(nodep->user2p(), VarRef);
UINFO(8,"connectto: "<<nodep->user2p()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
}
if (exprconstp) {
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
exprconstp->cloneTree(true)));
} else if (nodep->user3()) {
// Public variable at the lower module end - we need to make sure we propagate
// the logic changes up and down; if we aliased, we might remove the change detection
// on the output variable.
UINFO(8,"connectto: "<<nodep->user2p()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
}
if (exprconstp) {
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
exprconstp->cloneTree(true)));
} else if (nodep->user3()) {
// Public variable at the lower module end - we need to make sure we propagate
// the logic changes up and down; if we aliased, we might
// remove the change detection on the output variable.
UINFO(9,"public pin assign: "<<exprvarrefp<<endl);
if (nodep->isNonOutput()) nodep->v3fatalSrc("Outputs only - inputs use AssignAlias");
m_modp->addStmtp(
@@ -327,82 +327,87 @@ private:
m_modp->addStmtp(
new AstAssignVarScope(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false)));
AstNode* nodebp=exprvarrefp->varp();
new AstVarRef(nodep->fileline(),
exprvarrefp->varp(), false)));
AstNode* nodebp = exprvarrefp->varp();
nodep ->fileline()->modifyStateInherit(nodebp->fileline());
nodebp->fileline()->modifyStateInherit(nodep ->fileline());
} else {
// Do to inlining child's variable now within the same module, so a AstVarRef not AstVarXRef below
// Do to inlining child's variable now within the same
// module, so a AstVarRef not AstVarXRef below
m_modp->addStmtp(
new AstAssignAlias(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false)));
AstNode* nodebp=exprvarrefp->varp();
nodep ->fileline()->modifyStateInherit(nodebp->fileline());
nodebp->fileline()->modifyStateInherit(nodep ->fileline());
}
}
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
new AstVarRef(nodep->fileline(),
exprvarrefp->varp(), false)));
AstNode* nodebp = exprvarrefp->varp();
nodep ->fileline()->modifyStateInherit(nodebp->fileline());
nodebp->fileline()->modifyStateInherit(nodep ->fileline());
}
}
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
if (AstIfaceRefDType* ifacerefp = VN_CAST(nodep->dtypep(), IfaceRefDType)) {
m_renamedInterfaces.insert(nodep->name());
// Each inlined cell that contain an interface variable need to copy the IfaceRefDType and point it to
// the newly cloned interface cell.
m_renamedInterfaces.insert(nodep->name());
// Each inlined cell that contain an interface variable need to
// copy the IfaceRefDType and point it to the newly cloned
// interface cell.
AstIfaceRefDType* newdp = VN_CAST(ifacerefp->cloneTree(false), IfaceRefDType);
nodep->dtypep(newdp);
ifacerefp->addNextHere(newdp);
// Relink to point to newly cloned cell
if (newdp->cellp()) {
nodep->dtypep(newdp);
ifacerefp->addNextHere(newdp);
// Relink to point to newly cloned cell
if (newdp->cellp()) {
if (AstCell* newcellp = VN_CAST(newdp->cellp()->user4p(), Cell)) {
newdp->cellp(newcellp);
newdp->cellName(newcellp->name());
// Tag the old ifacerefp to ensure it leaves no stale reference to the inlined cell.
newdp->user5(false);
ifacerefp->user5(true);
}
}
}
// Variable under the inline cell, need to rename to avoid conflicts
// Also clear I/O bits, as it is now local.
string name = m_cellp->name() + "__DOT__" + nodep->name();
if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name);
if (!m_cellp->isTrace()) nodep->trace(false);
if (debug()>=9) { nodep->dumpTree(cout,"varchanged:"); }
if (debug()>=9 && nodep->valuep()) { nodep->valuep()->dumpTree(cout,"varchangei:"); }
newdp->cellp(newcellp);
newdp->cellName(newcellp->name());
// Tag the old ifacerefp to ensure it leaves no stale
// reference to the inlined cell.
newdp->user5(false);
ifacerefp->user5(true);
}
}
}
// Variable under the inline cell, need to rename to avoid conflicts
// Also clear I/O bits, as it is now local.
string name = m_cellp->name() + "__DOT__" + nodep->name();
if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name);
if (!m_cellp->isTrace()) nodep->trace(false);
if (debug()>=9) { nodep->dumpTree(cout, "varchanged:"); }
if (debug()>=9 && nodep->valuep()) { nodep->valuep()->dumpTree(cout, "varchangei:"); }
iterateChildren(nodep);
}
virtual void visit(AstNodeFTask* nodep) {
// Function under the inline cell, need to rename to avoid conflicts
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
// Function under the inline cell, need to rename to avoid conflicts
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
iterateChildren(nodep);
}
virtual void visit(AstTypedef* nodep) {
// Typedef under the inline cell, need to rename to avoid conflicts
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
// Typedef under the inline cell, need to rename to avoid conflicts
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
iterateChildren(nodep);
}
virtual void visit(AstVarRef* nodep) {
if (nodep->varp()->user2p() // It's being converted to an alias.
&& !nodep->varp()->user3()
if (nodep->varp()->user2p() // It's being converted to an alias.
&& !nodep->varp()->user3()
&& !VN_IS(nodep->backp(), AssignAlias)) { // Don't constant propagate aliases (we just made)
AstConst* exprconstp = VN_CAST(nodep->varp()->user2p(), Const);
AstVarRef* exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef);
if (exprconstp) {
nodep->replaceWith(exprconstp->cloneTree(true));
nodep->deleteTree(); VL_DANGLING(nodep);
return;
}
else if (exprvarrefp) {
nodep->varp( exprvarrefp->varp() );
}
else {
nodep->v3fatalSrc("Null connection?");
}
}
nodep->name(nodep->varp()->name());
if (exprconstp) {
nodep->replaceWith(exprconstp->cloneTree(true));
nodep->deleteTree(); VL_DANGLING(nodep);
return;
}
else if (exprvarrefp) {
nodep->varp( exprvarrefp->varp() );
}
else {
nodep->v3fatalSrc("Null connection?");
}
}
nodep->name(nodep->varp()->name());
iterateChildren(nodep);
}
virtual void visit(AstVarXRef* nodep) {
// Track what scope it was originally under so V3LinkDot can resolve it
// Track what scope it was originally under so V3LinkDot can resolve it
string newdots = VString::dot(m_cellp->name(), ".", nodep->inlinedDots());
nodep->inlinedDots(newdots);
for (string tryname = nodep->dotted(); 1;) {
@@ -421,13 +426,13 @@ private:
iterateChildren(nodep);
}
virtual void visit(AstNodeFTaskRef* nodep) {
// Track what scope it was originally under so V3LinkDot can resolve it
// Track what scope it was originally under so V3LinkDot can resolve it
string newdots = VString::dot(m_cellp->name(), ".", nodep->inlinedDots());
nodep->inlinedDots(newdots);
if (m_renamedInterfaces.count(nodep->dotted())) {
nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted());
}
UINFO(8," "<<nodep<<endl);
if (m_renamedInterfaces.count(nodep->dotted())) {
nodep->dotted(m_cellp->name() + "__DOT__" + nodep->dotted());
}
UINFO(8," "<<nodep<<endl);
iterateChildren(nodep);
}
@@ -435,21 +440,21 @@ private:
//virtual void visit(AstRefDType* nodep) {}
virtual void visit(AstScopeName* nodep) {
// If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Begin
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext();
// If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Begin
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp(new AstText(nodep->fileline(), string("__DOT__")+m_cellp->name()));
if (afterp) nodep->scopeAttrp(afterp);
afterp = nodep->scopeEntrp();
if (afterp) afterp->unlinkFrBackWithNext();
if (afterp) nodep->scopeAttrp(afterp);
afterp = nodep->scopeEntrp();
if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeEntrp(new AstText(nodep->fileline(), string("__DOT__")+m_cellp->name()));
if (afterp) nodep->scopeEntrp(afterp);
if (afterp) nodep->scopeEntrp(afterp);
iterateChildren(nodep);
}
virtual void visit(AstCoverDecl* nodep) {
// Fix path in coverage statements
// Fix path in coverage statements
nodep->hier(VString::dot(m_cellp->prettyName(), ".", nodep->hier()));
iterateChildren(nodep);
}
@@ -460,8 +465,8 @@ private:
public:
// CONSTUCTORS
InlineRelinkVisitor(AstNodeModule* cloneModp, AstNodeModule* oldModp, AstCell* cellp) {
m_modp = oldModp;
m_cellp = cellp;
m_modp = oldModp;
m_cellp = cellp;
iterate(cloneModp);
}
virtual ~InlineRelinkVisitor() {}
@@ -474,81 +479,83 @@ class InlineVisitor : public AstNVisitor {
private:
// NODE STATE
// Cleared entire netlist
// AstIfaceRefDType::user5p() // Whether the cell pointed to by this AstIfaceRefDType has been inlined
// AstIfaceRefDType::user5p() // Whether the cell pointed to by this
// // AstIfaceRefDType has been inlined
// Input:
// AstNodeModule::user1p() // bool. True to inline this module (from InlineMarkVisitor)
// AstNodeModule::user1p() // bool. True to inline this module (from InlineMarkVisitor)
// Cleared each cell
// AstVar::user2p() // AstVarRef*/AstConst* Points to signal this is a direct connect to
// AstVar::user3() // bool Don't alias the user2, keep it as signal
// AstCell::user4 // AstCell* of the created clone
// AstVar::user2p() // AstVarRef*/AstConst* Points to signal this
// // is a direct connect to
// AstVar::user3() // bool Don't alias the user2, keep it as signal
// AstCell::user4 // AstCell* of the created clone
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
AstUser4InUse m_inuser4;
AstUser5InUse m_inuser5;
AstUser5InUse m_inuser5;
// STATE
AstNodeModule* m_modp; // Current module
V3Double0 m_statCells; // Statistic tracking
V3Double0 m_statCells; // Statistic tracking
// METHODS
VL_DEBUG_FUNC; // Declare debug()
// VISITORS
virtual void visit(AstNetlist* nodep) {
// Iterate modules backwards, in bottom-up order. Required!
// Iterate modules backwards, in bottom-up order. Required!
iterateChildrenBackwards(nodep);
}
virtual void visit(AstIfaceRefDType* nodep) {
if (nodep->user5()) {
// The cell has been removed so let's make sure we don't leave a reference to it
// This dtype may still be in use by the AstAssignVarScope created earlier
// but that'll get cleared up later
nodep->cellp(NULL);
}
if (nodep->user5()) {
// The cell has been removed so let's make sure we don't leave a reference to it
// This dtype may still be in use by the AstAssignVarScope created earlier
// but that'll get cleared up later
nodep->cellp(NULL);
}
}
virtual void visit(AstNodeModule* nodep) {
m_modp = nodep;
m_modp = nodep;
iterateChildren(nodep);
}
virtual void visit(AstCell* nodep) {
if (nodep->modp()->user1()) { // Marked with inline request
UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl);
++m_statCells;
if (nodep->modp()->user1()) { // Marked with inline request
UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl);
++m_statCells;
// Before cloning simplify pin assignments
// Better off before, as if module has multiple instantiations
// we'll save work, and we can't call pinReconnectSimple in
// this loop as it clone()s itself.
// Before cloning simplify pin assignments
// Better off before, as if module has multiple instantiations
// we'll save work, and we can't call pinReconnectSimple in
// this loop as it clone()s itself.
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (!pinp->exprp()) continue;
if (!pinp->exprp()) continue;
V3Inst::pinReconnectSimple(pinp, nodep, false);
}
}
// Clone original module
if (debug()>=9) { nodep->dumpTree(cout,"inlcell:"); }
//if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); }
AstNodeModule* newmodp = nodep->modp()->cloneTree(false);
if (debug()>=9) { newmodp->dumpTree(cout,"newmod:"); }
// Clear var markings and find cell cross references
AstNode::user2ClearTree();
AstNode::user4ClearTree();
{ InlineCollectVisitor(nodep->modp()); } // {} to destroy visitor immediately
// Create data for dotted variable resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
nodep->name(), nodep->modp()->origName());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
// Create assignments to the pins
// Clone original module
if (debug()>=9) { nodep->dumpTree(cout, "inlcell:"); }
//if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); }
AstNodeModule* newmodp = nodep->modp()->cloneTree(false);
if (debug()>=9) { newmodp->dumpTree(cout, "newmod:"); }
// Clear var markings and find cell cross references
AstNode::user2ClearTree();
AstNode::user4ClearTree();
{ InlineCollectVisitor(nodep->modp()); } // {} to destroy visitor immediately
// Create data for dotted variable resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
nodep->name(), nodep->modp()->origName());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
// Create assignments to the pins
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
if (!pinp->exprp()) continue;
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// Make new signal; even though we'll optimize the interconnect, we
// need an alias to trace correctly. If tracing is disabled, we'll
// delete it in later optimizations.
AstVar* pinOldVarp = pinp->modVarp();
AstVar* pinNewVarp = pinOldVarp->clonep();
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
if (!pinp->exprp()) continue;
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// Make new signal; even though we'll optimize the interconnect, we
// need an alias to trace correctly. If tracing is disabled, we'll
// delete it in later optimizations.
AstVar* pinOldVarp = pinp->modVarp();
AstVar* pinNewVarp = pinOldVarp->clonep();
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
AstNode* connectRefp = pinp->exprp();
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
@@ -556,18 +563,18 @@ private:
}
V3Inst::checkOutputShort(pinp);
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
if (VN_IS(connectRefp, VarRef)) {
VN_CAST(connectRefp, VarRef)->varp()->propagateAttrFrom(pinOldVarp);
}
}
// One to one interconnect won't make a temporary variable.
// This prevents creating a lot of extra wires for clock signals.
// It will become a tracing alias.
UINFO(6,"One-to-one "<<connectRefp<<endl);
UINFO(6," -to "<<pinNewVarp<<endl);
pinNewVarp->user2p(connectRefp);
// One to one interconnect won't make a temporary variable.
// This prevents creating a lot of extra wires for clock signals.
// It will become a tracing alias.
UINFO(6,"One-to-one "<<connectRefp<<endl);
UINFO(6," -to "<<pinNewVarp<<endl);
pinNewVarp->user2p(connectRefp);
// Public output inside the cell must go via an assign rather
// than alias. Else the public logic will set the alias, losing
// the value to be propagated up (InOnly isn't a problem as the
@@ -575,19 +582,19 @@ private:
pinNewVarp->user3(pinNewVarp->isSigUserRWPublic()
&& pinNewVarp->direction()==VDirection::OUTPUT);
}
// Cleanup var names, etc, to not conflict
{ InlineRelinkVisitor(newmodp, m_modp, nodep); }
// Move statements to top module
if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); }
AstNode* stmtsp = newmodp->stmtsp();
if (stmtsp) stmtsp->unlinkFrBackWithNext();
if (stmtsp) m_modp->addStmtp(stmtsp);
// Remove the cell
newmodp->deleteTree(); VL_DANGLING(newmodp); // Clear any leftover ports, etc
nodep->unlinkFrBack();
pushDeletep(nodep); VL_DANGLING(nodep);
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
}
// Cleanup var names, etc, to not conflict
{ InlineRelinkVisitor(newmodp, m_modp, nodep); }
// Move statements to top module
if (debug()>=9) { newmodp->dumpTree(cout, "fixmod:"); }
AstNode* stmtsp = newmodp->stmtsp();
if (stmtsp) stmtsp->unlinkFrBackWithNext();
if (stmtsp) m_modp->addStmtp(stmtsp);
// Remove the cell
newmodp->deleteTree(); VL_DANGLING(newmodp); // Clear any leftover ports, etc
nodep->unlinkFrBack();
pushDeletep(nodep); VL_DANGLING(nodep);
if (debug()>=9) { m_modp->dumpTree(cout, "donemod:"); }
}
}
//--------------------
@@ -600,11 +607,11 @@ private:
public:
// CONSTUCTORS
explicit InlineVisitor(AstNode* nodep) {
m_modp = NULL;
m_modp = NULL;
iterate(nodep);
}
virtual ~InlineVisitor() {
V3Stats::addStat("Optimizations, Inlined cells", m_statCells);
V3Stats::addStat("Optimizations, Inlined cells", m_statCells);
}
};
@@ -613,8 +620,8 @@ public:
void V3Inline::inlineAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AstUser1InUse m_inuser1; // output of InlineMarkVisitor,
// input to InlineVisitor.
AstUser1InUse m_inuser1; // output of InlineMarkVisitor,
// input to InlineVisitor.
{
// Scoped to clean up temp userN's
InlineMarkVisitor mvisitor (nodep);
@@ -628,9 +635,9 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
AstNodeModule* nextmodp;
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
nextmodp = VN_CAST(modp->nextp(), NodeModule);
if (modp->user1()) { // Was inlined
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
}
if (modp->user1()) { // Was inlined
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
}
}
V3Global::dumpCheckGlobalTree("inline", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}