virtual void visit(AstNode* nodep) { if (nodep->user3p()) { SplitLogicVertex* vertexp = (SplitLogicVertex*)(nodep->user3p()); uint32_t color = vertexp->color(); m_colors.insert(color); UINFO(8, " SVL " << vertexp << " has color " << color << "\n"); // Record that all containing ifs have this color. for (IfStack::const_iterator it = m_ifStack.begin(); it != m_ifStack.end(); ++it) { m_ifColors[*it].insert(color); } } iterateChildren(nodep); }
virtual void visit(AstNode* nodep) { // Anything that's not an if/else we assume is a leaf // (that is, something we won't split.) Don't visit further // into the leaf. // // A leaf might contain another if, for example a WHILE loop // could contain an if. We can't split WHILE loops, so we // won't split its nested if either. Just treat it as part // of the leaf; do not visit further; do not reach visit(AstNodeIf*) // for such an embedded if. // Each leaf must have a user3p if (!nodep->user3p()) nodep->v3fatalSrc("null user3p in V3Split leaf"); // Clone the leaf into its new always block SplitLogicVertex* vxp = (SplitLogicVertex*)(nodep->user3p()); uint32_t color = vxp->color(); AstNode* clonedp = nodep->cloneTree(false); m_addAfter[color]->addNextHere(clonedp); m_addAfter[color] = clonedp; }
void cleanupBlockGraph(AstNode* nodep) { // Transform the graph into what we need UINFO(5, "ReorderBlock "<<nodep<<endl); m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); if (debug()>=9) { m_graph.dumpDotFilePrefixed("reorderg_nodup", false); //m_graph.dump(); cout<<endl; } // Mark all the logic for this step // Vertex::m_user begin: true indicates logic for this step m_graph.userClearVertices(); for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); vvertexp->user(true); } // If a var vertex has only inputs, it's a input-only node, // and can be ignored for coloring **this block only** SplitEdge::incrementStep(); pruneDepsOnInputs(); // For reordering this single block only, mark all logic // vertexes not involved with this step as unimportant for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (SplitLogicVertex* vvertexp = dynamic_cast<SplitLogicVertex*>(vertexp)) { if (!vvertexp->user()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep); oedgep->setIgnoreThisStep(); } for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep); oedgep->setIgnoreThisStep(); } } } } // Weak coloring to determine what needs to remain in order // This follows all step-relevant edges excluding PostEdges, which are done later m_graph.weaklyConnected(&SplitEdge::followScoreboard); // Add hard orderings between all nodes of same color, in the order they appeared vl_unordered_map<uint32_t, SplitLogicVertex*> lastOfColor; for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); uint32_t color = vvertexp->color(); if (!color) nextp->v3fatalSrc("No node color assigned"); if (lastOfColor[color]) { new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp); } lastOfColor[color] = vvertexp; } // And a real ordering to get the statements into something reasonable // We don't care if there's cutable violations here... // Non-cutable violations should be impossible; as those edges are program-order if (debug()>=9) m_graph.dumpDotFilePrefixed((string)"splitg_preo", false); m_graph.acyclic(&SplitEdge::followCyclic); m_graph.rank(&SplitEdge::followCyclic); // Or order(), but that's more expensive if (debug()>=9) m_graph.dumpDotFilePrefixed((string)"splitg_opt", false); }