mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
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:
+153
-142
@@ -20,9 +20,9 @@
|
||||
// V3LinkJump's Transformations:
|
||||
//
|
||||
// Each module:
|
||||
// Look for BEGINs
|
||||
// BEGIN(VAR...) -> VAR ... {renamed}
|
||||
// FOR -> WHILEs
|
||||
// Look for BEGINs
|
||||
// BEGIN(VAR...) -> VAR ... {renamed}
|
||||
// FOR -> WHILEs
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
@@ -45,194 +45,205 @@ private:
|
||||
typedef std::vector<AstBegin*> BeginStack;
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Current function/task
|
||||
AstWhile* m_loopp; // Current loop
|
||||
bool m_loopInc; // In loop increment
|
||||
int m_repeatNum; // Repeat counter
|
||||
BeginStack m_beginStack; // All begin blocks above current node
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Current function/task
|
||||
AstWhile* m_loopp; // Current loop
|
||||
bool m_loopInc; // In loop increment
|
||||
int m_repeatNum; // Repeat counter
|
||||
BeginStack m_beginStack; // All begin blocks above current node
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) {
|
||||
// Put label under given node, and if WHILE optionally at end of iteration
|
||||
UINFO(4,"Create label for "<<nodep<<endl);
|
||||
// Put label under given node, and if WHILE optionally at end of iteration
|
||||
UINFO(4,"Create label for "<<nodep<<endl);
|
||||
if (VN_IS(nodep, JumpLabel)) return VN_CAST(nodep, JumpLabel); // Done
|
||||
|
||||
AstNode* underp = NULL;
|
||||
bool under_and_next = true;
|
||||
AstNode* underp = NULL;
|
||||
bool under_and_next = true;
|
||||
if (VN_IS(nodep, Begin)) underp = VN_CAST(nodep, Begin)->stmtsp();
|
||||
else if (VN_IS(nodep, NodeFTask)) underp = VN_CAST(nodep, NodeFTask)->stmtsp();
|
||||
else if (VN_IS(nodep, While)) {
|
||||
if (endOfIter) {
|
||||
// Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip
|
||||
if (endOfIter) {
|
||||
// Note we jump to end of bodysp; a FOR loop has its
|
||||
// increment under incsp() which we don't skip
|
||||
underp = VN_CAST(nodep, While)->bodysp();
|
||||
} else {
|
||||
underp = nodep; under_and_next=false; // IE we skip the entire while
|
||||
}
|
||||
}
|
||||
else {
|
||||
nodep->v3fatalSrc("Unknown jump point for break/disable/continue");
|
||||
return NULL;
|
||||
}
|
||||
// Skip over variables as we'll just move them in a momement
|
||||
// Also this would otherwise prevent us from using a label twice
|
||||
// see t_func_return test.
|
||||
} else {
|
||||
underp = nodep; under_and_next = false; // IE we skip the entire while
|
||||
}
|
||||
}
|
||||
else {
|
||||
nodep->v3fatalSrc("Unknown jump point for break/disable/continue");
|
||||
return NULL;
|
||||
}
|
||||
// Skip over variables as we'll just move them in a momement
|
||||
// Also this would otherwise prevent us from using a label twice
|
||||
// see t_func_return test.
|
||||
while (underp && VN_IS(underp, Var)) underp = underp->nextp();
|
||||
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
|
||||
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
|
||||
|
||||
if (!underp) {
|
||||
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
|
||||
return NULL;
|
||||
if (!underp) {
|
||||
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
|
||||
return NULL;
|
||||
} else if (VN_IS(underp, JumpLabel)) {
|
||||
return VN_CAST(underp, JumpLabel);
|
||||
} else { // Move underp stuff to be under a new label
|
||||
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL);
|
||||
} else { // Move underp stuff to be under a new label
|
||||
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL);
|
||||
|
||||
AstNRelinker repHandle;
|
||||
if (under_and_next) underp->unlinkFrBackWithNext(&repHandle);
|
||||
else underp->unlinkFrBack(&repHandle);
|
||||
repHandle.relink(labelp);
|
||||
AstNRelinker repHandle;
|
||||
if (under_and_next) underp->unlinkFrBackWithNext(&repHandle);
|
||||
else underp->unlinkFrBack(&repHandle);
|
||||
repHandle.relink(labelp);
|
||||
|
||||
labelp->addStmtsp(underp);
|
||||
// Keep any AstVars under the function not under the new JumpLabel
|
||||
for (AstNode* nextp, *varp=underp; varp; varp = nextp) {
|
||||
nextp = varp->nextp();
|
||||
labelp->addStmtsp(underp);
|
||||
// Keep any AstVars under the function not under the new JumpLabel
|
||||
for (AstNode* nextp, *varp=underp; varp; varp = nextp) {
|
||||
nextp = varp->nextp();
|
||||
if (VN_IS(varp, Var)) {
|
||||
labelp->addPrev(varp->unlinkFrBack());
|
||||
}
|
||||
}
|
||||
return labelp;
|
||||
}
|
||||
labelp->addPrev(varp->unlinkFrBack());
|
||||
}
|
||||
}
|
||||
return labelp;
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
if (nodep->dead()) return;
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
if (nodep->dead()) return;
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
iterateChildren(nodep);
|
||||
m_modp = NULL;
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
m_ftaskp = nodep;
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_ftaskp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
m_beginStack.push_back(nodep);
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
m_beginStack.push_back(nodep);
|
||||
iterateChildren(nodep);
|
||||
m_beginStack.pop_back();
|
||||
m_beginStack.pop_back();
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep) {
|
||||
// So later optimizations don't need to deal with them,
|
||||
// REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
|
||||
// Note var can be signed or unsigned based on original number.
|
||||
AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
|
||||
string name = string("__Vrepeat")+cvtToStr(m_repeatNum++);
|
||||
// Spec says value is integral, if negative is ignored
|
||||
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
nodep->findSigned32DType());
|
||||
varp->usedLoopIdx(true);
|
||||
m_modp->addStmtp(varp);
|
||||
AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
|
||||
countp);
|
||||
AstNode* decp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
|
||||
new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
|
||||
// So later optimizations don't need to deal with them,
|
||||
// REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
|
||||
// Note var can be signed or unsigned based on original number.
|
||||
AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
|
||||
string name = string("__Vrepeat")+cvtToStr(m_repeatNum++);
|
||||
// Spec says value is integral, if negative is ignored
|
||||
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
nodep->findSigned32DType());
|
||||
varp->usedLoopIdx(true);
|
||||
m_modp->addStmtp(varp);
|
||||
AstNode* initsp = new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), varp, true),
|
||||
countp);
|
||||
AstNode* decp = new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), varp, true),
|
||||
new AstSub(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), varp, false),
|
||||
new AstConst(nodep->fileline(), 1)));
|
||||
V3Number zero (nodep, 32, 0); zero.isSigned(true);
|
||||
V3Number zero (nodep, 32, 0); zero.isSigned(true);
|
||||
AstNode* zerosp = new AstConst(nodep->fileline(), zero);
|
||||
AstNode* condp = new AstGtS(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
|
||||
zerosp);
|
||||
AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext();
|
||||
AstNode* newp = new AstWhile(nodep->fileline(),
|
||||
condp,
|
||||
bodysp,
|
||||
decp);
|
||||
initsp = initsp->addNext(newp);
|
||||
newp = initsp;
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
AstNode* condp = new AstGtS(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), varp, false),
|
||||
zerosp);
|
||||
AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext();
|
||||
AstNode* newp = new AstWhile(nodep->fileline(),
|
||||
condp,
|
||||
bodysp,
|
||||
decp);
|
||||
initsp = initsp->addNext(newp);
|
||||
newp = initsp;
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) {
|
||||
// Don't need to track AstRepeat/AstFor as they have already been converted
|
||||
AstWhile* lastLoopp = m_loopp;
|
||||
bool lastInc = m_loopInc;
|
||||
m_loopp = nodep;
|
||||
m_loopInc = false;
|
||||
// Don't need to track AstRepeat/AstFor as they have already been converted
|
||||
AstWhile* lastLoopp = m_loopp;
|
||||
bool lastInc = m_loopInc;
|
||||
m_loopp = nodep;
|
||||
m_loopInc = false;
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
m_loopInc = true;
|
||||
m_loopInc = true;
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
m_loopInc = lastInc;
|
||||
m_loopp = lastLoopp;
|
||||
m_loopInc = lastInc;
|
||||
m_loopp = lastLoopp;
|
||||
}
|
||||
virtual void visit(AstReturn* nodep) {
|
||||
iterateChildren(nodep);
|
||||
AstFunc* funcp = VN_CAST(m_ftaskp, Func);
|
||||
if (!m_ftaskp) { nodep->v3error("Return isn't underneath a task or function"); }
|
||||
else if (funcp && !nodep->lhsp()) { nodep->v3error("Return underneath a function should have return value"); }
|
||||
else if (!funcp && nodep->lhsp()) { nodep->v3error("Return underneath a task shouldn't have return value"); }
|
||||
else {
|
||||
if (funcp && nodep->lhsp()) {
|
||||
// Set output variable to return value
|
||||
nodep->addPrev(new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), VN_CAST(funcp->fvarp(), Var), true),
|
||||
nodep->lhsp()->unlinkFrBackWithNext()));
|
||||
}
|
||||
// Jump to the end of the function call
|
||||
AstJumpLabel* labelp = findAddLabel(m_ftaskp, false);
|
||||
nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
if (!m_ftaskp) {
|
||||
nodep->v3error("Return isn't underneath a task or function");
|
||||
} else if (funcp && !nodep->lhsp()) {
|
||||
nodep->v3error("Return underneath a function should have return value");
|
||||
} else if (!funcp && nodep->lhsp()) {
|
||||
nodep->v3error("Return underneath a task shouldn't have return value");
|
||||
} else {
|
||||
if (funcp && nodep->lhsp()) {
|
||||
// Set output variable to return value
|
||||
nodep->addPrev(new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(),
|
||||
VN_CAST(funcp->fvarp(), Var), true),
|
||||
nodep->lhsp()->unlinkFrBackWithNext()));
|
||||
}
|
||||
// Jump to the end of the function call
|
||||
AstJumpLabel* labelp = findAddLabel(m_ftaskp, false);
|
||||
nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstBreak* nodep) {
|
||||
iterateChildren(nodep);
|
||||
if (!m_loopp) { nodep->v3error("break isn't underneath a loop"); }
|
||||
else {
|
||||
// Jump to the end of the loop
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
if (!m_loopp) { nodep->v3error("break isn't underneath a loop"); }
|
||||
else {
|
||||
// Jump to the end of the loop
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstContinue* nodep) {
|
||||
iterateChildren(nodep);
|
||||
if (!m_loopp) { nodep->v3error("continue isn't underneath a loop"); }
|
||||
else {
|
||||
// Jump to the end of this iteration
|
||||
// If a "for" loop then need to still do the post-loop increment
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, true);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
if (!m_loopp) { nodep->v3error("continue isn't underneath a loop"); }
|
||||
else {
|
||||
// Jump to the end of this iteration
|
||||
// If a "for" loop then need to still do the post-loop increment
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, true);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstDisable* nodep) {
|
||||
UINFO(8," DISABLE "<<nodep<<endl);
|
||||
UINFO(8," DISABLE "<<nodep<<endl);
|
||||
iterateChildren(nodep);
|
||||
AstBegin* beginp = NULL;
|
||||
for (BeginStack::reverse_iterator it = m_beginStack.rbegin(); it != m_beginStack.rend(); ++it) {
|
||||
UINFO(9," UNDERBLK "<<*it<<endl);
|
||||
if ((*it)->name() == nodep->name()) {
|
||||
beginp = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labeli: "); }
|
||||
if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "<<nodep->prettyName()); }
|
||||
else {
|
||||
// Jump to the end of the named begin
|
||||
AstJumpLabel* labelp = findAddLabel(beginp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labelo: "); }
|
||||
AstBegin* beginp = NULL;
|
||||
for (BeginStack::reverse_iterator it = m_beginStack.rbegin();
|
||||
it != m_beginStack.rend(); ++it) {
|
||||
UINFO(9," UNDERBLK "<<*it<<endl);
|
||||
if ((*it)->name() == nodep->name()) {
|
||||
beginp = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout, " labeli: "); }
|
||||
if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "
|
||||
<<nodep->prettyName()); }
|
||||
else {
|
||||
// Jump to the end of the named begin
|
||||
AstJumpLabel* labelp = findAddLabel(beginp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout, " labelo: "); }
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true);
|
||||
if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true);
|
||||
}
|
||||
|
||||
virtual void visit(AstConst* nodep) {}
|
||||
@@ -242,11 +253,11 @@ private:
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
explicit LinkJumpVisitor(AstNetlist* nodep) {
|
||||
m_modp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
m_loopp = NULL;
|
||||
m_loopInc = false;
|
||||
m_repeatNum = 0;
|
||||
m_modp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
m_loopp = NULL;
|
||||
m_loopInc = false;
|
||||
m_repeatNum = 0;
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~LinkJumpVisitor() {}
|
||||
|
||||
Reference in New Issue
Block a user