本文整理汇总了C++中AstNode::unlinkFrBack方法的典型用法代码示例。如果您正苦于以下问题:C++ AstNode::unlinkFrBack方法的具体用法?C++ AstNode::unlinkFrBack怎么用?C++ AstNode::unlinkFrBack使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AstNode
的用法示例。
在下文中一共展示了AstNode::unlinkFrBack方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: createDeepTemp
void createDeepTemp(AstNode* nodep) {
UINFO(6," Deep "<<nodep<<endl);
//if (debug()>=9) nodep->dumpTree(cout,"deep:");
string newvarname = ((string)"__Vdeeptemp"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
// Width, not widthMin, as we may be in middle of BITSEL expression which
// though it's one bit wide, needs the mask in the upper bits.
// (Someday we'll have a valid bitmask instead of widths....)
// See t_func_crc for an example test that requires this
VFlagLogicPacked(), nodep->width());
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
m_funcp->addInitsp(varp);
// Replace node tree with reference to var
AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
nodep->replaceWith(newp);
// Put assignment before the referencing statement
AstAssign* assp = new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), varp, true),
nodep);
AstNRelinker linker2;
m_stmtp->unlinkFrBack(&linker2);
assp->addNext(m_stmtp);
linker2.relink(assp);
}
示例2: RemovePlaceholdersVisitor
explicit RemovePlaceholdersVisitor(AstNode* nodep) {
iterate(nodep);
for (NodeSet::const_iterator it = m_removeSet.begin();
it != m_removeSet.end(); ++it) {
AstNode* np = *it;
np->unlinkFrBack(); // Without next
np->deleteTree(); VL_DANGLING(np);
}
}
示例3: visit
// VISITORS
virtual void visit(AstVarScope* nodep, AstNUser*) {
if (AstNodeAssign* assp = nodep->valuep()->castNodeAssign()) {
UINFO(5," Removeassign "<<assp<<endl);
AstNode* valuep = assp->rhsp();
valuep->unlinkFrBack();
assp->replaceWith(valuep);
assp->deleteTree(); VL_DANGLING(assp);
}
}
示例4: replaceDisplay
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->displayType(AstDisplayType::DT_WRITE);
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->fmtp()->exprsp(timesp);
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
}
}
示例5: findAddLabel
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);
if (nodep->castJumpLabel()) return nodep->castJumpLabel(); // Done
AstNode* underp = NULL;
bool under_and_next = true;
if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp();
else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp();
else if (nodep->castWhile()) {
if (endOfIter) {
// Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip
underp = nodep->castWhile()->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.
while (underp && underp->castVar()) underp = underp->nextp();
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
if (!underp) {
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
return NULL;
} else if (underp->castJumpLabel()) {
return underp->castJumpLabel();
} 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);
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 (varp->castVar()) {
labelp->addPrev(varp->unlinkFrBack());
}
}
return labelp;
}
}
示例6: insertBeforeStmt
void insertBeforeStmt(AstNode* newp) {
// Insert newp before m_stmtp
if (m_inWhilep) {
// Statements that are needed for the 'condition' in a while actually have to
// be put before & after the loop, since we can't do any statements in a while's (cond).
m_inWhilep->addPrecondsp(newp);
} else if (m_inTracep) {
m_inTracep->addPrecondsp(newp);
} else if (m_stmtp) {
AstNRelinker linker;
m_stmtp->unlinkFrBack(&linker);
newp->addNext(m_stmtp);
linker.relink(newp);
} else {
newp->v3fatalSrc("No statement insertion point.");
}
}
示例7: consumedMove
void GateVisitor::consumedMove() {
// Remove unused logic (logic that doesn't hit a combo block or a display statement)
// We need the "usually" block logic to do a better job at this
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(vertexp)) {
if (!vvertexp->consumed() && !vvertexp->user()) {
UINFO(8, "Unconsumed "<<vvertexp->varScp()<<endl);
}
}
if (GateLogicVertex* lvertexp = dynamic_cast<GateLogicVertex*>(vertexp)) {
AstNode* nodep = lvertexp->nodep();
AstActive* oldactp = lvertexp->activep(); // NULL under cfunc
if (!lvertexp->consumed() && oldactp) {
// Eventually: Move the statement to a new active block with "tracing-on" sensitivity
UINFO(8," Remove unconsumed "<<nodep<<endl);
nodep->unlinkFrBack();
pushDeletep(nodep); VL_DANGLING(nodep);
}
}
}
}
示例8: reorderBlock
void reorderBlock(AstNode* nodep) {
// Reorder statements in the completed graph
// Map the rank numbers into nodes they associate with
typedef std::multimap<uint32_t,AstNode*> RankNodeMap;
RankNodeMap rankMap;
int currOrder = 0; // Existing sequence number of assignment
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
rankMap.insert(make_pair(vvertexp->rank(), nextp));
nextp->user4(++currOrder); // Record current ordering
}
// Is the current ordering OK?
bool leaveAlone=true;
int newOrder = 0; // New sequence number of assignment
for (RankNodeMap::const_iterator it = rankMap.begin();
it != rankMap.end(); ++it) {
AstNode* nextp = it->second;
if (++newOrder != nextp->user4()) leaveAlone=false;
}
if (leaveAlone) {
UINFO(6," No changes\n");
} else {
AstNRelinker replaceHandle; // Where to add the list
AstNode* newListp = NULL;
for (RankNodeMap::const_iterator it = rankMap.begin(); it != rankMap.end(); ++it) {
AstNode* nextp = it->second;
UINFO(6, " New order: "<<nextp<<endl);
if (nextp == nodep) nodep->unlinkFrBack(&replaceHandle);
else nextp->unlinkFrBack();
if (newListp) newListp = newListp->addNext(nextp);
else newListp = nextp;
}
replaceHandle.relink(newListp);
} // leaveAlone
}
示例9: optimizeSignals
//.........这里部分代码省略.........
GateLogicVertex* logicVertexp = dynamic_cast<GateLogicVertex*>
(vvertexp->inBeginp()->fromp());
UINFO(8, " From "<<logicVertexp->name()<<endl);
AstNode* logicp = logicVertexp->nodep();
if (logicVertexp->reducible()) {
// Can we eliminate?
GateOkVisitor okVisitor(logicp, vvertexp->isClock(), false);
bool multiInputs = okVisitor.rhsVarRefs().size() > 1;
// Was it ok?
bool doit = okVisitor.isSimple();
if (doit && multiInputs) {
if (!allowMultiIn) doit = false;
// Doit if one input, or not used, or used only once, ignoring traces
int n=0;
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
if (!consumeVertexp->slow()) { // Not tracing or other slow path junk
if (edgep->top()->outBeginp()) { // Destination is itself used
n += edgep->weight();
}
}
if (n>1) {
doit = false;
break;
}
}
}
// Process it
if (!doit) {
if (allowMultiIn && (debug()>=9)) {
UINFO(9, "Not ok simp"<<okVisitor.isSimple()<<" mi"<<multiInputs
<<" ob"<<vvertexp->outBeginp()<<" on"<<(vvertexp->outBeginp()?vvertexp->outBeginp()->outNextp():0)
<<" "<<vvertexp->name()
<<endl);
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
UINFO(9, " edge "<<edgep<<" to: "<<consumeVertexp->nodep()<<endl);
}
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->fromp());
UINFO(9, " edge "<<edgep<<" from: "<<consumeVertexp->nodep()<<endl);
}
}
}
else {
AstNode* substp = okVisitor.substTree();
if (debug()>=5) logicp->dumpTree(cout,"\telimVar: ");
if (debug()>=5) substp->dumpTree(cout,"\t subst: ");
++m_statSigs;
bool removedAllUsages = true;
for (V3GraphEdge* edgep = vvertexp->outBeginp();
edgep; ) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
AstNode* consumerp = consumeVertexp->nodep();
if (!elimLogicOkOutputs(consumeVertexp, okVisitor/*ref*/)) {
// Cannot optimize this replacement
removedAllUsages = false;
edgep = edgep->outNextp();
} else {
optimizeElimVar(vvertexp->varScp(), substp, consumerp);
// If the new replacement referred to a signal,
// Correct the graph to point to this new generating variable
const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs();
for (GateVarRefList::const_iterator it = rhsVarRefs.begin();
it != rhsVarRefs.end(); ++it) {
AstVarScope* newvarscp = (*it)->varScopep();
UINFO(9," Point-to-new vertex "<<newvarscp<<endl);
GateVarVertex* varvertexp = makeVarVertex(newvarscp);
new V3GraphEdge(&m_graph, varvertexp, consumeVertexp, 1);
// Propagate clock attribute onto generating node
varvertexp->propagateAttrClocksFrom(vvertexp);
}
// Remove the edge
edgep->unlinkDelete(); VL_DANGLING(edgep);
++m_statRefs;
edgep = vvertexp->outBeginp();
}
}
if (removedAllUsages) {
// Remove input links
while (V3GraphEdge* edgep = vvertexp->inBeginp()) {
edgep->unlinkDelete(); VL_DANGLING(edgep);
}
// Clone tree so we remember it for tracing, and keep the pointer
// to the "ALWAYS" part of the tree as part of this statement
// That way if a later signal optimization that retained a pointer to the always
// can optimize it further
logicp->unlinkFrBack();
vvertexp->varScp()->valuep(logicp);
logicp = NULL;
// Mark the vertex so we don't mark it as being unconsumed in the next step
vvertexp->user(true);
logicVertexp->user(true);
}
}
}
}
}
}
}
示例10: replaceCaseComplicated
void replaceCaseComplicated(AstCase* nodep) {
// CASEx(cexpr,ITEM(icond1,istmts1),ITEM(icond2,istmts2),ITEM(default,istmts3))
// -> IF((cexpr==icond1),istmts1,
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
// ,istmts2, istmts3
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
// We'll do this in two stages. First stage, convert the conditions to
// the appropriate IF AND terms.
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
bool hadDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (!itemp->condsp()) {
// Default clause. Just make true, we'll optimize it away later
itemp->condsp(new AstConst(itemp->fileline(), AstConst::LogicTrue()));
hadDefault = true;
} else {
// Expressioned clause
AstNode* icondNextp = NULL;
AstNode* ifexprp = NULL; // If expression to test
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) {
icondNextp = icondp->nextp();
icondp->unlinkFrBack();
AstNode* condp = NULL; // Default is to use and1p/and2p
AstConst* iconstp = icondp->castConst();
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
// Similar logic in V3Width::visit(AstInside)
AstNode* ap = AstGte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->lhsp()->unlinkFrBack());
AstNode* bp = AstLte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->rhsp()->unlinkFrBack());
condp = new AstAnd(itemp->fileline(), ap, bp);
} else if (iconstp && iconstp->num().isFourState()
&& (nodep->casex() || nodep->casez() || nodep->caseInside())) {
V3Number nummask (itemp->fileline(), iconstp->width());
nummask.opBitsNonX(iconstp->num());
V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num());
AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
new AstConst(itemp->fileline(), nummask));
AstNode* and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
AstNode* and1p = cexprp->cloneTree(false);
AstNode* and2p = icondp;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
}
if (!ifexprp) {
ifexprp = condp;
} else {
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
}
}
// Replace expression in tree
itemp->condsp(ifexprp);
}
}
cexprp->deleteTree(); cexprp=NULL;
if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later.
nodep->addItemsp(new AstCaseItem(nodep->fileline(),
new AstConst(nodep->fileline(), AstConst::LogicTrue()),
NULL));
}
if (debug()>=9) nodep->dumpTree(cout," _comp_COND: ");
// Now build the IF statement tree
// The tree can be quite huge. Pull ever group of 8 out, and make a OR tree.
// This reduces the depth for the bottom elements, at the cost of some of the top elements.
// If we ever have profiling data, we should pull out the most common item from here and
// instead make it the first IF branch.
int depth = 0;
AstNode* grouprootp = NULL;
AstIf* groupnextp = NULL;
AstIf* itemnextp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext();
// Expressioned clause
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
{ // Prepare for next group
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
if (depth == 1) { // First group or starting new group
itemnextp = NULL;
AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL);
if (groupnextp) groupnextp->addElsesp(newp);
else grouprootp = newp;
groupnextp = newp;
//.........这里部分代码省略.........
示例11: visit
virtual void visit(AstAssignW* nodep, AstNUser*) {
// Note: this detects and expands tristates of the forms:
// assign x = (OE) ? y : 'hZ;
// assign x = (OE) ? 'hz : y;
// see if this a COND and separate out the __en logic from the output logic if it is
if (AstCond* condp = nodep->rhsp()->castCond()) {
//if (debug()>=9) nodep->dumpTree(cout,"- cond-in: ");
AstNode* oep = condp->condp();
AstNode* expr1p = condp->expr1p();
AstNode* expr2p = condp->expr2p();
AstNode* enrhsp;
AstNode* outrhsp;
if (expr1p->castConst() && expr1p->castConst()->num().isAllZ()) {
enrhsp = new AstNot(oep->fileline(), oep->unlinkFrBack());
outrhsp = expr2p->unlinkFrBack();
} else if (expr2p->castConst() && expr2p->castConst()->num().isAllZ()){
enrhsp = oep->unlinkFrBack();
outrhsp = expr1p->unlinkFrBack();
} else {
// not a tristate or not in a form we recgonize, so exit and move on.
return;
}
AstNode* outp = nodep->lhsp()->unlinkFrBack();;
AstVarRef* outrefp = NULL;
if (outp->castVarRef()) {
outrefp = outp->castVarRef();
} else if (outp->castSel()) {
outrefp = outp->castSel()->fromp()->castVarRef();
} else {
nodep->v3error("Can't find LHS varref");
}
createEnableVar(outp, outrefp, enrhsp, outrhsp->width());
// replace the old assign logic with the new one
AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,outrhsp);
//if (debug()>=9) newassp->dumpTreeAndNext(cout,"- cond-out: ");
nodep->replaceWith(newassp);
nodep->deleteTree(); nodep=NULL;
newassp->iterateChildren(*this);
}
// How about a tri gate?
else if (AstBufIf1* bufp = nodep->rhsp()->castBufIf1()) {
//if (debug()>=9) nodep->dumpTree(cout,"- tri-in : ");
AstNode* enrhsp = bufp->lhsp()->unlinkFrBack();
AstNode* outrhsp = bufp->rhsp()->unlinkFrBack();
AstNode* outp = nodep->lhsp()->unlinkFrBack();;
AstVarRef* outrefp = NULL;
if (outp->castVarRef()) {
outrefp = outp->castVarRef();
} else if (outp->castSel()) {
outrefp = outp->castSel()->fromp()->castVarRef();
} else {
nodep->v3error("Can't find LHS varref");
}
createEnableVar(outp, outrefp, enrhsp, outrhsp->width());
// replace the old assign logic with the new one
AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,outrhsp);
//if (debug()>=9) newassp->dumpTreeAndNext(cout,"- tri-out: ");
nodep->replaceWith(newassp);
nodep->deleteTree(); nodep=NULL;
newassp->iterateChildren(*this);
}
else {
nodep->iterateChildren(*this);
}
}
示例12: reorderBlock
void reorderBlock(AstNode* nodep) {
// Reorder statements in the completed graph
AstAlways* splitAlwaysp = nodep->backp()->castAlways();
// Map the rank numbers into nodes they associate with
typedef multimap<uint32_t,AstNode*> RankNodeMap;
typedef map<uint32_t,RankNodeMap> ColorRankMap;
ColorRankMap colorRankMap;
uint32_t firstColor = 0; bool multiColors = false;
int currOrder = 0; // Existing sequence number of assignment
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
if (!splitAlwaysp) vvertexp->splitColor(1); // All blocks remain as-is
RankNodeMap& rankMap = colorRankMap[vvertexp->splitColor()];
rankMap.insert(make_pair(vvertexp->rank(), nextp));
if (firstColor && firstColor != vvertexp->splitColor()) multiColors = true;
firstColor = vvertexp->splitColor();
nextp->user4(++currOrder); // Record current ordering
}
// If there was only one color, we don't need multiple always blocks
if (!multiColors) splitAlwaysp = NULL;
// Is the current ordering OK?
bool leaveAlone=true;
if (splitAlwaysp) leaveAlone=false;
int newOrder = 0; // New sequence number of assignment
for (ColorRankMap::iterator colorIt = colorRankMap.begin(); colorIt != colorRankMap.end(); ++colorIt) {
RankNodeMap& rankMap = colorIt->second;
for (RankNodeMap::iterator it = rankMap.begin(); it != rankMap.end(); ++it) {
AstNode* nextp = it->second;
if (++newOrder != nextp->user4()) leaveAlone=false;
}
}
if (leaveAlone) {
UINFO(6," No changes\n");
} else {
AstNRelinker replaceHandle; // Where to add the list
AstNode* addAfterp = splitAlwaysp;
for (ColorRankMap::iterator colorIt = colorRankMap.begin(); colorIt != colorRankMap.end(); ++colorIt) {
uint32_t color = colorIt->first;
RankNodeMap& rankMap = colorIt->second;
AstNode* newListp = NULL;
for (RankNodeMap::iterator it = rankMap.begin(); it != rankMap.end(); ++it) {
AstNode* nextp = it->second;
UINFO(6, " Color="<<color<<" New order: "<<nextp<<endl);
if (nextp == nodep && !splitAlwaysp) nodep->unlinkFrBack(&replaceHandle);
else nextp->unlinkFrBack();
newListp = newListp->addNext(nextp);
}
if (splitAlwaysp) {
++m_statSplits;
AstAlways* alwaysp = new AstAlways(newListp->fileline(), VAlwaysKwd::ALWAYS, NULL, NULL);
addAfterp->addNextHere(alwaysp); addAfterp=alwaysp;
alwaysp->addStmtp(newListp);
} else {
// Just reordering
replaceHandle.relink(newListp);
}
}
if (splitAlwaysp) {
pushDeletep(splitAlwaysp->unlinkFrBack());
}
} // leaveAlone
}