From: Pan Xiuli <xiuli....@intel.com> Fix the pre schedule, now it will work with the origin algorithm. We add more dependency for instruction to keep the schedule result not random and keep the origin order.
Contributor: Ruiling Song <ruiling.s...@intel.com> Signed-off-by: Pan Xiuli <xiuli....@intel.com> --- backend/src/backend/gen_insn_scheduling.cpp | 113 +++++++++++++++++++--------- 1 file changed, 77 insertions(+), 36 deletions(-) diff --git a/backend/src/backend/gen_insn_scheduling.cpp b/backend/src/backend/gen_insn_scheduling.cpp index 245d17a..de21301 100644 --- a/backend/src/backend/gen_insn_scheduling.cpp +++ b/backend/src/backend/gen_insn_scheduling.cpp @@ -102,7 +102,8 @@ namespace gbe WRITE_AFTER_WRITE, WRITE_AFTER_READ, READ_AFTER_WRITE, - READ_AFTER_WRITE_MEMORY + READ_AFTER_WRITE_MEMORY, + SYNCHRONIZATION } DepMode; /*! We need to chain together the node we point */ @@ -113,11 +114,17 @@ namespace gbe DepMode depMode; }; + struct ScheduleDAGWrapper + { + INLINE ScheduleDAGWrapper(ScheduleDAGNode *node, DepMode m = READ_AFTER_WRITE) : node(node), depMode(m) {} + ScheduleDAGNode *node; + DepMode depMode; + }; /*! Node of the DAG */ struct ScheduleDAGNode { INLINE ScheduleDAGNode(SelectionInstruction &insn) : - insn(insn), refNum(0), depNum(0), retiredCycle(0), preRetired(false), readDistance(0x7fffffff) {} + insn(insn), refNum(0), depNum(0), regNum(0), retiredCycle(0), preRetired(false), readDistance(0x7fffffff) {} bool dependsOn(ScheduleDAGNode *node) const { GBE_ASSERT(node != NULL); for (auto child : node->children) @@ -206,7 +213,7 @@ namespace gbe /*! Stores the last node that wrote to a register / memory ... */ vector<ScheduleDAGNode*> nodes; /*! store nodes each node depends on */ - map<ScheduleDAGNode *, vector<ScheduleDAGNode*>> deps; + map<ScheduleDAGNode *, vector<ScheduleDAGWrapper>> deps; /*! Stores the nodes per instruction */ vector<ScheduleDAGNode*> insnNodes; /*! Number of virtual register in the selection */ @@ -283,20 +290,22 @@ namespace gbe void DependencyTracker::addDependency(ScheduleDAGNode *node0, ScheduleDAGNode *node1, DepMode depMode) { if (node0 != NULL && node1 != NULL && node0 != node1 && node0->dependsOn(node1) == false) { - if (node1->insn.isRead()) - depMode = depMode == READ_AFTER_WRITE ? READ_AFTER_WRITE_MEMORY : depMode; ScheduleListNode *dep = scheduler.newScheduleListNode(node0, depMode); node0->refNum++; node1->children.push_back(dep); node1->depNum++; auto it = deps.find(node0); if (it != deps.end()) { - it->second.push_back(node1); + it->second.push_back(ScheduleDAGWrapper(node1, depMode)); } else { - vector<ScheduleDAGNode*> vn; - vn.push_back(node1); + vector<ScheduleDAGWrapper> vn; + vn.push_back(ScheduleDAGWrapper(node1, depMode)); deps.insert(std::make_pair(node0, vn)); } + } else { + if (node0 != NULL && node1 == NULL && depMode == READ_AFTER_WRITE) { + node0->regNum += 1; + } } } @@ -474,8 +483,8 @@ namespace gbe auto it = tracker.deps.find(node); if (it != tracker.deps.end()) { for (auto &depNode : it->second) { - if (depNode && !depNode->insn.isRead()) - traverseReadNode(depNode, degree + 1); + if (depNode.node && !depNode.node->insn.isRead()) + traverseReadNode(depNode.node, degree + 1); } } } @@ -504,12 +513,12 @@ namespace gbe // read-after-write in memory if (insn.isRead()) { const uint32_t index = tracker.getMemoryIndex(); - tracker.addDependency(node, index, READ_AFTER_WRITE); + tracker.addDependency(node, index, READ_AFTER_WRITE_MEMORY); } //read-after-write of scratch memory if (insn.opcode == SEL_OP_UNSPILL_REG) { const uint32_t index = tracker.getMemoryIndex(); - tracker.addDependency(node, index, READ_AFTER_WRITE); + tracker.addDependency(node, index, READ_AFTER_WRITE_MEMORY); } // Consider barriers and wait are reading memory (local and global) @@ -518,7 +527,7 @@ namespace gbe insn.opcode == SEL_OP_WAIT || insn.opcode == SEL_OP_WORKGROUP_OP) { const uint32_t memIndex = tracker.getMemoryIndex(); - tracker.addDependency(node, memIndex, READ_AFTER_WRITE); + tracker.addDependency(node, memIndex, READ_AFTER_WRITE_MEMORY); } // write-after-write in registers @@ -630,6 +639,9 @@ namespace gbe inline bool cmp(const ScheduleDAGNode *v0, const ScheduleDAGNode *v1) { return v0->regNum < v1->regNum; } + inline bool cmpID(const ScheduleDAGNode *v0, const ScheduleDAGNode *v1) { + return v0->insn.ID < v1->insn.ID; + } /* Recursively compute heuristic Sethi-Ullman number for each node. */ void SelectionScheduler::computeRegPressure(ScheduleDAGNode *node, @@ -639,24 +651,30 @@ namespace gbe return; } if (node->refNum == 0) { - node->regNum = 0; - regPressureMap.insert(std::make_pair(node, 0)); + regPressureMap.insert(std::make_pair(node, node->regNum)); return; } - auto &children = tracker.deps.find(node)->second; - for (auto child : children) { - computeRegPressure(child, regPressureMap); + auto &childrenOld = tracker.deps.find(node)->second; + for (auto child : childrenOld) { + computeRegPressure(child.node, regPressureMap); + } + // we only care true data dependency here. + vector<ScheduleDAGNode *> children; + + for (auto &x : childrenOld) { + if (x.depMode == READ_AFTER_WRITE) + children.push_back(x.node); } std::sort(children.begin(), children.end(), cmp); uint32_t maxRegNum = 0; - int32_t i = 0; + int32_t i = 1; for (auto &child : children) { if (child->regNum + children.size() - i > maxRegNum) - maxRegNum = child->regNum + node->children.size() - i; + maxRegNum = child->regNum + children.size() - i; ++i; } - node->regNum = maxRegNum; - regPressureMap.insert(std::make_pair(node, maxRegNum)); + node->regNum += maxRegNum; + regPressureMap.insert(std::make_pair(node, node->regNum)); return; } @@ -673,7 +691,7 @@ namespace gbe computeRegPressure(node, regPressureMap); parentIndexMap.insert(std::make_pair(node, INT_MAX)); } - set<ScheduleDAGNode *> readySet(rootNodes.begin(), rootNodes.end()); + vector<ScheduleDAGNode *> readySet(rootNodes.begin(), rootNodes.end()); set<ScheduleDAGNode *> scheduledSet; int32_t j = insnNum; @@ -682,36 +700,59 @@ namespace gbe // as the best node to schedule. while(readySet.size()) { ScheduleDAGNode * bestNode = NULL; + vector<ScheduleDAGNode *>::iterator bestNodeitr; int32_t minRegNum = INT_MAX; int32_t minParentIndex = INT_MAX; - for(auto node : readySet) { + uint32_t nowinsnID = 0; + std::sort(readySet.begin(), readySet.end(), cmp); + for(auto itr = readySet.begin(); itr != readySet.end(); ++itr) { + ScheduleDAGNode * node = *itr; GBE_ASSERT(scheduledSet.contains(node) == false); if (parentIndexMap.find(node)->second < minParentIndex) { bestNode = node; + bestNodeitr = itr; minParentIndex = parentIndexMap.find(node)->second; minRegNum = regPressureMap.find(node)->second; } else if (parentIndexMap.find(node)->second == minParentIndex) { if (regPressureMap.find(node)->second < minRegNum) { + bestNodeitr = itr; bestNode = node; minRegNum = regPressureMap.find(node)->second; } + else if (regPressureMap.find(node)->second == minRegNum) { + if (nowinsnID < node->insn.ID) { + bestNode = node; + bestNodeitr = itr; + nowinsnID = node->insn.ID; + } + } } } - for( auto node : tracker.deps.find(bestNode)->second ) { - if (node == NULL) - continue; - node->depNum--; - if (parentIndexMap.find(node) != parentIndexMap.end()) - parentIndexMap.find(node)->second = j; - else - parentIndexMap.insert(std::make_pair(node, j)); - if (node->depNum == 0 && scheduledSet.contains(node) == false) - readySet.insert(node); - } bb.prepend(&bestNode->insn); - readySet.erase(bestNode); + readySet.erase(bestNodeitr); scheduledSet.insert(bestNode); + auto itt = tracker.deps.find(bestNode); + if (itt != tracker.deps.end()) { + for( auto node : itt->second ) { + if (node.node == NULL) + continue; + node.node->depNum--; + if (parentIndexMap.find(node.node) != parentIndexMap.end()) + parentIndexMap.find(node.node)->second = j; + else + parentIndexMap.insert(std::make_pair(node.node, j)); + for(auto noderd : readySet) { + if (noderd->dependsOn(node.node) && node.depMode != 2) + { + parentIndexMap.find(noderd)->second = j - 1; + } + } + } + for( auto node : itt->second ) + if (node.node->depNum == 0 && scheduledSet.contains(node.node) == false) + readySet.push_back(node.node); + } --j; } GBE_ASSERT(insnNum == (int32_t)bb.insnList.size()); -- 2.7.4 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/beignet