Internals: Add more const. No functional change.

This commit is contained in:
Wilson Snyder 2021-11-03 17:49:19 -04:00
parent 758264dc77
commit c26ce25cea
3 changed files with 131 additions and 126 deletions

View File

@ -111,7 +111,7 @@ public:
} else {
uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->inBeginp(); depp; depp = depp->inNextp()) {
depCount++;
++depCount;
}
VxHolder newVx(vxp, pos++, depCount);
m_waitingVertices.emplace(vxp, newVx);
@ -123,7 +123,7 @@ public:
} else {
uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->outBeginp(); depp; depp = depp->outNextp()) {
depCount++;
++depCount;
}
VxHolder newVx(vxp, pos++, depCount);
m_waitingVertices.emplace(vxp, newVx);
@ -194,7 +194,7 @@ private:
void unblockDeps(const V3GraphVertex* vertexp) {
if (m_way == GraphWay::FORWARD) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
V3GraphVertex* toVertexp = edgep->top();
V3GraphVertex* const toVertexp = edgep->top();
const auto it = m_waitingVertices.find(toVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
@ -206,7 +206,7 @@ private:
}
} else {
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
V3GraphVertex* fromVertexp = edgep->fromp();
V3GraphVertex* const fromVertexp = edgep->fromp();
const auto it = m_waitingVertices.find(fromVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,

View File

@ -187,13 +187,13 @@ public:
// of each, and add each to m_pending if its overall CP has grown.
for (V3GraphEdge* edgep = vxp->beginp(m_way); edgep; edgep = edgep->nextp(m_way)) {
if (!m_edgeFuncp(edgep)) continue;
V3GraphVertex* relativep = edgep->furtherp(m_way);
V3GraphVertex* const relativep = edgep->furtherp(m_way);
m_accessp->notifyEdgeCp(relativep, m_way, vxp, newInclusiveCp);
if (m_accessp->critPathCost(relativep, m_way) < newInclusiveCp) {
// relativep's critPathCost() is out of step with its
// longest !wayward edge. Schedule that to be resolved.
uint32_t newPendingVal
const uint32_t newPendingVal
= newInclusiveCp - m_accessp->critPathCost(relativep, m_way);
if (m_pending.has(relativep)) {
if (newPendingVal > m_pending.at(relativep)) {
@ -225,14 +225,14 @@ public:
// This generalizes to multiple seed nodes also.
while (!m_pending.empty()) {
const auto it = m_pending.rbegin();
V3GraphVertex* updateMep = (*it).key();
uint32_t cpGrowBy = (*it).value();
V3GraphVertex* const updateMep = (*it).key();
const uint32_t cpGrowBy = (*it).value();
m_pending.erase(it);
// For *updateMep, whose critPathCost was out-of-date with respect
// to its edges, update the critPathCost.
uint32_t startCp = m_accessp->critPathCost(updateMep, m_way);
uint32_t newCp = startCp + cpGrowBy;
const uint32_t startCp = m_accessp->critPathCost(updateMep, m_way);
const uint32_t newCp = startCp + cpGrowBy;
if (m_slowAsserts) m_accessp->checkNewCpVersusEdges(updateMep, m_way, newCp);
m_accessp->setCritPathCost(updateMep, m_way, newCp);
@ -263,7 +263,7 @@ protected:
friend class PartPropagateCp<PartPropagateCpSelfTest>;
void notifyEdgeCp(V3GraphVertex* vxp, GraphWay way, V3GraphVertex* throughp,
uint32_t cp) const {
uint32_t throughCost = critPathCost(throughp, way);
const uint32_t throughCost = critPathCost(throughp, way);
UASSERT_SELFTEST(uint32_t, cp, (1 + throughCost));
}
@ -293,10 +293,10 @@ private:
// redundant to test.
GraphStreamUnordered order(&m_graph);
while (const V3GraphVertex* cvxp = order.nextp()) {
V3GraphVertex* vxp = const_cast<V3GraphVertex*>(cvxp);
V3GraphVertex* const vxp = const_cast<V3GraphVertex*>(cvxp);
uint32_t cpCost = 0;
for (V3GraphEdge* edgep = vxp->inBeginp(); edgep; edgep = edgep->inNextp()) {
V3GraphVertex* parentp = edgep->fromp();
V3GraphVertex* const parentp = edgep->fromp();
cpCost = std::max(cpCost, critPathCost(parentp, GraphWay::FORWARD) + 1);
}
if (checkOnly) {
@ -315,8 +315,8 @@ private:
// Create 250 edges at random. Edges must go from
// lower-to-higher index vertices, so we get a DAG.
for (unsigned i = 0; i < 250; ++i) {
unsigned idx1 = V3Os::rand64(rngState) % 50;
unsigned idx2 = V3Os::rand64(rngState) % 50;
const unsigned idx1 = V3Os::rand64(rngState) % 50;
const unsigned idx2 = V3Os::rand64(rngState) % 50;
if (idx1 > idx2) {
new V3GraphEdge(&m_graph, m_vx[idx2], m_vx[idx1], 1);
} else if (idx2 > idx1) {
@ -375,17 +375,17 @@ public:
~CpCostAccessor() = default;
// Return cost of this node
uint32_t cost(const V3GraphVertex* vxp) const {
const LogicMTask* mtaskp = dynamic_cast<const LogicMTask*>(vxp);
const LogicMTask* const mtaskp = dynamic_cast<const LogicMTask*>(vxp);
return mtaskp->stepCost();
}
// Return stored CP to this node
uint32_t critPathCost(const V3GraphVertex* vxp, GraphWay way) const {
const LogicMTask* mtaskp = dynamic_cast<const LogicMTask*>(vxp);
const LogicMTask* const mtaskp = dynamic_cast<const LogicMTask*>(vxp);
return mtaskp->critPathCost(way);
}
// Store a new CP to this node
void setCritPathCost(V3GraphVertex* vxp, GraphWay way, uint32_t cost) const {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
mtaskp->setCritPathCost(way, cost);
}
// Notify vxp that the wayward CP at the throughp-->vxp edge
@ -393,19 +393,19 @@ public:
// This is our cue to update vxp's m_edges[!way][throughp].
void notifyEdgeCp(V3GraphVertex* vxp, GraphWay way, V3GraphVertex* throuvhVxp,
uint32_t cp) const {
LogicMTask* updateVxp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* lthrouvhVxp = dynamic_cast<LogicMTask*>(throuvhVxp);
LogicMTask* const updateVxp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const lthrouvhVxp = dynamic_cast<LogicMTask*>(throuvhVxp);
EdgeSet& edges = updateVxp->m_edges[way.invert()];
uint32_t edgeCp = edges.at(lthrouvhVxp);
const uint32_t edgeCp = edges.at(lthrouvhVxp);
if (cp > edgeCp) edges.set(lthrouvhVxp, cp);
}
// Check that CP matches that of the longest edge wayward of vxp.
void checkNewCpVersusEdges(V3GraphVertex* vxp, GraphWay way, uint32_t cp) const {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
EdgeSet& edges = mtaskp->m_edges[way.invert()];
// This is mtaskp's relative with longest !wayward inclusive CP:
const auto edgeIt = edges.rbegin();
uint32_t edgeCp = (*edgeIt).value();
const uint32_t edgeCp = (*edgeIt).value();
UASSERT_OBJ(edgeCp == cp, vxp, "CP doesn't match longest wayward edge");
}
@ -455,7 +455,7 @@ public:
for (unsigned int& i : m_critPathCost) i = 0;
if (mtmvVxp) { // Else null for test
m_vertices.push_back(mtmvVxp);
if (OrderLogicVertex* olvp = mtmvVxp->logicp()) {
if (OrderLogicVertex* const olvp = mtmvVxp->logicp()) {
m_cost += V3InstrCount::count(olvp->nodep(), true);
}
}
@ -502,7 +502,7 @@ public:
logcost = ceil(logcost);
logcost = logcost / 20.0;
uint32_t stepCost = static_cast<uint32_t>(exp(logcost));
const uint32_t stepCost = static_cast<uint32_t>(exp(logcost));
UASSERT_STATIC(stepCost >= cost, "stepped cost error exceeded");
UASSERT_STATIC(stepCost <= ((cost * 11 / 10)), "stepped cost error exceeded");
return stepCost;
@ -528,8 +528,8 @@ public:
void checkRelativesCp(GraphWay way) const {
const EdgeSet& edges = m_edges[way];
for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) {
LogicMTask* relativep = (*it).key();
uint32_t cachedCp = (*it).value();
LogicMTask* const relativep = (*it).key();
const uint32_t cachedCp = (*it).value();
partCheckCachedScoreVsActual(cachedCp, relativep->critPathCost(way.invert())
+ relativep->stepCost());
}
@ -603,7 +603,7 @@ private:
for (const V3GraphEdge* followp = fromp->outBeginp(); followp;
followp = followp->outNextp()) {
if (followp == excludedEdgep) continue;
LogicMTask* nextp = dynamic_cast<LogicMTask*>(followp->top());
LogicMTask* const nextp = dynamic_cast<LogicMTask*>(followp->top());
if (pathExistsFromInternal(nextp, top, nullptr, generation)) return true;
}
return false;
@ -634,7 +634,7 @@ public:
const LogicMTask* startp = nullptr;
for (const V3GraphVertex* vxp = graphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
const LogicMTask* mtaskp = dynamic_cast<const LogicMTask*>(vxp);
const LogicMTask* const mtaskp = dynamic_cast<const LogicMTask*>(vxp);
if (!startp) {
startp = mtaskp;
continue;
@ -669,7 +669,7 @@ public:
*osp << "begin mtask with cost " << mtaskp->cost() << '\n';
for (VxList::const_iterator lit = mtaskp->vertexListp()->begin();
lit != mtaskp->vertexListp()->end(); ++lit) {
const OrderLogicVertex* logicp = (*lit)->logicp();
const OrderLogicVertex* const logicp = (*lit)->logicp();
if (!logicp) continue;
if (false) {
// Show nodes only
@ -781,7 +781,7 @@ public:
}
static MTaskEdge* cast(V3GraphEdge* edgep) {
if (!edgep) return nullptr;
MTaskEdge* resultp = dynamic_cast<MTaskEdge*>(edgep);
MTaskEdge* const resultp = dynamic_cast<MTaskEdge*>(edgep);
UASSERT(resultp, "Failed to cast in MTaskEdge::cast");
return resultp;
}
@ -789,8 +789,8 @@ public:
// out of the edge-map for each node and reinsert at a new location
// with updated critical path.
void resetCriticalPaths() {
LogicMTask* fromp = fromMTaskp();
LogicMTask* top = toMTaskp();
LogicMTask* const fromp = fromMTaskp();
LogicMTask* const top = toMTaskp();
fromp->removeRelative(GraphWay::FORWARD, top);
top->removeRelative(GraphWay::REVERSE, fromp);
fromp->addRelative(GraphWay::FORWARD, top);
@ -809,8 +809,8 @@ class OrderByPtrId final {
public:
virtual bool operator()(const OrderVarStdVertex* lhsp, const OrderVarStdVertex* rhsp) const {
vluint64_t l_id = m_ids.findId(lhsp);
vluint64_t r_id = m_ids.findId(rhsp);
const vluint64_t l_id = m_ids.findId(lhsp);
const vluint64_t r_id = m_ids.findId(rhsp);
return l_id < r_id;
}
};
@ -905,8 +905,8 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
GraphStreamUnordered order(mtasksp, way);
const GraphWay rev = way.invert();
for (const V3GraphVertex* vertexp; (vertexp = order.nextp());) {
const LogicMTask* mtaskcp = dynamic_cast<const LogicMTask*>(vertexp);
LogicMTask* mtaskp = const_cast<LogicMTask*>(mtaskcp);
const LogicMTask* const mtaskcp = dynamic_cast<const LogicMTask*>(vertexp);
LogicMTask* const mtaskp = const_cast<LogicMTask*>(mtaskcp);
uint32_t cpCost = 0;
std::unordered_set<V3GraphVertex*> relatives;
for (V3GraphEdge* edgep = vertexp->beginp(rev); edgep; edgep = edgep->nextp(rev)) {
@ -917,7 +917,7 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
"Should be no redundant edges in mtasks graph");
relatives.insert(edgep->furtherp(rev));
LogicMTask* relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev));
LogicMTask* const relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev));
cpCost = std::max(cpCost, (relativep->critPathCost(way)
+ static_cast<uint32_t>(relativep->stepCost())));
}
@ -938,7 +938,7 @@ static void partInitCriticalPaths(V3Graph* mtasksp) {
// They would have been all zeroes on initial creation of the MTaskEdges.
for (V3GraphVertex* vxp = mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
MTaskEdge* mtedgep = dynamic_cast<MTaskEdge*>(edgep);
MTaskEdge* const mtedgep = dynamic_cast<MTaskEdge*>(edgep);
mtedgep->resetCriticalPaths();
}
}
@ -950,7 +950,7 @@ static void partCheckCriticalPaths(V3Graph* mtasksp) {
partInitHalfCriticalPaths(GraphWay::FORWARD, mtasksp, true);
partInitHalfCriticalPaths(GraphWay::REVERSE, mtasksp, true);
for (V3GraphVertex* vxp = mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
mtaskp->checkRelativesCp(GraphWay::FORWARD);
mtaskp->checkRelativesCp(GraphWay::REVERSE);
}
@ -958,7 +958,7 @@ static void partCheckCriticalPaths(V3Graph* mtasksp) {
// Advance to nextp(way) and delete edge
static V3GraphEdge* partBlastEdgep(GraphWay way, V3GraphEdge* edgep) {
V3GraphEdge* nextp = edgep->nextp(way);
V3GraphEdge* const nextp = edgep->nextp(way);
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
return nextp;
}
@ -1000,12 +1000,12 @@ static void partMergeEdgesFrom(V3Graph* mtasksp, LogicMTask* recipientp, LogicMT
V3Scoreboard<MergeCandidate, uint32_t>* sbp) {
for (const auto& way : {GraphWay::FORWARD, GraphWay::REVERSE}) {
for (V3GraphEdge* edgep = donorp->beginp(way); edgep; edgep = partBlastEdgep(way, edgep)) {
MTaskEdge* tedgep = MTaskEdge::cast(edgep);
MTaskEdge* const tedgep = MTaskEdge::cast(edgep);
if (sbp && !tedgep->removedFromSb()) sbp->removeElem(tedgep);
// Existing edge; mark it in need of a rescore
if (recipientp->hasRelative(way, tedgep->furtherMTaskp(way))) {
if (sbp) {
MTaskEdge* existMTaskEdgep = MTaskEdge::cast(
MTaskEdge* const existMTaskEdgep = MTaskEdge::cast(
recipientp->findConnectingEdgep(way, tedgep->furtherMTaskp(way)));
UASSERT(existMTaskEdgep, "findConnectingEdge didn't find edge");
if (!existMTaskEdgep->removedFromSb()) {
@ -1104,7 +1104,7 @@ public:
while (true) {
// This is the best edge to merge, with the lowest
// score (shortest local critical path)
MergeCandidate* mergeCanp = const_cast<MergeCandidate*>(m_sb.bestp());
MergeCandidate* const mergeCanp = const_cast<MergeCandidate*>(m_sb.bestp());
if (!mergeCanp) {
// Scoreboard found no eligible merges. Maybe a rescore
// will produce some merge-able pairs?
@ -1119,8 +1119,8 @@ public:
UASSERT(!m_sb.needsRescore(mergeCanp),
"Need-rescore items should not be returned by bestp");
}
uint32_t cachedScore = m_sb.cachedScore(mergeCanp);
uint32_t actualScore = mergeCandidateScore(mergeCanp);
const uint32_t cachedScore = m_sb.cachedScore(mergeCanp);
const uint32_t actualScore = mergeCandidateScore(mergeCanp);
if (actualScore > cachedScore) {
// Cached score is out-of-date.
@ -1232,8 +1232,9 @@ private:
newCp = std::max(otherp->critPathCost(way), mtaskp->critPathCost(way));
}
uint32_t origRelativesCp = mtaskp->critPathCost(way) + mtaskp->stepCost();
uint32_t newRelativesCp = newCp + LogicMTask::stepCost(mtaskp->cost() + otherp->cost());
const uint32_t origRelativesCp = mtaskp->critPathCost(way) + mtaskp->stepCost();
const uint32_t newRelativesCp
= newCp + LogicMTask::stepCost(mtaskp->cost() + otherp->cost());
NewCp result;
result.cp = newCp;
@ -1245,9 +1246,9 @@ private:
void removeSiblingMCsWith(LogicMTask* mtaskp) {
for (SibpSet::iterator it = m_mtask2sibs[mtaskp].begin(); it != m_mtask2sibs[mtaskp].end();
++it) {
const SiblingMC* pairp = *it;
const SiblingMC* const pairp = *it;
if (!pairp->removedFromSb()) m_sb.removeElem(pairp);
LogicMTask* otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp();
LogicMTask* const otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp();
size_t erased = m_mtask2sibs[otherp].erase(pairp);
UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask");
erased = m_pairs.erase(*pairp);
@ -1374,14 +1375,14 @@ private:
siblingPairFromRelatives(GraphWay::FORWARD, recipientp, true);
unsigned edges = 0;
for (V3GraphEdge* edgep = recipientp->outBeginp(); edgep; edgep = edgep->outNextp()) {
LogicMTask* postreqp = dynamic_cast<LogicMTask*>(edgep->top());
LogicMTask* const postreqp = dynamic_cast<LogicMTask*>(edgep->top());
siblingPairFromRelatives(GraphWay::REVERSE, postreqp, false);
edges++;
if (edges > PART_SIBLING_EDGE_LIMIT) break;
}
edges = 0;
for (V3GraphEdge* edgep = recipientp->inBeginp(); edgep; edgep = edgep->inNextp()) {
LogicMTask* prereqp = dynamic_cast<LogicMTask*>(edgep->fromp());
LogicMTask* const prereqp = dynamic_cast<LogicMTask*>(edgep->fromp());
siblingPairFromRelatives(GraphWay::FORWARD, prereqp, false);
edges++;
if (edges > PART_SIBLING_EDGE_LIMIT) break;
@ -1416,11 +1417,11 @@ private:
}
static uint32_t siblingScore(const SiblingMC* sibsp) {
LogicMTask* ap = sibsp->ap();
LogicMTask* bp = sibsp->bp();
uint32_t mergedCpCostFwd
const LogicMTask* const ap = sibsp->ap();
const LogicMTask* const bp = sibsp->bp();
const uint32_t mergedCpCostFwd
= std::max(ap->critPathCost(GraphWay::FORWARD), bp->critPathCost(GraphWay::FORWARD));
uint32_t mergedCpCostRev
const uint32_t mergedCpCostRev
= std::max(ap->critPathCost(GraphWay::REVERSE), bp->critPathCost(GraphWay::REVERSE));
return mergedCpCostRev + mergedCpCostFwd + LogicMTask::stepCost(ap->cost() + bp->cost());
}
@ -1429,12 +1430,14 @@ private:
// Score this edge. Lower is better. The score is the new local CP
// length if we merge these mtasks. ("Local" means the longest
// critical path running through the merged node.)
LogicMTask* top = dynamic_cast<LogicMTask*>(edgep->top());
LogicMTask* fromp = dynamic_cast<LogicMTask*>(edgep->fromp());
uint32_t mergedCpCostFwd = std::max(fromp->critPathCost(GraphWay::FORWARD),
top->critPathCostWithout(GraphWay::FORWARD, edgep));
uint32_t mergedCpCostRev = std::max(fromp->critPathCostWithout(GraphWay::REVERSE, edgep),
top->critPathCost(GraphWay::REVERSE));
LogicMTask* const top = dynamic_cast<LogicMTask*>(edgep->top());
LogicMTask* const fromp = dynamic_cast<LogicMTask*>(edgep->fromp());
const uint32_t mergedCpCostFwd
= std::max(fromp->critPathCost(GraphWay::FORWARD),
top->critPathCostWithout(GraphWay::FORWARD, edgep));
const uint32_t mergedCpCostRev
= std::max(fromp->critPathCostWithout(GraphWay::REVERSE, edgep),
top->critPathCost(GraphWay::REVERSE));
return mergedCpCostRev + mergedCpCostFwd
+ LogicMTask::stepCost(fromp->cost() + top->cost());
}
@ -1443,7 +1446,7 @@ private:
SiblingMC newSibs(ap, bp);
std::pair<SibSet::iterator, bool> insertResult = m_pairs.insert(newSibs);
if (insertResult.second) {
const SiblingMC* newSibsp = &(*insertResult.first);
const SiblingMC* const newSibsp = &(*insertResult.first);
m_mtask2sibs[ap].insert(newSibsp);
m_mtask2sibs[bp].insert(newSibsp);
m_sb.addElem(newSibsp);
@ -1455,7 +1458,7 @@ private:
bool found = false;
for (SibpSet::iterator it = m_mtask2sibs[ap].begin(); it != m_mtask2sibs[ap].end();
++it) {
const SiblingMC* sibsp = *it;
const SiblingMC* const sibsp = *it;
UASSERT_OBJ(!(!sibsp->removedFromSb() && !m_sb.contains(sibsp)), ap,
"One sibling must be the one we collided with");
if ((sibsp->ap() == ap && sibsp->bp() == bp)
@ -1468,11 +1471,11 @@ private:
static const GraphWay* s_shortestWaywardCpInclusiveWay;
static int shortestWaywardCpInclusive(const void* vap, const void* vbp) {
const GraphWay* wp = s_shortestWaywardCpInclusiveWay;
const LogicMTask* ap = *reinterpret_cast<const LogicMTask* const*>(vap);
const LogicMTask* bp = *reinterpret_cast<const LogicMTask* const*>(vbp);
uint32_t aCp = ap->critPathCost(*wp) + ap->stepCost();
uint32_t bCp = bp->critPathCost(*wp) + bp->stepCost();
const GraphWay* const wp = s_shortestWaywardCpInclusiveWay;
const LogicMTask* const ap = *reinterpret_cast<const LogicMTask* const*>(vap);
const LogicMTask* const bp = *reinterpret_cast<const LogicMTask* const*>(vbp);
const uint32_t aCp = ap->critPathCost(*wp) + ap->stepCost();
const uint32_t bCp = bp->critPathCost(*wp) + bp->stepCost();
if (aCp < bCp) return -1;
if (aCp > bCp) return 1;
if (ap->id() < bp->id()) return -1;
@ -1484,7 +1487,7 @@ private:
std::vector<LogicMTask*> shortestPrereqs;
for (V3GraphEdge* edgep = mtaskp->beginp(way); edgep; edgep = edgep->nextp(way)) {
LogicMTask* prereqp = dynamic_cast<LogicMTask*>(edgep->furtherp(way));
LogicMTask* const prereqp = dynamic_cast<LogicMTask*>(edgep->furtherp(way));
shortestPrereqs.push_back(prereqp);
// Prevent nodes with huge numbers of edges from massively
// slowing down the partitioner:
@ -1503,9 +1506,9 @@ private:
auto it = shortestPrereqs.cbegin();
for (unsigned i = 0; exhaustive || (i < 3); ++i) {
if (it == shortestPrereqs.cend()) break;
LogicMTask* ap = *(it++);
LogicMTask* const ap = *(it++);
if (it == shortestPrereqs.cend()) break;
LogicMTask* bp = *(it++);
LogicMTask* const bp = *(it++);
makeSiblingMC(ap, bp);
}
}
@ -1517,8 +1520,8 @@ private:
// runtime should be N*log(N) for a chain-shaped graph.
//
static void selfTestChain() {
vluint64_t usecsSmall = partitionChainUsecs(5);
vluint64_t usecsLarge = partitionChainUsecs(500);
const vluint64_t usecsSmall = partitionChainUsecs(5);
const vluint64_t usecsLarge = partitionChainUsecs(500);
// Large input is 50x bigger than small input.
// Its runtime should be about 10x longer -- not about 2500x longer
// or worse which would suggest N^2 scaling or worse.
@ -1533,7 +1536,7 @@ private:
V3Graph mtasks;
LogicMTask* lastp = nullptr;
for (unsigned i = 0; i < chain_len; ++i) {
LogicMTask* mtp = new LogicMTask(&mtasks, nullptr);
LogicMTask* const mtp = new LogicMTask(&mtasks, nullptr);
mtp->setCost(1);
if (lastp) new MTaskEdge(&mtasks, lastp, mtp, 1);
lastp = mtp;
@ -1551,8 +1554,8 @@ private:
PartParallelismEst check(&mtasks);
check.traverse();
vluint64_t endUsecs = V3Os::timeUsecs();
vluint64_t elapsedUsecs = endUsecs - startUsecs;
const vluint64_t endUsecs = V3Os::timeUsecs();
const vluint64_t elapsedUsecs = endUsecs - startUsecs;
if (debug() >= 6) {
UINFO(0, "Chain self test stats:\n");
@ -1582,20 +1585,20 @@ private:
static void selfTestX() {
// NOTE: To get a dot file run with --debugi-V3Partition 4 or more.
V3Graph mtasks;
LogicMTask* center = new LogicMTask(&mtasks, nullptr);
center->setCost(1);
LogicMTask* const centerp = new LogicMTask(&mtasks, nullptr);
centerp->setCost(1);
unsigned i;
for (i = 0; i < 50; ++i) {
LogicMTask* mtp = new LogicMTask(&mtasks, nullptr);
LogicMTask* const mtp = new LogicMTask(&mtasks, nullptr);
mtp->setCost(1);
// Edge from every input -> center
new MTaskEdge(&mtasks, mtp, center, 1);
// Edge from every input -> centerp
new MTaskEdge(&mtasks, mtp, centerp, 1);
}
for (i = 0; i < 50; ++i) {
LogicMTask* mtp = new LogicMTask(&mtasks, nullptr);
LogicMTask* const mtp = new LogicMTask(&mtasks, nullptr);
mtp->setCost(1);
// Edge from center -> every output
new MTaskEdge(&mtasks, center, mtp, 1);
// Edge from centerp -> every output
new MTaskEdge(&mtasks, centerp, mtp, 1);
}
partInitCriticalPaths(&mtasks);
@ -1776,18 +1779,18 @@ private:
void findAdjacentTasks(OvvSet::iterator ovvIt, TasksByRank* tasksByRankp) {
// Find all writer tasks for this variable, group by rank.
for (V3GraphEdge* edgep = (*ovvIt)->inBeginp(); edgep; edgep = edgep->inNextp()) {
OrderLogicVertex* logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
if (!logicp) continue;
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
LogicMTask* writerMtaskp = m_olv2mtask.at(logicp);
LogicMTask* const writerMtaskp = m_olv2mtask.at(logicp);
(*tasksByRankp)[writerMtaskp->rank()].insert(writerMtaskp);
}
// Find all reader tasks for this variable, group by rank.
for (V3GraphEdge* edgep = (*ovvIt)->outBeginp(); edgep; edgep = edgep->outNextp()) {
OrderLogicVertex* logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
if (!logicp) continue;
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
LogicMTask* readerMtaskp = m_olv2mtask.at(logicp);
LogicMTask* const readerMtaskp = m_olv2mtask.at(logicp);
(*tasksByRankp)[readerMtaskp->rank()].insert(readerMtaskp);
}
}
@ -1801,7 +1804,7 @@ private:
LogicMTask* mergedp = nullptr;
for (LogicMTaskSet::iterator it = rankIt->second.begin(); it != rankIt->second.end();
++it) {
LogicMTask* mtaskp = *it;
LogicMTask* const mtaskp = *it;
if (mergedp) {
if (mergedp->cost() < mtaskp->cost()) mergedp = mtaskp;
} else {
@ -1812,15 +1815,15 @@ private:
while (!rankIt->second.empty()) {
const auto begin = rankIt->second.cbegin();
LogicMTask* donorp = *begin;
LogicMTask* const donorp = *begin;
UASSERT_OBJ(donorp != mergedp, donorp, "Donor can't be merged edge");
rankIt->second.erase(begin);
// Merge donorp into mergedp.
// Fix up the map, so donor's OLVs map to mergedp
for (LogicMTask::VxList::const_iterator tmvit = donorp->vertexListp()->begin();
tmvit != donorp->vertexListp()->end(); ++tmvit) {
MTaskMoveVertex* tmvp = *tmvit;
OrderLogicVertex* logicp = tmvp->logicp();
MTaskMoveVertex* const tmvp = *tmvit;
OrderLogicVertex* const logicp = tmvp->logicp();
if (logicp) m_olv2mtask[logicp] = mergedp;
}
// Move all vertices from donorp to mergedp
@ -1846,7 +1849,7 @@ private:
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
it != mtaskp->vertexListp()->end(); ++it) {
if (!(*it)->logicp()) continue;
AstNode* nodep = (*it)->logicp()->nodep();
AstNode* const nodep = (*it)->logicp()->nodep();
// NOTE: We don't handle DPI exports. If testbench code calls a
// DPI-exported function at any time during eval() we may have
// a data hazard. (Likewise in non-threaded mode if an export
@ -1874,20 +1877,21 @@ public:
OvvSet ovvSetSystemC(ovvOrder);
for (V3GraphVertex* vxp = m_mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
// Should be only one MTaskMoveVertex in each mtask at this
// stage, but whatever, write it as a loop:
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
it != mtaskp->vertexListp()->end(); ++it) {
MTaskMoveVertex* tmvp = *it;
if (OrderLogicVertex* logicp = tmvp->logicp()) {
MTaskMoveVertex* const tmvp = *it;
if (OrderLogicVertex* const logicp = tmvp->logicp()) {
m_olv2mtask[logicp] = mtaskp;
// Look at downstream vars.
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep;
edgep = edgep->outNextp()) {
// Only consider OrderVarStdVertex which reflects
// an actual lvalue assignment; the others do not.
OrderVarStdVertex* ovvp = dynamic_cast<OrderVarStdVertex*>(edgep->top());
OrderVarStdVertex* const ovvp
= dynamic_cast<OrderVarStdVertex*>(edgep->top());
if (!ovvp) continue;
if (ovvp->varScp()->varp()->isSc()) {
ovvSetSystemC.insert(ovvp);
@ -1983,7 +1987,7 @@ public:
TasksByRank tasksByRank;
for (V3GraphVertex* vxp = m_mtasksp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(vxp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
if (hasDpiHazard(mtaskp)) tasksByRank[vxp->rank()].insert(mtaskp);
}
mergeSameRankTasks(&tasksByRank);
@ -2103,7 +2107,7 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
// Find minimum cost MTask for scaling MTask node widths
uint32_t minCost = UINT32_MAX;
for (const V3GraphVertex* vxp = depGraph->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
if (const ExecMTask* mtaskp = dynamic_cast<const ExecMTask*>(vxp)) {
if (const ExecMTask* const mtaskp = dynamic_cast<const ExecMTask*>(vxp)) {
minCost = minCost > mtaskp->cost() ? mtaskp->cost() : minCost;
}
}
@ -2126,15 +2130,15 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
// Emit MTasks
for (const V3GraphVertex* vxp = depGraph->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
if (const ExecMTask* mtaskp = dynamic_cast<const ExecMTask*>(vxp)) { emitMTask(mtaskp); }
if (const ExecMTask* const mtaskp = dynamic_cast<const ExecMTask*>(vxp)) emitMTask(mtaskp);
}
// Emit MTask dependency edges
*logp << "\n // MTask dependencies\n";
for (const V3GraphVertex* vxp = depGraph->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
if (const ExecMTask* mtaskp = dynamic_cast<const ExecMTask*>(vxp)) {
if (const ExecMTask* const mtaskp = dynamic_cast<const ExecMTask*>(vxp)) {
for (V3GraphEdge* edgep = mtaskp->outBeginp(); edgep; edgep = edgep->outNextp()) {
const V3GraphVertex* top = edgep->top();
const V3GraphVertex* const top = edgep->top();
*logp << " " << vxp->name() << " -> " << top->name() << "\n";
}
}
@ -2452,7 +2456,7 @@ void V3Partition::hashGraphDebug(const V3Graph* graphp, const char* debugName) {
unsigned hash = 0;
for (const V3GraphVertex* vxp = graphp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
for (const V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
const V3GraphVertex* top = edgep->top();
const V3GraphVertex* const top = edgep->top();
hash = vx2Id[top] + 31U * hash; // The K&R hash function
}
}
@ -2462,7 +2466,7 @@ void V3Partition::hashGraphDebug(const V3Graph* graphp, const char* debugName) {
void V3Partition::setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp) {
// Look at each mtask
for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(itp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
const LogicMTask::VxList* vertexListp = mtaskp->vertexListp();
// For each logic vertex in this mtask, create an mtask-to-mtask
@ -2471,11 +2475,11 @@ void V3Partition::setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp)
vit != vertexListp->end(); ++vit) {
for (V3GraphEdge* outp = (*vit)->outBeginp(); outp; outp = outp->outNextp()) {
UASSERT(outp->weight() > 0, "Mtask not assigned weight");
const MTaskMoveVertex* top = dynamic_cast<MTaskMoveVertex*>(outp->top());
const MTaskMoveVertex* const top = dynamic_cast<MTaskMoveVertex*>(outp->top());
UASSERT(top, "MoveVertex not associated to mtask");
const auto it = vlstd::as_const(vx2mtaskp)->find(top);
UASSERT(it != vx2mtaskp->end(), "MTask map can't find id");
LogicMTask* otherMTaskp = it->second;
LogicMTask* const otherMTaskp = it->second;
UASSERT(otherMTaskp, "nullptr other Mtask");
UASSERT_OBJ(otherMTaskp != mtaskp, mtaskp, "Would create a cycle edge");
@ -2505,10 +2509,10 @@ void V3Partition::go(V3Graph* mtasksp) {
Vx2MTaskMap vx2mtask;
for (V3GraphVertex* vxp = m_fineDepsGraphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
MTaskMoveVertex* mtmvVxp = dynamic_cast<MTaskMoveVertex*>(vxp);
MTaskMoveVertex* const mtmvVxp = dynamic_cast<MTaskMoveVertex*>(vxp);
UASSERT_OBJ(mtmvVxp, vxp, "Every vertex here should be an MTaskMoveVertex");
LogicMTask* mtaskp = new LogicMTask(mtasksp, mtmvVxp);
LogicMTask* const mtaskp = new LogicMTask(mtasksp, mtmvVxp);
vx2mtask[mtmvVxp] = mtaskp;
totalGraphCost += mtaskp->cost();
@ -2591,7 +2595,7 @@ void V3Partition::go(V3Graph* mtasksp) {
using SortedMTaskSet = std::set<LogicMTask*, LogicMTask::CmpLogicMTask>;
SortedMTaskSet sorted;
for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(itp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
sorted.insert(mtaskp);
}
uint32_t nextId = 1;
@ -2602,16 +2606,16 @@ void V3Partition::go(V3Graph* mtasksp) {
UASSERT(nextId <= (*it)->id(), "Should only shrink MTaskIDs here");
UINFO(4, "Reassigning MTask id " << (*it)->id() << " to id " << nextId << "\n");
(*it)->id(nextId);
nextId++;
++nextId;
}
}
// Set color to indicate an mtaskId on every underlying MTaskMoveVertex.
for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
LogicMTask* mtaskp = dynamic_cast<LogicMTask*>(itp);
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
it != mtaskp->vertexListp()->end(); ++it) {
MTaskMoveVertex* mvertexp = *it;
MTaskMoveVertex* const mvertexp = *it;
mvertexp->color(mtaskp->id());
}
}
@ -2643,7 +2647,7 @@ static void normalizeCosts(Costs& costs) {
// For data where we don't have profiled data, compute how much to
// scale up/down the estimate to make on same relative scale as
// profiled data. (Improves results if only a few profiles missing.)
double estToProfile
const double estToProfile
= static_cast<double>(sumCostProfiled) / static_cast<double>(sumCostEstimate);
UINFO(5, "Estimated data needs scaling by "
<< estToProfile << ", sumCostProfiled=" << sumCostProfiled
@ -2713,13 +2717,14 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
for (const V3GraphVertex* vxp = execMTaskGraphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
// Compute name of mtask, for hash lookup
mtp->hashName(m_uniqueNames.get(mtp->bodyp()));
// This estimate is 64 bits, but the final mtask graph algorithm needs 32 bits
vluint64_t costEstimate = V3InstrCount::count(mtp->bodyp(), false);
vluint64_t costProfiled = V3Config::getProfileData(v3Global.opt.prefix(), mtp->hashName());
const vluint64_t costEstimate = V3InstrCount::count(mtp->bodyp(), false);
const vluint64_t costProfiled
= V3Config::getProfileData(v3Global.opt.prefix(), mtp->hashName());
if (costProfiled) {
UINFO(5, "Profile data for mtask " << mtp->id() << " " << mtp->hashName()
<< " cost override " << costProfiled << endl);
@ -2733,7 +2738,7 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
int missingProfiles = 0;
for (const V3GraphVertex* vxp = execMTaskGraphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
const uint32_t costEstimate = costs[mtp->id()].first;
const uint64_t costProfiled = costs[mtp->id()].second;
UINFO(9, "ce = " << costEstimate << " cp=" << costProfiled << endl);
@ -2751,7 +2756,7 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
}
if (missingProfiles) {
if (FileLine* fl = V3Config::getProfileDataFileLine()) {
if (FileLine* const fl = V3Config::getProfileDataFileLine()) {
fl->v3warn(PROFOUTOFDATE, "Profile data for mtasks may be out of date. "
<< missingProfiles << " of " << totalEstimates
<< " mtasks had no data");
@ -2762,14 +2767,14 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
static void finalizeCosts(V3Graph* execMTaskGraphp) {
GraphStreamUnordered ser(execMTaskGraphp, GraphWay::REVERSE);
while (const V3GraphVertex* vxp = ser.nextp()) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
// "Priority" is the critical path from the start of the mtask, to
// the end of the graph reachable from this mtask. Given the
// choice among several ready mtasks, we'll want to start the
// highest priority one first, so we're always working on the "long
// pole"
for (V3GraphEdge* edgep = mtp->outBeginp(); edgep; edgep = edgep->outNextp()) {
ExecMTask* followp = dynamic_cast<ExecMTask*>(edgep->top());
ExecMTask* const followp = dynamic_cast<ExecMTask*>(edgep->top());
if ((followp->priority() + mtp->cost()) > mtp->priority()) {
mtp->priority(followp->priority() + mtp->cost());
}
@ -2780,13 +2785,13 @@ static void finalizeCosts(V3Graph* execMTaskGraphp) {
// (It's common for tasks to shrink to nothing when V3LifePost
// removes dly assignments.)
for (V3GraphVertex* vxp = execMTaskGraphp->verticesBeginp(); vxp;) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(vxp);
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(vxp);
vxp = vxp->verticesNextp(); // Advance before delete
// Don't rely on checking mtp->cost() == 0 to detect an empty task.
// Our cost-estimating logic is just an estimate. Instead, check
// the MTaskBody to see if it's empty. That's the source of truth.
AstMTaskBody* bodyp = mtp->bodyp();
AstMTaskBody* const bodyp = mtp->bodyp();
if (!bodyp->stmtsp()) { // Kill this empty mtask
UINFO(6, "Removing zero-cost " << mtp->name() << endl);
for (V3GraphEdge* inp = mtp->inBeginp(); inp; inp = inp->inNextp()) {
@ -2805,7 +2810,7 @@ static void finalizeCosts(V3Graph* execMTaskGraphp) {
vluint64_t profilerId = 0;
for (const V3GraphVertex* vxp = execMTaskGraphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
mtp->profilerId(profilerId++);
}

View File

@ -252,7 +252,7 @@ public:
return iterator(valIt, keyIt, this);
}
const_iterator begin() const {
SortByValueMap* mutp = const_cast<SortByValueMap*>(this);
SortByValueMap* const mutp = const_cast<SortByValueMap*>(this);
const auto valIt = mutp->m_vals.begin();
if (valIt == mutp->m_vals.end()) return end();
const auto keyIt = valIt->second.begin();
@ -278,7 +278,7 @@ public:
return iterator(valIt, keyIt, this);
}
const_iterator find(const T_Key& k) const {
SortByValueMap* mutp = const_cast<SortByValueMap*>(this);
SortByValueMap* const mutp = const_cast<SortByValueMap*>(this);
const auto kvit = mutp->m_keys.find(k);
if (kvit == mutp->m_keys.end()) return end();