本文整理汇总了C++中AstNode::backp方法的典型用法代码示例。如果您正苦于以下问题:C++ AstNode::backp方法的具体用法?C++ AstNode::backp怎么用?C++ AstNode::backp使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AstNode
的用法示例。
在下文中一共展示了AstNode::backp方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: processBlock
void processBlock(AstNode* nodep) {
if (!nodep) return; // Empty lists are ignorable
// Pass the first node in a list of block items, we'll process them
// Check there's >= 2 sub statements, else nothing to analyze
// Save recursion state
AstNode* firstp = nodep; // We may reorder, and nodep is no longer first.
void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
nodep->user3p(NULL);
if (!nodep->firstAbovep()) nodep->v3fatalSrc("Node passed is in next list; should have processed all list at once");
// Process it
if (!nodep->nextp()) {
// Just one, so can't reorder. Just look for more blocks/statements.
iterate(nodep);
} else {
UINFO(9," processBlock "<<nodep<<endl);
// Process block and followers
scanBlock(nodep);
if (m_noReorderWhy != "") { // Jump or something nasty
UINFO(9," NoReorderBlock because "<<m_noReorderWhy<<endl);
} else {
// Reorder statements in this block
cleanupBlockGraph(nodep);
reorderBlock(nodep);
// Delete old vertexes and edges only applying to this block
while (firstp->backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list
for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
vvertexp->unlinkDelete(&m_graph);
}
}
}
// Again, nodep may no longer be first.
firstp->user3p(oldBlockUser3);
}
示例2: visit
virtual void visit(AstDefImplicitDType* nodep, AstNUser*) {
cleanFileline(nodep);
UINFO(8," DEFIMPLICIT "<<nodep<<endl);
// Must remember what names we've already created, and combine duplicates
// so that for "var enum {...} a,b" a & b will share a common typedef
// Unique name space under each containerp() so that an addition of a new type won't change every verilated module.
AstTypedef* defp = NULL;
ImplTypedefMap::iterator it = m_implTypedef.find(make_pair(nodep->containerp(), nodep->name()));
if (it != m_implTypedef.end()) {
defp = it->second;
} else {
// Definition must be inserted right after the variable (etc) that needed it
// AstVar, AstTypedef, AstNodeFTask are common containers
AstNode* backp = nodep->backp();
for (; backp; backp=backp->backp()) {
if (backp->castVar()) break;
else if (backp->castTypedef()) break;
else if (backp->castNodeFTask()) break;
}
if (!backp) nodep->v3fatalSrc("Implicit enum/struct type created under unexpected node type");
AstNodeDType* dtypep = nodep->dtypep(); dtypep->unlinkFrBack();
if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing
// For typedefs just remove the AstRefDType level of abstraction
nodep->replaceWith(dtypep);
nodep->deleteTree(); nodep=NULL;
return;
} else {
defp = new AstTypedef(nodep->fileline(), nodep->name(), dtypep);
m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp));
backp->addNextHere(defp);
}
}
nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name()));
nodep->deleteTree(); nodep=NULL;
}
示例3: detectDuplicates
void detectDuplicates() {
UINFO(9,"Finding duplicates\n");
// Note uses user4
V3Hashed hashed; // Duplicate code detection
// Hash all of the original signals we toggle cover
for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) {
AstCoverToggle* nodep = *it;
hashed.hashAndInsert(nodep->origp());
}
// Find if there are any duplicates
for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) {
AstCoverToggle* nodep = *it;
if (nodep->backp()) { // nodep->backp() is null if we already detected it's a duplicate and unlinked it
// Want to choose a base node, and keep finding duplicates that are identical
// This prevents making chains where a->b, then c->d, then b->c, as we'll find a->b, a->c, a->d directly.
while (1) {
V3Hashed::iterator dupit = hashed.findDuplicate(nodep->origp());
if (dupit == hashed.end()) break;
//
AstNode* duporigp = hashed.iteratorNodep(dupit);
// Note hashed will point to the original variable (what's duplicated), not the covertoggle,
// but we need to get back to the covertoggle which is immediately above, so:
AstCoverToggle* removep = duporigp->backp()->castCoverToggle();
if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
UINFO(8," Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
UINFO(8," dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);
// The CoverDecl the duplicate pointed to now needs to point to the original's data
// IE the duplicate will get the coverage number from the non-duplicate
AstCoverDecl* datadeclp = nodep->incp()->declp()->dataDeclThisp();
removep->incp()->declp()->dataDeclp (datadeclp);
UINFO(8," new "<<removep->incp()->declp()<<endl);
// Mark the found node as a duplicate of the first node
// (Not vice-versa as we have the iterator for the found node)
removep->unlinkFrBack(); pushDeletep(removep); removep=NULL;
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
++m_statToggleJoins;
}
}
}
}
示例4: visit
virtual void visit(AstSenItem* nodep, AstNUser*) {
// Remove bit selects, and bark if it's not a simple variable
nodep->iterateChildren(*this);
if (nodep->isClocked()) {
// If it's not a simple variable wrap in a temporary
// This is a bit unfortunate as we haven't done width resolution
// and any width errors will look a bit odd, but it works.
AstNode* sensp = nodep->sensp();
if (sensp
&& !sensp->castNodeVarRef()
&& !sensp->castConst()) {
// Make a new temp wire
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname,
VFlagLogicPacked(), 1);
// We can't just add under the module, because we may be inside a generate, begin, etc.
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
AstNode* addwherep = nodep; // Add to this element's next
while (addwherep->castSenItem()
|| addwherep->castSenTree()) {
addwherep = addwherep->backp();
}
if (!addwherep->castAlways()) { // Assertion perhaps?
sensp->v3error("Unsupported: Non-single-bit pos/negedge clock statement under some complicated block");
addwherep = m_modp;
}
addwherep->addNext(newvarp);
sensp->replaceWith(new AstVarRef (sensp->fileline(), newvarp, false));
AstAssignW* assignp = new AstAssignW
(sensp->fileline(),
new AstVarRef(sensp->fileline(), newvarp, true),
sensp);
addwherep->addNext(assignp);
}
} else { // Old V1995 sensitivity list; we'll probably mostly ignore
bool did=1;
while (did) {
did=0;
if (AstNodeSel* selp = nodep->sensp()->castNodeSel()) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
did=1;
}
// NodeSel doesn't include AstSel....
if (AstSel* selp = nodep->sensp()->castSel()) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
did=1;
}
if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) {
AstNode* fromp = selp->lhsp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
did=1;
}
}
}
if (!nodep->sensp()->castNodeVarRef()
&& !nodep->sensp()->castEnumItemRef()) { // V3Const will cleanup
if (debug()) nodep->dumpTree(cout,"-tree: ");
nodep->v3error("Unsupported: Complex statement in sensitivity list");
}
}
示例5: replaceBoundLvalue
void replaceBoundLvalue(AstNode* nodep, AstNode* condp) {
// Spec says a out-of-range LHS SEL results in a NOP.
// This is a PITA. We could:
// 1. IF(...) around an ASSIGN,
// but that would break a "foo[TOO_BIG]=$fopen(...)".
// 2. Hack to extend the size of the output structure
// by one bit, and write to that temporary, but never read it.
// That makes there be two widths() and is likely a bug farm.
// 3. Make a special SEL to choose between the real lvalue
// and a temporary NOP register.
// 4. Assign to a temp, then IF that assignment.
// This is suspected to be nicest to later optimizations.
// 4 seems best but breaks later optimizations. 3 was tried,
// but makes a mess in the emitter as lvalue switching is needed. So 4.
// SEL(...) -> temp
// if (COND(LTE(bit<=maxlsb))) ASSIGN(SEL(...)),temp)
if (m_assignwp) {
// Wire assigns must become always statements to deal with insertion
// of multiple statements. Perhaps someday make all wassigns into always's?
UINFO(5," IM_WireRep "<<m_assignwp<<endl);
m_assignwp->convertToAlways(); pushDeletep(m_assignwp); m_assignwp=NULL;
}
bool needDly = (m_assigndlyp != NULL);
if (m_assigndlyp) {
// Delayed assignments become normal assignments,
// then the temp created becomes the delayed assignment
AstNode* newp = new AstAssign(m_assigndlyp->fileline(),
m_assigndlyp->lhsp()->unlinkFrBackWithNext(),
m_assigndlyp->rhsp()->unlinkFrBackWithNext());
m_assigndlyp->replaceWith(newp); pushDeletep(m_assigndlyp); m_assigndlyp=NULL;
}
AstNode* prep = nodep;
// Scan back to put the condlvalue above all selects (IE top of the lvalue)
while (prep->backp()->castNodeSel()
|| prep->backp()->castSel()) {
prep=prep->backp();
}
FileLine* fl = nodep->fileline();
VL_DANGLING(nodep); // Zap it so we don't use it by mistake - use prep
// Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b,
// Saves us teaching V3Const how to optimize, and it won't be needed again.
if (AstIf* ifp = prep->user2p()->castIf()) {
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
AstNRelinker replaceHandle;
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
AstNode* newp = new AstLogAnd (condp->fileline(),
condp,
earliercondp);
UINFO(4, "Edit BOUNDLVALUE "<<newp<<endl);
replaceHandle.relink(newp);
}
else {
string name = ((string)"__Vlvbound"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar(fl, AstVarType::MODULETEMP, name,
prep->dtypep());
m_modp->addStmtp(varp);
AstNode* abovep = prep->backp(); // Grab above point before lose it w/ next replace
prep->replaceWith(new AstVarRef(fl, varp, true));
AstNode* newp = new AstIf(fl, condp,
(needDly
? static_cast<AstNode*>
(new AstAssignDly(fl, prep,
new AstVarRef(fl, varp, false)))
: static_cast<AstNode*>
(new AstAssign (fl, prep,
new AstVarRef(fl, varp, false)))),
NULL);
if (debug()>=9) newp->dumpTree(cout," _new: ");
abovep->addNextStmt(newp,abovep);
prep->user2p(newp); // Save so we may LogAnd it next time
}
}
示例6: replaceSelPlusMinus
void replaceSelPlusMinus(AstNodePreSel* nodep) {
// Select of a range specified with +: or -:, i.e. "array[2+:3], [2-:3]"
// This select style has a lsb and width
UINFO(6,"SELPLUS/MINUS "<<nodep<<endl);
// Below 2 lines may change nodep->widthp()
if (debug()>=9) nodep->dumpTree(cout,"--SELPM0: ");
V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node
checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant");
if (debug()>=9) nodep->dumpTree(cout,"--SELPM3: ");
// Now replace it with an AstSel
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* widthp = nodep->thsp()->unlinkFrBack();
int width = widthp->castConst()->toSInt();
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<<widthp->prettyName());
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
FromData fromdata = fromDataForArray(nodep, fromp, width!=1);
AstNodeDType* ddtypep = fromdata.m_dtypep;
VNumRange fromRange = fromdata.m_fromRange;
if (ddtypep->castBasicDType()
|| ddtypep->castPackArrayDType()
|| (ddtypep->castNodeClassDType()
&& ddtypep->castNodeClassDType()->packedUnsup())) {
int elwidth = 1;
AstNode* newwidthp = widthp;
if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
elwidth = adtypep->width() / fromRange.elements();
newwidthp = new AstConst (nodep->fileline(),AstConst::Unsized32(), width * elwidth);
}
AstNode* newlsbp = NULL;
if (nodep->castSelPlus()) {
if (fromRange.littleEndian()) {
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
newlsbp = newSubNeg((fromRange.hi()-width+1), rhsp);
} else {
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
newlsbp = newSubNeg(rhsp, fromRange.lo());
}
} else if (nodep->castSelMinus()) {
if (fromRange.littleEndian()) {
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
newlsbp = newSubNeg(fromRange.hi(), rhsp);
} else {
// SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#)
newlsbp = newSubNeg(rhsp, fromRange.lo()+(width-1));
}
} else {
nodep->v3fatalSrc("Bad Case");
}
if (elwidth != 1) newlsbp = new AstMul (nodep->fileline(), newlsbp,
new AstConst (nodep->fileline(), elwidth));
AstSel* newp = new AstSel (nodep->fileline(),
fromp, newlsbp, newwidthp);
newp->declRange(fromRange);
newp->declElWidth(elwidth);
UINFO(6," new "<<newp<<endl);
if (debug()>=9) newp->dumpTree(cout,"--SELNEW: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else { // NULL=bad extract, or unknown node type
nodep->v3error("Illegal +: or -: select; type already selected, or bad dimension: type is "
<<fromdata.m_errp->prettyTypeName());
// How to recover? We'll strip a dimension.
nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep);
}
// delete whataver we didn't use in reconstruction
if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); }
if (!rhsp->backp()) { pushDeletep(rhsp); VL_DANGLING(rhsp); }
if (!widthp->backp()) { pushDeletep(widthp); VL_DANGLING(widthp); }
}
示例7: visit
virtual void visit(AstSelExtract* nodep, AstNUser*) {
// Select of a range specified part of an array, i.e. "array[2:3]"
// SELEXTRACT(from,msb,lsb) -> SEL(from, lsb, 1+msb-lsb)
// This select style has a (msb or lsb) and width
UINFO(6,"SELEXTRACT "<<nodep<<endl);
//if (debug()>=9) nodep->dumpTree(cout,"--SELEX0: ");
// Below 2 lines may change nodep->widthp()
V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node
V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node
//if (debug()>=9) nodep->dumpTree(cout,"--SELEX3: ");
checkConstantOrReplace(nodep->lsbp(), "First value of [a:b] isn't a constant, maybe you want +: or -:");
checkConstantOrReplace(nodep->msbp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:");
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
AstNode* lsbp = nodep->thsp()->unlinkFrBack();
vlsint32_t msb = msbp->castConst()->toSInt();
vlsint32_t lsb = lsbp->castConst()->toSInt();
FromData fromdata = fromDataForArray(nodep, fromp, false);
AstNodeDType* ddtypep = fromdata.m_dtypep;
VNumRange fromRange = fromdata.m_fromRange;
if (ddtypep->castUnpackArrayDType()) {
// Slice extraction
if (fromRange.elements() == (msb-lsb+1)
&& fromRange.lo() == lsb) { // Extracting whole of original array
nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep);
} else {
// TODO when unpacked arrays fully supported probably need new data type here
AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp);
newp->start(lsb);
newp->length((msb - lsb) + 1);
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
// SELEXTRACT(array, msb, lsb) -> SEL(array, lsb*width-of-subindex, width-of-subindex*(msb-lsb))
if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0)
adtypep->v3fatalSrc("Array extraction with width miscomputed "
<<adtypep->width()<<"/"<<fromRange.elements());
int elwidth = adtypep->width() / fromRange.elements();
AstSel* newp = new AstSel (nodep->fileline(),
fromp,
new AstConst(nodep->fileline(),AstConst::Unsized32(),lsb*elwidth),
new AstConst(nodep->fileline(),AstConst::Unsized32(),(msb-lsb+1)*elwidth));
newp->declRange(fromRange);
newp->declElWidth(elwidth);
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
//if (debug()>=9) newp->dumpTree(cout,"--EXTBTn: ");
if (newp->widthMin()!=(int)newp->widthConst()) nodep->v3fatalSrc("Width mismatch");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castBasicDType()) {
if (fromRange.littleEndian()) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
}
if (lsb > msb) {
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
int x = msb; msb = lsb; lsb = x;
}
AstNode* widthp = new AstConst (msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user
msb +1-lsb);
AstSel* newp = new AstSel (nodep->fileline(),
fromp,
newSubLsbOf(lsbp, fromRange),
widthp);
newp->declRange(fromRange);
UINFO(6," new "<<newp<<endl);
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (ddtypep->castNodeClassDType()) {
// Classes aren't little endian
if (lsb > msb) {
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
int x = msb; msb = lsb; lsb = x;
}
AstNode* widthp = new AstConst (msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user
msb +1-lsb);
AstSel* newp = new AstSel (nodep->fileline(),
fromp,
newSubLsbOf(lsbp, fromRange),
widthp);
newp->declRange(fromRange);
UINFO(6," new "<<newp<<endl);
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else { // NULL=bad extract, or unknown node type
nodep->v3error("Illegal range select; type already selected, or bad dimension: type is "
<<fromdata.m_errp->prettyName());
UINFO(1," Related ddtype: "<<ddtypep<<endl);
// How to recover? We'll strip a dimension.
nodep->replaceWith(fromp); pushDeletep(nodep); VL_DANGLING(nodep);
}
// delete whataver we didn't use in reconstruction
if (!fromp->backp()) { pushDeletep(fromp); VL_DANGLING(fromp); }
if (!msbp->backp()) { pushDeletep(msbp); VL_DANGLING(msbp); }
if (!lsbp->backp()) { pushDeletep(lsbp); VL_DANGLING(lsbp); }
}