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 }
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("splitg_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(); uint32_t numVertexes = 1; // As colors start at 1, not 0 for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { numVertexes++; if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep); oedgep->setIgnoreThisStep(); } } // Mark all logic vertexes not involved with this step as unimportant 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 vector<SplitLogicVertex*> lastOfColor; lastOfColor.resize(numVertexes); for (uint32_t i=0; i<numVertexes; i++) lastOfColor[i] = NULL; for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); vvertexp->splitColor(vvertexp->color()); uint32_t color = vvertexp->splitColor(); if (color >= numVertexes) nextp->v3fatalSrc("More colors than vertexes!\n"); if (!color) nextp->v3fatalSrc("No node color assigned\n"); 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); }