Skip to content

Commit

Permalink
(NFC) Remove preId and postId from G4_BB
Browse files Browse the repository at this point in the history
preId and postId field in G4_BB were used for DFS algorithm (and for some
reason we have several) on the control flow graph. They should not be kept
inside G4_BB as their values can become stale after flow graph update. Instead,
the user of the DFS should pass ina BB-to-Id map where we can return the
results.

Also remove sendInBB and Latency_Sched from G4_BB for similar reasons.
  • Loading branch information
Wei-Chen-Intel authored and igcbot committed Jun 30, 2023
1 parent e383450 commit d4ec717
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 106 deletions.
101 changes: 39 additions & 62 deletions visa/FlowGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,10 +679,6 @@ void FlowGraph::constructFlowGraph(INST_LIST &instlist) {
curr_BB->splice(curr_BB->end(), instlist, iter);
G4_INST *next_i = (instlist.empty()) ? nullptr : instlist.front();

if (i->isSend()) {
curr_BB->setSendInBB(true);
}

if (i->isLabel() && i->getLabel()->isFuncLabel()) {
std::vector<G4_BB *> bbvec;
subroutines[i->getLabel()] = bbvec;
Expand Down Expand Up @@ -1520,39 +1516,39 @@ void FlowGraph::normalizeSubRoutineBB(FuncInfoHashTable &funcInfoTable) {
// preId set according to the ordering. Blocks that never get visited will
// have their preId unmodified.
//
void doDFS(G4_BB *startBB, unsigned int p) {
static void doDFS(G4_BB *startBB, unsigned int p, BBIDMap &preIDMap) {
unsigned int currP = p;
std::stack<G4_BB *> traversalStack;
traversalStack.push(startBB);

while (!traversalStack.empty()) {
G4_BB *currBB = traversalStack.top();
traversalStack.pop();
if (currBB->getPreId() != UINT_MAX) {
if (preIDMap.at(currBB) != UINT_MAX) {
continue;
}
currBB->setPreId(currP++);
preIDMap[currBB] = currP++;

for (G4_BB *tmp : currBB->Succs) {
if (tmp->getPreId() == UINT_MAX) {
if (preIDMap.at(tmp) == UINT_MAX) {
traversalStack.push(tmp);
}
}
}
}

void FlowGraph::recomputePreId() {
void FlowGraph::recomputePreId(BBIDMap &IDMap) {
unsigned preId = 0;
//
// initializations
//
for (G4_BB *bb : BBs) {
bb->setPreId(UINT_MAX);
IDMap[bb] = UINT_MAX;
}
//
// assign DFS based pre/rpost ids to all blocks in the main program
//
doDFS(getEntryBB(), preId);
doDFS(getEntryBB(), preId, IDMap);
}

//
Expand All @@ -1564,7 +1560,8 @@ void FlowGraph::recomputePreId() {
// is deemed unreachable.
//
void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
recomputePreId();
BBIDMap preIDMap;
recomputePreId(preIDMap);

//
// Basic blocks with preId/rpostId set to UINT_MAX are unreachable.
Expand All @@ -1578,7 +1575,7 @@ void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
BB_LIST_ITER it = BBs.begin();
while (it != BBs.end()) {
G4_BB *bb = (*it);
if (bb->getPreId() == UINT_MAX) {
if (preIDMap.at(bb) == UINT_MAX) {
if (bb->getBBType() & G4_BB_INIT_TYPE) {
// Remove it from funcInfoHT.
int funcId = bb->getId();
Expand All @@ -1588,8 +1585,8 @@ void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
// If call bb is removed, its return BB shuld be removed as well.
G4_BB *retBB = bb->getPhysicalSucc();
vISA_ASSERT(retBB, "vISA ICE: missing Return BB");
if (retBB->getPreId() != UINT_MAX) {
retBB->setPreId(UINT_MAX);
if (preIDMap.at(retBB) != UINT_MAX) {
preIDMap[retBB] = UINT_MAX;
}
}

Expand Down Expand Up @@ -1629,7 +1626,7 @@ void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
G4_BB *retBB = bb->getPhysicalSucc();
vISA_ASSERT(retBB && (retBB->getBBType() & G4_BB_RETURN_TYPE),
"vISA ICE: missing RETURN BB");
if (retBB->getPreId() == UINT_MAX) {
if (preIDMap.at(retBB) == UINT_MAX) {
// For example,
// CALL_BB : call A succ: init_BB
// RETURN_BB: pred: exit_BB
Expand All @@ -1640,7 +1637,7 @@ void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
// exit_BB: succ : RETURN_BB
// Both RETURN_BB and exit_BB are unreachable, but
// we keep both!
retBB->setPreId(UINT_MAX - 1);
preIDMap[retBB] = UINT_MAX - 1;
}
} else if (bb->getBBType() & G4_BB_INIT_TYPE) {
// function isn't dead, don't remove exit BB.
Expand All @@ -1650,9 +1647,9 @@ void FlowGraph::removeUnreachableBlocks(FuncInfoHashTable &funcInfoHT) {
FuncInfo *finfo = entry->second;
G4_BB *exitBB = finfo->getExitBB();
vISA_ASSERT(exitBB, "vISA ICE: missing exit BB");
if (exitBB->getPreId() == UINT_MAX) {
if (preIDMap.at(exitBB) == UINT_MAX) {
// See the example above for G4_BB_CALL_TYPE
exitBB->setPreId(UINT_MAX - 1);
preIDMap[exitBB] = UINT_MAX - 1;
}
}
it++;
Expand Down Expand Up @@ -3707,7 +3704,7 @@ void FlowGraph::addSIMDEdges() {
// subroutine blocks so that they will be processed independently later)
//
void FlowGraph::DFSTraverse(G4_BB *startBB, unsigned &preId, unsigned &postId,
FuncInfo *fn) {
FuncInfo *fn, BBPrePostIDMap &BBPrePostId) {
vISA_ASSERT(fn, "Invalid func info");

// clear fields that will be reset by this function.
Expand All @@ -3716,13 +3713,24 @@ void FlowGraph::DFSTraverse(G4_BB *startBB, unsigned &preId, unsigned &postId,
std::stack<G4_BB *> traversalStack;
traversalStack.push(startBB);

constexpr int PRE_ID = 0, POST_ID = 1;

auto getPreId = [&](G4_BB *bb) {
auto iter = BBPrePostId.find(bb);
return iter != BBPrePostId.end() ? iter->second[PRE_ID] : UINT_MAX;
};
auto getPostId = [&](G4_BB *bb) {
auto iter = BBPrePostId.find(bb);
return iter != BBPrePostId.end() ? iter->second[POST_ID] : UINT_MAX;
};

while (!traversalStack.empty()) {
G4_BB *bb = traversalStack.top();
if (bb->getPreId() != UINT_MAX) {
if (getPreId(bb) != UINT_MAX) {
// Pre-processed already and continue to the next one.
// Before doing so, set postId if not set before.
traversalStack.pop();
if (bb->getRPostId() == UINT_MAX) {
if (getPostId(bb) == UINT_MAX) {
// All bb's succ has been visited (PreId is set) at this time.
// if any of its succ has not been finished (RPostId not set),
// bb->succ forms a backedge.
Expand All @@ -3732,21 +3740,21 @@ void FlowGraph::DFSTraverse(G4_BB *startBB, unsigned &preId, unsigned &postId,
// be checked as well ?)
if (!(bb->getBBType() & (G4_BB_CALL_TYPE | G4_BB_EXIT_TYPE))) {
for (auto succBB : bb->Succs) {
if (succBB->getRPostId() == UINT_MAX) {
if (getPostId(succBB) == UINT_MAX) {
backEdges.push_back(Edge(bb, succBB));
}
}
}

// Need to keep this after backedge checking so that self-backedge
// (single-bb loop) will not be missed.
bb->setRPostId(postId++);
BBPrePostId[bb][POST_ID] = postId++;
}
continue;
}

fn->addBB(bb);
bb->setPreId(preId++);
BBPrePostId[bb][PRE_ID] = preId++;

if (bb->getBBType() & G4_BB_CALL_TYPE) {
G4_BB *returnBB = bb->BBAfterCall();
Expand All @@ -3769,7 +3777,7 @@ void FlowGraph::DFSTraverse(G4_BB *startBB, unsigned &preId, unsigned &postId,
}
}

if (returnBB->getPreId() == UINT_MAX) {
if (getPreId(returnBB) == UINT_MAX) {
traversalStack.push(returnBB);
} else {
vISA_ASSERT(false, ERROR_FLOWGRAPH);
Expand All @@ -3781,17 +3789,11 @@ void FlowGraph::DFSTraverse(G4_BB *startBB, unsigned &preId, unsigned &postId,
BB_LIST_RITER RIE = bb->Succs.rend();
for (BB_LIST_RITER rit = bb->Succs.rbegin(); rit != RIE; ++rit) {
G4_BB *succBB = *rit;
if (succBB->getPreId() == UINT_MAX) {
if (getPreId(succBB) == UINT_MAX) {
traversalStack.push(succBB);
}
}
}
// As the top of stack may be different than that at the
// beginning of this iteration, cannot do pop here. Instead,
// do pop and set RPostId at the beginning of each iteration.
//
// traversalStack.pop();
// bb->setRPostId(postId++);
}
}

Expand All @@ -3808,51 +3810,26 @@ void vISA::FlowGraph::markStale() {
// should be marked as stale here.
}

void FlowGraph::markRPOTraversal() {
vISA_ASSERT(numBBId == BBs.size(), ERROR_FLOWGRAPH);

unsigned postID = 0;
backEdges.clear();

for (auto curBB : BBs) {
curBB->setRPostId(postID++);

if (curBB->size() > 0) {
if (curBB->getBBType() & G4_BB_CALL_TYPE) {
// skip
} else if (curBB->getBBType() & G4_BB_EXIT_TYPE) {
// Skip
} else {
for (auto succBB : curBB->Succs) {
if (curBB->getId() >= succBB->getId()) {
backEdges.push_back(Edge(curBB, succBB));
}
}
}
}
}
}

//
// Find back-edges in the flow graph.
//
void FlowGraph::findBackEdges() {
vISA_ASSERT(numBBId == BBs.size(), ERROR_FLOWGRAPH);
BBPrePostIDMap BBPrePostID;

for (auto bb : BBs) {
bb->setPreId(UINT_MAX);
bb->setRPostId(UINT_MAX);
BBPrePostID[bb] = {UINT_MAX, UINT_MAX};
}

unsigned preId = 0;
unsigned postID = 0;
backEdges.clear();

setPhysicalPredSucc();
DFSTraverse(getEntryBB(), preId, postID, kernelInfo);
DFSTraverse(getEntryBB(), preId, postID, kernelInfo, BBPrePostID);

for (auto fn : funcInfoTable) {
DFSTraverse(fn->getInitBB(), preId, postID, fn);
DFSTraverse(fn->getInitBB(), preId, postID, fn, BBPrePostID);
}
}

Expand Down
11 changes: 6 additions & 5 deletions visa/FlowGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ class GlobalOpndHashTable {
void dump(std::ostream &os = std::cerr) const;
}; // GlobalOpndHashTable

using BBIDMap = std::unordered_map<G4_BB *, uint32_t>;

class FlowGraph {
// This list maintains the ordering of the basic blocks (i.e., asm and binary
// emission will output the blocks in list oder. Important: Due to the nature
Expand Down Expand Up @@ -501,8 +503,7 @@ class FlowGraph {

//
// Recompute preId of all BBs in FlowGraph
//
void recomputePreId();
void recomputePreId(BBIDMap &IDMap);

void constructFlowGraph(INST_LIST &instlist);
bool matchBranch(int &sn, INST_LIST &instlist, INST_LIST_ITER &it);
Expand All @@ -528,8 +529,6 @@ class FlowGraph {
// explicitly
void setPhysicalPredSucc();

void markRPOTraversal();

void findBackEdges();
void findNaturalLoops();

Expand Down Expand Up @@ -605,7 +604,9 @@ class FlowGraph {

void decoupleReturnBlock(G4_BB *);
void decoupleInitBlock(G4_BB *, FuncInfoHashTable &funcInfoTable);
void DFSTraverse(G4_BB *bb, unsigned &preId, unsigned &postId, FuncInfo *fn);
using BBPrePostIDMap = std::unordered_map<G4_BB *, std::array<uint32_t, 2>>;
void DFSTraverse(G4_BB *bb, unsigned &preId, unsigned &postId, FuncInfo *fn,
BBPrePostIDMap &BBIdMap);

}; // FlowGraph

Expand Down
30 changes: 4 additions & 26 deletions visa/G4_BB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ class G4_BB {
//
unsigned id;
//
// preorder block id
//
unsigned preId;
//
// reverse postorder block id
//
unsigned rpostId;
//
// traversal is for traversing control flow graph (to indicate the
// block is visited)
//
Expand All @@ -79,7 +71,6 @@ class G4_BB {

// indicates if the block is part of a natural loop or not
bool inNaturalLoop;
bool hasSendInBB;

// indicate the nest level of the loop
unsigned char loopNestLevel;
Expand All @@ -92,8 +83,6 @@ class G4_BB {
// active in this BB.
bool divergent;

bool Latency_Sched;

bool specialEmptyBB;

// the physical pred/succ for this block (i.e., the pred/succ for this
Expand Down Expand Up @@ -201,11 +190,10 @@ class G4_BB {
BB_LIST Succs;

G4_BB(INST_LIST_NODE_ALLOCATOR &alloc, unsigned i, FlowGraph *fg)
: id(i), preId(0), rpostId(0), traversal(0), calleeInfo(NULL),
BBType(G4_BB_NONE_TYPE), inNaturalLoop(false), hasSendInBB(false),
loopNestLevel(0), scopeID(0), divergent(false), specialEmptyBB(false),
physicalPred(NULL), physicalSucc(NULL), parent(fg), instList(alloc),
Latency_Sched(false) {}
: id(i), traversal(0), calleeInfo(NULL), BBType(G4_BB_NONE_TYPE),
inNaturalLoop(false), loopNestLevel(0), scopeID(0), divergent(false),
specialEmptyBB(false), physicalPred(NULL), physicalSucc(NULL),
parent(fg), instList(alloc) {}

~G4_BB() { instList.clear(); }

Expand All @@ -220,12 +208,6 @@ class G4_BB {
unsigned getId() const { return id; }
void setId(unsigned i);

unsigned getPreId() const { return preId; }
void setPreId(unsigned i) { preId = i; }

unsigned getRPostId() const { return rpostId; }
void setRPostId(unsigned i) { rpostId = i; }

void markTraversed(unsigned num) { traversal = num; }
bool isAlreadyTraversed(unsigned num) const { return traversal >= num; }

Expand All @@ -250,17 +232,13 @@ class G4_BB {
bool isInNaturalLoop() const { return inNaturalLoop; }

bool isSuccBB(G4_BB *succ) const; // return true if succ is in bb's Succss
void setSendInBB(bool val) { hasSendInBB = val; }
bool isSendInBB() const { return hasSendInBB; }

void setNestLevel() { loopNestLevel++; }
unsigned getNestLevel() const { return loopNestLevel; }
void resetNestLevel() { loopNestLevel = 0; }

void setDivergent(bool val) { divergent = val; }
bool isDivergent() const { return divergent; }
void setLatencySched(bool val) { Latency_Sched = val; }
bool isLatencySched() const { return Latency_Sched; }
bool isAllLaneActive() const;

unsigned getScopeID() const { return scopeID; }
Expand Down
Loading

0 comments on commit d4ec717

Please sign in to comment.