diff --git a/include/opt-sched/Scheduler/bb_thread.h b/include/opt-sched/Scheduler/bb_thread.h index 13e8c82e..4cc546f7 100644 --- a/include/opt-sched/Scheduler/bb_thread.h +++ b/include/opt-sched/Scheduler/bb_thread.h @@ -35,7 +35,7 @@ Last Update: Jan. 2022 #include #include #include - +#include namespace llvm { namespace opt_sched { @@ -87,12 +87,31 @@ class InstPool { inline int getSortMethod() {return SortMethod_;} inline void setDepth(int Depth) {Depth_ = Depth;} }; +class BBWorker; +class StopRequestBuffer { + + private: + //make mail boxes 64 bytes in size for better caching + struct MailBox { + unsigned long long cost; //8bytes + CostHistEnumTreeNode* history; //8bytes + unsigned long long padding[6]; //48bytes + }; + vector> requestBuffer; + void clear(InstCount readerID); + public: + StopRequestBuffer(); + ~StopRequestBuffer(); + void resize(InstCount numSolvers); + EnumTreeNode* read(InstCount readerID, EnumTreeNode* currentNode, BBWorker* bbt_); + void write(CostHistEnumTreeNode* history, InstCount cost, InstCount writerID, InstCount readerID); +}; class InstPool2 { private: @@ -222,7 +241,7 @@ class BBThread { uint64_t OtherInfsbl = 0; // Global Pool Nodes explored uint64_t GlobalPoolNodes = 0; - + // Allocate register structures needed to track cost void setupForSchdulng(); // Initialize cost and register information (e.g register pressure) @@ -564,7 +583,7 @@ class BBWorker : public BBThread { vector localPools_; std::mutex **localPoolLocks_; - + std::string filename; // References to the locks on shared data std::mutex **HistTableLock_; std::mutex *GlobalPoolLock_; @@ -573,16 +592,18 @@ class BBWorker : public BBThread { std::mutex *ImprvmntCntLock_; std::mutex *RegionSchedLock_; std::mutex *InactiveThreadLock_; - + std::mutex *fileLock_; + StopRequestBuffer* stopRequestBuffer_; int *IdleTime_; int *InactiveThreads_; uint64_t *nodeCounts_; - + std::ofstream ofs; bool WorkSteal_; bool *WorkStealOn_; int64_t **subspaceLwrBounds_; EnumTreeNode *stolenNode_ {nullptr}; - + bool* stopRequestIssued_; + std::atomic* numStopRequests_; bool IsTimeoutPerInst_; int timeoutToMemblock_; @@ -622,7 +643,8 @@ class BBWorker : public BBThread { vector *resAddr, int *idleTimes, int NumSolvers, std::vector localPools, std::mutex **localPoolLocks, int *inactiveThreads, std::mutex *inactiveThreadLock, int LocalPoolSize, bool WorkSteal, bool *WorkStealOn, bool IsTimeoutPerInst, uint64_t *nodeCounts, - int timeoutToMemblock, int64_t **subspaceLwrBounds); + int timeoutToMemblock, int64_t **subspaceLwrBounds, std::mutex* fileLock, + std::atomic* numStopRequests, bool* stopRequestIssued, StopRequestBuffer* stopRequestBuffer); ~BBWorker(); /* @@ -645,7 +667,7 @@ class BBWorker : public BBThread { void allocSched_(); inline void destroy() {Enumrtr_->destroy();} - + void write(const string s); void setBestSched(InstSchedule *sched); void setCrntSched(InstSchedule *sched); @@ -665,6 +687,8 @@ class BBWorker : public BBThread { Enumrtr_->appendToRdyLst(lst); } + void writeStopRequest(CostHistEnumTreeNode* historyNode, InstCount cost, InstCount SolverID); + EnumTreeNode* readStopRequest(EnumTreeNode* node); inline void setRootRdyLst() {Enumrtr_->setRootRdyLst();} bool generateStateFromNode(EnumTreeNode *GlobalPoolNode, bool isGlobalPoolNode = true); @@ -745,8 +769,11 @@ class BBMaster : public BBInterfacer { private: vector Workers; vector ThreadManager; + StopRequestBuffer stopRequestBuffer_; InstPool4 *GlobalPool; int firstLevelSize_; + bool stopRequestIssued_; + std::atomic numStopRequests_; int NumThreads_; int MinNodesAsMultiple_,MinSplittingDepth_, MaxSplittingDepth_; uint64_t MasterNodeCount_; @@ -762,7 +789,7 @@ class BBMaster : public BBInterfacer { std::mutex ImprvCountLock; std::mutex RegionSchedLock; std::mutex InactiveThreadLock; - + std::mutex fileLock; int64_t HistTableSize_; int *idleTimes; @@ -795,7 +822,9 @@ class BBMaster : public BBInterfacer { vector *results, int *idleTimes, int NumSolvers, std::vector localPools, std::mutex **localPoolLocks, int *InactiveThreads_, std::mutex *InactiveThreadLock, int LocalPoolSize, bool WorkSteal, - bool *WorkStealOn, bool IsTimeoutPerInst, uint64_t *nodeCounts, int timeoutToMemblock, int64_t **subspaceLwrBounds); + bool *WorkStealOn, bool IsTimeoutPerInst, uint64_t *nodeCounts, int timeoutToMemblock, + int64_t **subspaceLwrBounds, std::mutex* fileLock, std::atomic* numStopRequests, + bool* stopRequestIssued_, StopRequestBuffer* stopRequestBuffer); bool initGlobalPool(); diff --git a/include/opt-sched/Scheduler/enumerator.h b/include/opt-sched/Scheduler/enumerator.h index 39771f13..fbdeeedb 100644 --- a/include/opt-sched/Scheduler/enumerator.h +++ b/include/opt-sched/Scheduler/enumerator.h @@ -546,7 +546,7 @@ class Enumerator : public ConstrainedScheduler { InstCount minUnschduldTplgclOrdr_; BinHashTable *exmndSubProbs_; - + EnumTreeNode* parentOfDominatedNode_; // A list of insts whose lower bounds have been tightened to be used for // efficient untightening LinkedList *tightndLst_; diff --git a/include/opt-sched/Scheduler/gen_sched.h b/include/opt-sched/Scheduler/gen_sched.h index 527fe6bc..8f5b6e64 100644 --- a/include/opt-sched/Scheduler/gen_sched.h +++ b/include/opt-sched/Scheduler/gen_sched.h @@ -122,6 +122,7 @@ class ConstrainedScheduler : public InstScheduler { // Calculates the schedule and returns it in the passed argument. virtual FUNC_RESULT FindSchedule(InstSchedule *sched, SchedRegion *rgn) = 0; + BBThread* getSolver() {return bbt_;} protected: // The data dependence graph to be scheduled. DataDepGraph *dataDepGraph_; diff --git a/include/opt-sched/Scheduler/hist_table.h b/include/opt-sched/Scheduler/hist_table.h index 36838325..1d076f69 100644 --- a/include/opt-sched/Scheduler/hist_table.h +++ b/include/opt-sched/Scheduler/hist_table.h @@ -83,6 +83,10 @@ class HistEnumTreeNode { inline void setInserted(bool inserted) {isInserted_ = inserted;} + inline void addSolverToHistoryNode(InstCount SolverID) { solversActive_ |= (1 << (SolverID - 2)); } + inline void removeSolverOnHistoryNode(InstCount SolverID) { solversActive_ ^= (1 << (SolverID - 2)); } + inline unsigned int getSolversOnHistoryNode() { return solversActive_; } + inline void clearSolvers() { solversActive_ = 0; } protected: HistEnumTreeNode *prevNode_; @@ -91,7 +95,8 @@ class HistEnumTreeNode { InstCount time_; SchedInstruction *inst_; - + + unsigned int solversActive_; bool fullyExplored_ = false; bool totalCostIsUseable_ = false; bool archived_ = false; diff --git a/lib/Scheduler/bb_thread.cpp b/lib/Scheduler/bb_thread.cpp index fd7405b0..27ee1a8a 100644 --- a/lib/Scheduler/bb_thread.cpp +++ b/lib/Scheduler/bb_thread.cpp @@ -4,6 +4,7 @@ #include "opt-sched/Scheduler/enumerator.h" #include "opt-sched/Scheduler/bb_thread.h" #include "opt-sched/Scheduler/list_sched.h" +#include "opt-sched/Scheduler/hist_table.h" #include "opt-sched/Scheduler/logger.h" #include "opt-sched/Scheduler/random.h" #include "opt-sched/Scheduler/reg_alloc.h" @@ -49,7 +50,11 @@ InstPool3::~InstPool3() { void InstPool3::removeSpecificElement(SchedInstruction *inst, EnumTreeNode *parent, EnumTreeNode *&removed) { // if we've reached this point of the code then there must be isnts in the pool - assert(pool->GetElmntCnt() > 0); + if(pool->GetElmntCnt() == 0) { + removed = nullptr; + return; + } + LinkedListIterator it = pool->begin(); bool removeElement = false; @@ -296,8 +301,88 @@ void InstPool::sort() { //pool = sortedQueue; } +StopRequestBuffer::StopRequestBuffer() {} + +StopRequestBuffer::~StopRequestBuffer() {} + +void StopRequestBuffer::resize(InstCount numSolvers) { + requestBuffer.resize(numSolvers, vector(numSolvers, {INT_MAX, nullptr})); +} + +void StopRequestBuffer::write(CostHistEnumTreeNode* history, InstCount cost, InstCount writerID, InstCount readerID) { + requestBuffer[readerID][writerID].cost = cost; + requestBuffer[readerID][writerID].history = history; +} + +EnumTreeNode* StopRequestBuffer::read(InstCount readerID, EnumTreeNode* currentNode, BBWorker* bbt_) { + + //check and see if we have mail and get the lowest depth candidate + //bbt_->write("Solver ID " + std::to_string(bbt_->getSolverID()) + " read collect"); + vector> candidates; + for(auto& candidate : requestBuffer[readerID]) { + if(candidate.history) { + candidates.push_back({candidate.cost, candidate.history}); + } + } + //bbt_->write("Solver ID " + std::to_string(bbt_->getSolverID()) + " read sort"); + std::sort(candidates.begin(), candidates.end(), [](auto& candidateA, auto& candidateB){ + return candidateA.second->GetTime() < candidateB.second->GetTime(); + }); + + EnumTreeNode* parent = nullptr; + //TODO: the lowest depth request may be stale if we got the request but finished a search and stole work. + //loop through candidates and break on the first match + //bbt_->write("Solver ID " + std::to_string(bbt_->getSolverID()) + " read loop"); + for(auto& candidate : candidates) { + auto historyPtr = candidate.second; + if(!historyPtr) continue; + + //unwind current ptr until we match in instructions or the current ptr is null + auto currentPtr = currentNode; + while(currentPtr && currentPtr->GetInstNum() != historyPtr->GetInstNum()) { + currentPtr = currentPtr->GetParent(); + } + + //if null, then this is a stale request most likely + if(!currentPtr) continue; + + //otherwise, unwind both and check they are the same + parent = currentPtr->GetParent(); + bool samePrefix = true; + while(historyPtr && currentPtr) { + if(historyPtr->GetInstNum() != currentPtr->GetInstNum()) { + samePrefix = false; + break; + } + historyPtr = static_cast(historyPtr->GetParent()); + currentPtr = currentPtr->GetParent(); + } + + //if the instructions didn't match or one was null first, it could be a stale request + if(!samePrefix || (historyPtr && !currentPtr) || (!historyPtr && currentPtr)) { + parent = nullptr; + continue; + } + + //if we've made it to here, we have a match and can exit the loop + //TODO: Figure out stale requests, if we can avoid checking them, and if this should be a do/while + break; + } + //cleanup + //bbt_->write("Solver ID " + std::to_string(bbt_->getSolverID()) + " read clear"); + clear(readerID); + //this will either be valid or null if all the requests didn't match/were stale + //bbt_->write("Solver ID " + std::to_string(bbt_->getSolverID()) + " read return"); + return parent; +} +void StopRequestBuffer::clear(InstCount readerID) { + for(auto& entry : requestBuffer[readerID]) { + entry.cost = INT_MAX; + entry.history = nullptr; + } +} // The denominator used when calculating cost weight. @@ -882,7 +967,6 @@ bool BBThread::chkCostFsblty(InstCount trgtLngth, EnumTreeNode *&node, bool isGl assert(dynmcCostLwrBound >= 0); fsbl = dynmcCostLwrBound < getBestCost(); - // FIXME: RP tracking should be limited to the current SCF. We need RP // tracking interface. if (fsbl || isGlobalPoolNode) { @@ -898,7 +982,7 @@ bool BBThread::chkCostFsblty(InstCount trgtLngth, EnumTreeNode *&node, bool isGl node->SetLocalBestCost(dynmcCostLwrBound); } - stats::costInfeasibilityHits++; + //stats::costInfeasibilityHits++; return fsbl; } /*****************************************************************************/ @@ -1344,9 +1428,9 @@ FUNC_RESULT BBWithSpill::Enumerate_(Milliseconds StartTime, lngthDeadline = rgnDeadline; } - stats::positiveDominationHits.Print(cout); - stats::nodeSuperiorityInfeasibilityHits.Print(cout); - stats::costInfeasibilityHits.Print(cout); + //stats::positiveDominationHits.Print(cout); + //stats::nodeSuperiorityInfeasibilityHits.Print(cout); + //stats::costInfeasibilityHits.Print(cout); #ifdef IS_DEBUG_ITERS stats::iterations.Record(iterCnt); @@ -1422,7 +1506,9 @@ BBWorker::BBWorker(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, std::mutex *RegionSchedLock, vector *RsltAddr, int *idleTimes, int NumSolvers, vector localPools, std::mutex **localPoolLocks, int *inactiveThreads, std::mutex *inactiveThreadLock, int LocalPoolSize, bool WorkSteal, - bool *WorkStealOn, bool IsTimeoutPerInst, uint64_t *nodeCounts, int timeoutToMemblock, int64_t **subspaceLwrBounds) + bool *WorkStealOn, bool IsTimeoutPerInst, uint64_t *nodeCounts, int timeoutToMemblock, + int64_t **subspaceLwrBounds, std::mutex* fileLock, std::atomic* numStopRequests, + bool* stopRequestIssued, StopRequestBuffer* stopRequestBuffer) : BBThread(OST_, dataDepGraph, rgnNum, sigHashSize, lbAlg, hurstcPrirts, enumPrirts, vrfySched, PruningStrategy, SchedForRPOnly, enblStallEnum, SCW, spillCostFunc, HeurSchedType) { @@ -1434,11 +1520,12 @@ BBWorker::BBWorker(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, PruningStrategy_ = PruningStrategy; SpillCostFunc_ = spillCostFunc; SigHashSize_ = sigHashSize; - + IsSecondPass_ = IsSecondPass; TwoPassEnabled_ = twoPassEnabled; NumSolvers_ = NumSolvers; // NumSolvers_ is the number of Threads - + stopRequestIssued_ = stopRequestIssued; + numStopRequests_ = numStopRequests; // Shared Fields MasterSched_ = MasterSched; MasterCost_ = MasterCost; @@ -1458,7 +1545,8 @@ BBWorker::BBWorker(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, RegionSchedLock_ = RegionSchedLock; NodeCountLock_ = NodeCountLock; ImprvmntCntLock_ = ImprvmntCntLock; - + fileLock_ = fileLock; + stopRequestBuffer_ = stopRequestBuffer; RsltAddr_ = RsltAddr; IdleTime_ = idleTimes; @@ -1476,12 +1564,23 @@ BBWorker::BBWorker(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, subspaceLwrBounds_ = subspaceLwrBounds; IsTimeoutPerInst_ = IsTimeoutPerInst; timeoutToMemblock_ = timeoutToMemblock; - + filename = "/home/ramsey/output/" + to_string(SolverID_ - 2) + ".log"; + ofs.open(filename, std::ios_base::app); subspaceLwrBounds[SolverID_-2] = &SubspaceLwrBound_; } +void BBWorker::write(const string s) { + //if(!fileLock_) return; + //std::lock_guard lock(*fileLock_); + //ofs.open("/home/ramsey/output/hist.txt", std::ios_base::app); + ofs << s << std::endl; + //ofs.close(); + +} + BBWorker::~BBWorker() { - delete EnumCrntSched_; + ofs.close(); + delete EnumCrntSched_; } void BBWorker::setHeurInfo(InstCount SchedUprBound, InstCount HeuristicCost, @@ -1611,9 +1710,18 @@ bool BBWorker::generateStateFromNode(std::shared_ptr &GlobalPoolNode){ } return true; } +/*****************************************************************************/ +void BBWorker::writeStopRequest(CostHistEnumTreeNode* history, InstCount cost, InstCount readerID) { + (*numStopRequests_)++; + *stopRequestIssued_ = true; + stopRequestBuffer_->write(history, cost, SolverID_ - 2, readerID); +} +/*****************************************************************************/ - +EnumTreeNode* BBWorker::readStopRequest(EnumTreeNode* currentNode) { + return stopRequestBuffer_->read(SolverID_ - 2, currentNode, this); +} /*****************************************************************************/ bool BBWorker::generateStateFromNode(EnumTreeNode *GlobalPoolNode, bool isGlobalPoolNode){ @@ -1848,6 +1956,7 @@ FUNC_RESULT BBWorker::enumerate_(Milliseconds StartTime, Logger::Info("SolverID %d launching GlobalPoolNode with inst %d (parent %d)", SolverID_, temp->GetInstNum(), temp->GetParent()->GetInstNum()); #endif assert(temp != NULL); + write("Solver " + std::to_string(SolverID_ - 2) + " is attempting a global pool!"); rslt = generateAndEnumerate(temp, StartTime, RgnTimeout, LngthTimeout); if (RegionSched_->GetSpillCost() == 0 || MasterSched_->GetSpillCost() == 0 || rslt == RES_ERROR || (rslt == RES_TIMEOUT) || rslt == RES_EXIT) { return rslt; @@ -1867,7 +1976,7 @@ if (isWorkSteal()) { Logger::Info("solverID_ %d just turned on work stealing", SolverID_); } GlobalPoolLock_->unlock(); - + write("Solver " + std::to_string(SolverID_ - 2) + " is stealing work!"); IdleTime_[SolverID_ - 2] = Utilities::GetProcessorTime(); InactiveThreadLock_->lock(); @@ -1935,6 +2044,8 @@ if (isWorkSteal()) { (*InactiveThreads_)++; InactiveThreadLock_->unlock(); stoleWork = false; + } else { + write("Solver " + std::to_string(SolverID_ - 2) + " took instruction " + std::to_string(workStealNode->GetInstNum()) + " from solver " + std::to_string(victimID)); } } @@ -2085,6 +2196,7 @@ BBMaster::BBMaster(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, MinNodesAsMultiple_ = MinNodesAsMultiple; MinSplittingDepth_ = MinSplittingDepth; MaxSplittingDepth_ = MaxSplittingDepth; + stopRequestBuffer_.resize(NumSolvers); NumSolvers_ = NumSolvers; //how many scheduling instances in total GlobalPool = new InstPool4(GlobalPoolSort); Logger::Info("setting localPoolSize to %d", LocalPoolSize); @@ -2092,11 +2204,11 @@ BBMaster::BBMaster(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, ExploitationPercent_ = ExploitationPercent; Logger::Info("setting globalPoolSCF to %d", GlobalPoolSCF); GlobalPoolSCF_ = GlobalPoolSCF; - Logger::Info("setting work steal to %d", WorkSteal); WorkSteal_ = WorkSteal; WorkStealOn_ = false; - + stopRequestIssued_ = false; + numStopRequests_ = 0; TwoPassEnabled_ = twoPassEnabled; HistTableSize_ = 1 + (UDT_HASHVAL)(((int64_t)(1) << sigHashSize) - 1); @@ -2112,13 +2224,12 @@ BBMaster::BBMaster(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, idleTimes[i] = 0; nodeCounts[i] = 0; localPools[i] = new InstPool3(LocalPoolSize_); - localPoolLocks[i] = new mutex(); + localPoolLocks[i] = new std::mutex(); } for (int i = 0; i < HistTableSize_; i++) { - HistTableLock[i] = new mutex(); + HistTableLock[i] = new std::mutex(); } - results.assign(NumThreads_, RES_SUCCESS); MasterNodeCount_ = 0; @@ -2133,7 +2244,8 @@ BBMaster::BBMaster(const OptSchedTarget *OST_, DataDepGraph *dataDepGraph, &bestSchedLngth_, GlobalPool, &MasterNodeCount_, HistTableLock, &GlobalPoolLock, &BestSchedLock, &NodeCountLock, &ImprvCountLock, &RegionSchedLock, &results, idleTimes, NumSolvers_, localPools, localPoolLocks, &InactiveThreads_, &InactiveThreadLock, LocalPoolSize_, WorkSteal_, - &WorkStealOn_, IsTimeoutPerInst_, nodeCounts, timeoutToMemblock_, subspaceLwrBounds_); + &WorkStealOn_, IsTimeoutPerInst_, nodeCounts, timeoutToMemblock_, subspaceLwrBounds_, &fileLock, + &numStopRequests_, &stopRequestIssued_, &stopRequestBuffer_); ThreadManager.resize(NumThreads_); @@ -2177,7 +2289,8 @@ void BBMaster::initWorkers(const OptSchedTarget *OST_, DataDepGraph *dataDepGrap vector *results, int *idleTimes, int NumSolvers, vector localPools, std::mutex **localPoolLocks, int *inactiveThreads, std::mutex *inactiveThreadLock, int LocalPoolSize, bool WorkSteal, bool *WorkStealOn, bool IsTimeoutPerInst, - uint64_t *nodeCounts, int timeoutToMemblock, int64_t **subspaceLwrBounds) { + uint64_t *nodeCounts, int timeoutToMemblock, int64_t **subspaceLwrBounds, std::mutex* fileLock, + std::atomic* numStopRequests, bool* stopRequestIssued, StopRequestBuffer* stopRequestBuffer) { Workers.resize(NumThreads_); @@ -2189,7 +2302,8 @@ void BBMaster::initWorkers(const OptSchedTarget *OST_, DataDepGraph *dataDepGrap GlobalPoolLock, BestSchedLock, NodeCountLock, ImprvCountLock, RegionSchedLock, results, idleTimes, NumThreads_, localPools, localPoolLocks, inactiveThreads, inactiveThreadLock, LocalPoolSize, WorkSteal, WorkStealOn, - IsTimeoutPerInst, nodeCounts, timeoutToMemblock, subspaceLwrBounds); + IsTimeoutPerInst, nodeCounts, timeoutToMemblock, subspaceLwrBounds, fileLock, + numStopRequests, stopRequestIssued, stopRequestBuffer); } } /*****************************************************************************/ @@ -2692,6 +2806,10 @@ FUNC_RESULT BBMaster::Enumerate_(Milliseconds startTime, Milliseconds rgnTimeout } + if(stopRequestIssued_) { + int numStopRequests = numStopRequests_; + Logger::Event("StopRequestRegion", "num", numStopRequests); + } for (int j = 0; j < NumThreads_; j++) { diff --git a/lib/Scheduler/enumerator.cpp b/lib/Scheduler/enumerator.cpp index d709c6b7..a1357b67 100644 --- a/lib/Scheduler/enumerator.cpp +++ b/lib/Scheduler/enumerator.cpp @@ -38,9 +38,6 @@ HalfNode::~HalfNode() { } } - - - EnumTreeNode::EnumTreeNode() { isCnstrctd_ = false; isClean_ = true; @@ -615,7 +612,7 @@ Enumerator::Enumerator(DataDepGraph *dataDepGraph, MachineModel *machMdl, } dataDepGraph_->EnableBackTracking(); - + parentOfDominatedNode_ = NULL; maxNodeCnt_ = 0; createdNodeCnt_ = 0; exmndNodeCnt_ = 0; @@ -643,7 +640,7 @@ Enumerator::Enumerator(DataDepGraph *dataDepGraph, MachineModel *machMdl, } histTableInitTime = Utilities::GetProcessorTime() - histTableInitTime; - stats::historyTableInitializationTime.Record(histTableInitTime); + //stats::historyTableInitializationTime.Record(histTableInitTime); tightndLst_ = NULL; bkwrdTightndLst_ = NULL; @@ -1192,13 +1189,32 @@ FUNC_RESULT Enumerator::FindFeasibleSchedule_(InstSchedule *sched, } else { - // All branches from the current node have been explored, and no more - // branches that lead to feasible nodes have been found. - if (crntNode_ == rootNode_) { - if (bbt_->isWorker() && IsFirstPass_) BackTrackRoot_(); - allNodesExplrd = true; + if(parentOfDominatedNode_ != NULL && parentOfDominatedNode_ != nullptr && !bbt_->isSecondPass() && bbt_->isWorker()) { + //static_cast(bbt_)->write("Solver " + std::to_string(this->getSolverID() - 2) + " at instruction " + std::to_string(crntNode_->GetInstNum()) + + // " backtracking to parent of dominated node parent inst: " + std::to_string(parentOfDominatedNode_->GetInstNum())); + if(parentOfDominatedNode_ && crntNode_ != parentOfDominatedNode_) { + if(crntNode_ != rootNode_ && !crntNode_->isArtRoot()){ + BackTrack_(); + }else{ + BackTrackRoot_(); + //if(bbt_->isWorkStealOn() && bbt_->isWorkSteal() && bbt_->isWorker() && !bbt_->isSecondPass()) + //static_cast(bbt_)->write("Solver " + std::to_string(this->getSolverID() - 2) + " backtracked root!"); + allNodesExplrd = true; + } + } + if(parentOfDominatedNode_ && crntNode_ == parentOfDominatedNode_ || allNodesExplrd) { + //static_cast(bbt_)->write("Solver " + std::to_string(this->getSolverID() - 2) + " unsetting parent"); + parentOfDominatedNode_ = NULL; + } } else { - isCrntNodeFsbl = BackTrack_(); + // All branches from the current node have been explored, and no more + // branches that lead to feasible nodes have been found. + if (crntNode_ == rootNode_) { + if (bbt_->isWorker() && IsFirstPass_) BackTrackRoot_(); + allNodesExplrd = true; + } else { + isCrntNodeFsbl = BackTrack_(); + } } } @@ -1246,6 +1262,10 @@ bool Enumerator::FindNxtFsblBrnch_(EnumTreeNode *&newNode) { stats::maxReadyListSize.SetMax(rdyInstCnt); #endif + if(parentOfDominatedNode_ != NULL && bbt_->isWorker() && !bbt_->isSecondPass()){ + //static_cast(bbt_)->write("Solver " + std::to_string(getSolverID() - 2) + " not inspecting children!!!"); + return false; + } if (crntBrnchNum == 0 && SchedForRPOnly_) crntNode_->SetFoundInstWithUse(IsUseInRdyLst_()); @@ -1353,6 +1373,9 @@ bool Enumerator::FindNxtFsblBrnch_(EnumTreeNode *&newNode) { isNodeDmntd = isRlxInfsbl = false; isLngthFsbl = true; + /* if(!bbt_->isSecondPass() && bbt_->isWorker()) + static_cast(bbt_)->write(std::to_string(SolverID_ - 2) + " considering inst " + std::to_string(inst->GetNum())); +*/ if (ProbeBranch_(inst, newNode, isNodeDmntd, isRlxInfsbl, isLngthFsbl)) { @@ -1364,6 +1387,11 @@ bool Enumerator::FindNxtFsblBrnch_(EnumTreeNode *&newNode) { RestoreCrntState_(inst, newNode); crntNode_->NewBranchExmnd(inst, true, isNodeDmntd, isRlxInfsbl, false, DIR_FRWRD, isLngthFsbl); + if(parentOfDominatedNode_ != NULL && bbt_->isWorker() && !bbt_->isSecondPass()){ + //static_cast(bbt_)->write("Solver " + std::to_string(getSolverID() - 2) + " not inspecting children!!!"); + return false; + } + } @@ -1407,7 +1435,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, #ifdef IS_DEBUG_INFSBLTY_TESTS stats::forwardLBInfeasibilityHits++; #endif - stats::forwardLBInfeasibilityHits++; + //stats::forwardLBInfeasibilityHits++; #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: LB fail"); #endif @@ -1417,7 +1445,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, #ifdef IS_DEBUG_INFSBLTY_TESTS stats::backwardLBInfeasibilityHits++; #endif - stats::backwardLBInfeasibilityHits++; + //stats::backwardLBInfeasibilityHits++; #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: deadline fail"); @@ -1439,7 +1467,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, if (prune_.nodeSup) { if (inst != NULL) { if (crntNode_->WasSprirNodeExmnd(inst)) { - stats::nodeSuperiorityInfeasibilityHits++; + //stats::nodeSuperiorityInfeasibilityHits++; nodeSupInfsbl++; isNodeDmntd = true; #ifdef IS_DEBUG_SEARCH_ORDER @@ -1467,7 +1495,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, stats::slotCountInfeasibilityHits++; #endif if (!bbt_->isSecondPass()) Logger::Info("actually pruning due to slot count"); - stats::slotCountInfeasibilityHits++; + //stats::slotCountInfeasibilityHits++; #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: issue slot fail"); #endif @@ -1484,7 +1512,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, stats::rangeTighteningInfeasibilityHits++; #endif if (!bbt_->isSecondPass()) Logger::Info("actually pruning due to rng tightn"); - stats::rangeTighteningInfeasibilityHits++; + //stats::rangeTighteningInfeasibilityHits++; #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: tightn LB fail"); @@ -1509,7 +1537,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, #ifdef IS_DEBUG_INFSBLTY_TESTS stats::historyDominationInfeasibilityHits++; #endif - stats::historyDominationInfeasibilityHits++; + //stats::historyDominationInfeasibilityHits++; #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: histDom fail"); #endif @@ -1530,7 +1558,7 @@ bool Enumerator::ProbeBranch_(SchedInstruction *inst, EnumTreeNode *&newNode, stats::relaxedSchedulingInfeasibilityHits++; #endif if (!bbt_->isSecondPass()) Logger::Info("actually pruning due to rlx schd"); - stats::relaxedSchedulingInfeasibilityHits++; + //stats::relaxedSchedulingInfeasibilityHits++; isRlxInfsbl = true; #ifdef IS_DEBUG_SEARCH_ORDER @@ -1702,6 +1730,7 @@ if (bbt_->isWorkStealOn()) { HistEnumTreeNode *crntHstry = crntNode_->GetHistory(); crntHstry->setFullyExplored(false); crntHstry->setCostIsUseable(false); + crntHstry->addSolverToHistoryNode(SolverID_); bbt_->histTableLock(key); assert(!crntHstry->isInserted()); exmndSubProbs_->InsertElement(crntNode_->GetSig(), crntHstry, @@ -1742,6 +1771,9 @@ if (bbt_->isWorkStealOn()) { CmtLwrBoundTightnng_(); ClearState_(); + //if(!bbt_->isSecondPass() && bbt_->isWorker()) { + // static_cast(bbt_)->write(std::to_string(SolverID_ - 2) + " stepping into inst " + std::to_string(instNumToSchdul)); + // } } /*****************************************************************************/ @@ -1956,7 +1988,6 @@ bool Enumerator::BackTrack_(bool trueState) { SchedInstruction *inst = crntNode_->GetInst(); EnumTreeNode *trgtNode = crntNode_->GetParent(); bool fullyExplored = false; - #ifdef IS_CORRECT_LOCALPOOL Logger::Info("SolverID %d backtracking to time %d", SolverID_, trgtNode->GetTime()); #endif @@ -1989,6 +2020,7 @@ bool Enumerator::BackTrack_(bool trueState) { fullyExplored = true; if (crntNode_->wasChildStolen()) Logger::Info("$$GOODHIT -- fullyexplored with stolen child"); } + // set fully explored to fullyExplored when work stealing crntHstry->setFullyExplored(fullyExplored); SetTotalCostsAndSuffixes(crntNode_, trgtNode, trgtSchedLngth_, @@ -2078,6 +2110,10 @@ bool Enumerator::BackTrack_(bool trueState) { // there is a race condition to setFullyExplored when a child has stole // from the subspace, thus the fullyExplored assert is only true // if the subspace has not been stolen from + if (parentOfDominatedNode_) { + crntHstry->removeSolverOnHistoryNode(getSolverID()); + fullyExplored = true; + } crntHstry->setFullyExplored(fullyExplored); SetTotalCostsAndSuffixes(crntNode_, trgtNode, trgtSchedLngth_, prune_.useSuffixConcatenation, fullyExplored); @@ -2159,7 +2195,7 @@ bool Enumerator::WasDmnntSubProbExmnd_(SchedInstruction *, int listSize = exmndSubProbs_->GetListSize(newNode->GetSig()); UDT_HASHVAL key = exmndSubProbs_->HashKey(newNode->GetSig()); - stats::historyListSize.Record(listSize); + //stats::historyListSize.Record(listSize); if (listSize == 0) return false; mostRecentMatchingHistNode_ = nullptr; bool mostRecentMatchWasSet = false; @@ -2168,7 +2204,8 @@ bool Enumerator::WasDmnntSubProbExmnd_(SchedInstruction *, // lock table for syncrhonized iterator - + + bbt_->histTableLock(key); HashTblEntry *srchPtr = nullptr; exNode = exmndSubProbs_->GetLastMatch(srchPtr,newNode->GetSig()); @@ -2196,7 +2233,7 @@ bool Enumerator::WasDmnntSubProbExmnd_(SchedInstruction *, exNode->PrntPartialSched(Logger::GetLogStream()); #endif - stats::positiveDominationHits++; + //stats::positiveDominationHits++; #ifdef IS_DEBUG_SPD stats::positiveDominationHits++; stats::traversedHistoryListSize.Record(trvrsdListSize); @@ -2210,7 +2247,34 @@ bool Enumerator::WasDmnntSubProbExmnd_(SchedInstruction *, } else { if (exNode->getFullyExplored()) { lastMatch = exNode; + } else { + //we didn't prune and the history wasn't fully explored. + //If we are looking at a first pass parallel enumeration, stop the other thread! + if(bbt_->isWorker() && !bbt_->isSecondPass()) { + //lock so we can update those that added themselves to the node. anyone accessing history after this point will prune if they have a worse cost + //or they will be responsible for the next stop request. + + + auto solversOnHistoryNode = exNode->getSolversOnHistoryNode(); + for(int i = 0; i < 16; i++) { + if(solversOnHistoryNode & (1 << i)){ + //static_cast(bbt_)->write("Solver ID: " + std::to_string(getSolverID()) + " write start"); + static_cast(bbt_)->writeStopRequest(static_cast(exNode), + newNode->GetCostLwrBound(), i); + //static_cast(bbt_)->write("Solver ID: " + std::to_string(getSolverID()) + " write end"); } + + } + exNode->ResetHistFields(newNode); + exNode->setRecycled(true); + newNode->SetHistory(exNode); + newNode->setRecyclesHistNode(true); + newNode->setArchived(true); + exNode->clearSolvers(); + exNode->addSolverToHistoryNode(getSolverID()); + } + } + #ifdef IS_DEBUG_SPD stats::signatureAliases++; #endif @@ -2221,18 +2285,17 @@ bool Enumerator::WasDmnntSubProbExmnd_(SchedInstruction *, } if (!wasDmntSubProbExmnd && lastMatch != nullptr && IsTwoPass_ && !isSecondPass()) { - bbt_->histTableLock(key); lastMatch->ResetHistFields(newNode); lastMatch->setRecycled(true); newNode->SetHistory(lastMatch); newNode->setRecyclesHistNode(true); newNode->setArchived(true); - bbt_->histTableUnlock(key); } - + + bbt_->histTableUnlock(key); - stats::traversedHistoryListSize.Record(trvrsdListSize); + //stats::traversedHistoryListSize.Record(trvrsdListSize); return wasDmntSubProbExmnd; } /****************************************************************************/ @@ -2558,7 +2621,7 @@ void Enumerator::PrintLog_() { Logger::Info("Total nodes examined: %lld\n", GetNodeCnt()); Logger::Info("History table includes %d entries.\n", exmndSubProbs_->GetEntryCnt()); - Logger::GetLogStream() << stats::historyEntriesPerIteration; + //Logger::GetLogStream() << stats::historyEntriesPerIteration; Logger::Info("--------------------------------------------------\n"); } /*****************************************************************************/ @@ -2870,6 +2933,10 @@ bool LengthCostEnumerator::ProbeBranch_(SchedInstruction *inst, #endif crntNode_->incrementExploredChildren(); crntNode_->SetLocalBestCost(newNode->GetLocalBestCost()); + /*if(!bbt_->isSecondPass() && bbt_->isWorker()) + static_cast(bbt_)->write(std::to_string(SolverID_ - 2) + " cost infsbl"); + */ + return false; } @@ -2886,7 +2953,7 @@ bool LengthCostEnumerator::ProbeBranch_(SchedInstruction *inst, #ifdef IS_DEBUG_INFSBLTY_TESTS stats::historyDominationInfeasibilityHits++; #endif - stats::historyDominationInfeasibilityHits; + //stats::historyDominationInfeasibilityHits; bbt_->unschdulInst(inst, crntCycleNum_, crntSlotNum_, parent); #ifdef IS_DEBUG_SEARCH_ORDER Logger::Log((Logger::LOG_LEVEL) 4, false, "probe: LCE history fail"); @@ -2895,10 +2962,34 @@ bool LengthCostEnumerator::ProbeBranch_(SchedInstruction *inst, crntNode_->incrementExploredChildren(); nodeAlctr_->Free(newNode); newNode = NULL; + /*if(!bbt_->isSecondPass() && bbt_->isWorker()) + static_cast(bbt_)->write(std::to_string(SolverID_ - 2) + " hist dom"); +*/ return false; } } + + + //thread stop check + if(bbt_->isWorker() && !bbt_->isSecondPass()) { + + //if we get a valid pointer back, set the stop flag so we can back track to the parent + //static_cast(bbt_)->write("Solver ID " + std::to_string(getSolverID()) + " read start"); + auto parentOfDominatedNode = static_cast(bbt_)->readStopRequest(crntNode_); + //static_cast(bbt_)->write("Solver ID " + std::to_string(getSolverID()) + " read end"); + if(parentOfDominatedNode != NULL) { + EnumTreeNode *parent = newNode->GetParent(); + bbt_->unschdulInst(inst, crntCycleNum_, crntSlotNum_, parent); + nodeAlctr_->Free(newNode); + newNode = NULL; + crntNode_->incrementExploredChildren(); + parentOfDominatedNode_ = parentOfDominatedNode; + return false; + + } + } + assert(newNode); return true; } @@ -2915,9 +3006,8 @@ bool LengthCostEnumerator::ChkCostFsblty_(SchedInstruction *inst, if (prune_.spillCost) { isFsbl = bbt_->chkCostFsblty(trgtSchedLngth_, newNode, !trueState); - if (!isFsbl && trueState) { - stats::costInfeasibilityHits++; + //stats::costInfeasibilityHits++; #ifdef IS_DEBUG_FLOW Logger::Info("Detected cost infeasibility of inst %d in cycle %d", inst == NULL ? -2 : inst->GetNum(), crntCycleNum_); @@ -2935,6 +3025,8 @@ bool LengthCostEnumerator::ChkCostFsblty_(SchedInstruction *inst, bool LengthCostEnumerator::BackTrack_(bool trueState) { SchedInstruction *inst = crntNode_->GetInst(); + //if(bbt_->isWorker() && !bbt_->isSecondPass()) + //static_cast(bbt_)->write("Solver " + std::to_string(getSolverID() - 2) + " backtracking from " + std::to_string(crntNode_->GetInstNum()) + " which had time " + std::to_string(crntNode_->GetTime())); bbt_->unschdulInst(inst, crntCycleNum_, crntSlotNum_, crntNode_->GetParent()); bool fsbl = Enumerator::BackTrack_(trueState); @@ -2948,6 +3040,8 @@ bool LengthCostEnumerator::BackTrack_(bool trueState) { } } + if(parentOfDominatedNode_) fsbl = false; + if (!fsbl) { crntNode_->setIsInfsblFromBacktrack_(true); crntNode_->SetLocalBestCost(crntNode_->GetCostLwrBound()); @@ -2958,16 +3052,18 @@ if (bbt_->isWorkStealOn()) { // thus we need to ensure that all children are removed on backtrack if (bbt_->isWorker() && IsFirstPass_ && !fsbl) { bbt_->localPoolLock(SolverID_ - 2); + if (bbt_->getLocalPoolSize(SolverID_ - 2) > 0) { EnumTreeNode *popNode = bbt_->localPoolPopFront(SolverID_ - 2); assert(popNode); - assert(popNode->GetTime() <= (crntNode_->GetTime() + 1)); - while (popNode->GetTime() == (crntNode_->GetTime() + 1)) { + assert(popNode->GetTime() <= (crntNode_->GetTime() + 1) || parentOfDominatedNode_ != NULL); + + while (popNode->GetTime() >= (crntNode_->GetTime() + 1)) { #ifdef IS_CORRECT_LOCALPOOL Logger::Info("SolverID %d removed element from localPool at time %d", SolverID_, popNode->GetTime()); #endif - assert(popNode->GetParent() == crntNode_); + assert(popNode->GetParent() == crntNode_ || parentOfDominatedNode_ != NULL); nodeAlctr_->Free(popNode); if (bbt_->getLocalPoolSize(SolverID_ - 2) == 0) break; popNode = bbt_->localPoolPopFront(SolverID_ - 2); @@ -2977,6 +3073,7 @@ if (bbt_->isWorkStealOn()) { bbt_->localPoolPushFront(SolverID_- 2,popNode); } } + crntNode_->setPushedToLocalPool(false); bbt_->localPoolUnlock(SolverID_ - 2); } } @@ -2988,7 +3085,9 @@ if (bbt_->isWorkStealOn()) { void LengthCostEnumerator::BackTrackRoot_(EnumTreeNode *) { EnumTreeNode *tempNode = nullptr; if (bbt_->getStolenNode() != nullptr) tempNode = bbt_->getStolenNode(); - + + //if(bbt_->getStolenNode() != nullptr) + //static_cast(bbt_)->write("Solver " + std::to_string(getSolverID() - 2) + " in backtrack root with stolen node " + std::to_string(crntNode_->GetInstNum()) + " is? " + std::to_string(bbt_->getStolenNode()->GetInstNum()) + " time: " + std::to_string(crntNode_->GetTime())); // if we have stolen work, need to backtrack against the victim threads active tree // use the stolen node to backtrack from Enumerator::BackTrackRoot_(tempNode); @@ -3119,6 +3218,10 @@ void Enumerator::BackTrackRoot_(EnumTreeNode *tmpCrntNode) { } fullyExplored = true; } + if(parentOfDominatedNode_) { + crntHstry->removeSolverOnHistoryNode(getSolverID()); + fullyExplored = true; + } // set fully explored to fullyExplored when work stealing // TODO(jeff): it is possible that the crntHstry has been recycled and now belongs // to a different subspace @@ -3146,13 +3249,13 @@ void Enumerator::BackTrackRoot_(EnumTreeNode *tmpCrntNode) { if (bbt_->getLocalPoolSize(SolverID_ - 2) > 0) { EnumTreeNode *popNode = bbt_->localPoolPopFront(SolverID_ - 2); assert(popNode); - assert(popNode->GetTime() <= (crntNode_->GetTime() + 1)); + assert(popNode->GetTime() <= (crntNode_->GetTime() + 1) || parentOfDominatedNode_ != NULL); - while (popNode->GetTime() == (crntNode_->GetTime() + 1)) { + while (popNode->GetTime() >= (crntNode_->GetTime() + 1)) { #ifdef IS_CORRECT_LOCALPOOL Logger::Info("SolverID %d removed element from localPool at time %d", SolverID_, popNode->GetTime()); #endif - assert(popNode->GetParent() == crntNode_); + assert(popNode->GetParent() == crntNode_ || parentOfDominatedNode_ != NULL); nodeAlctr_->Free(popNode); if (bbt_->getLocalPoolSize(SolverID_ - 2) == 0) break; popNode = bbt_->localPoolPopFront(SolverID_ - 2); @@ -3380,6 +3483,7 @@ bool LengthCostEnumerator::scheduleNodeOrPrune(EnumTreeNode *node, break; } } + assert(found); rdyLst_->ResetIterator(); @@ -3494,6 +3598,7 @@ EnumTreeNode *LengthCostEnumerator::scheduleInst_(SchedInstruction *inst, bool i bbt_->histTableLock(key); crntHstry->setFullyExplored(false); crntHstry->setCostIsUseable(false); + crntHstry->addSolverToHistoryNode(getSolverID()); if (!crntNode_->getRecyclesHistNode()) { assert(!crntHstry->isInserted() || isSecondPass()); exmndSubProbs_->InsertElement(crntNode_->GetSig(), crntHstry, diff --git a/lib/Scheduler/hist_table.cpp b/lib/Scheduler/hist_table.cpp index c37e8273..1064257b 100644 --- a/lib/Scheduler/hist_table.cpp +++ b/lib/Scheduler/hist_table.cpp @@ -2,12 +2,13 @@ #include "opt-sched/Scheduler/logger.h" #include "opt-sched/Scheduler/stats.h" #include "opt-sched/Scheduler/utilities.h" +#include "opt-sched/Scheduler/bb_thread.h" #include "llvm/Support/Casting.h" #include using namespace llvm::opt_sched; -HistEnumTreeNode::HistEnumTreeNode() { rsrvSlots_ = NULL; } +HistEnumTreeNode::HistEnumTreeNode() { rsrvSlots_ = NULL; solversActive_ = 0; } HistEnumTreeNode::~HistEnumTreeNode() { if (rsrvSlots_) @@ -588,9 +589,10 @@ static bool doesHistoryPeakCostDominate(InstCount OtherPrefixCost, // If we cannot improve the prefix, prune the candidate node. Likewise, if // the total cost is determined by the suffix schedule we cannot improve the // cost with a better prefix. - if (OtherPrefixCost >= HistPrefixCost || HistTotalCost > HistPrefixCost) - return true; + if (OtherPrefixCost >= HistPrefixCost || HistTotalCost > HistPrefixCost) { + return true; + } // Prunes the candidate node if the improved prefix still has higher cost than // the best schedule found so far. return LCE->GetBestCost() <= OtherPrefixCost; @@ -612,7 +614,8 @@ bool CostHistEnumTreeNode::ChkCostDmntnForBBSpill_(EnumTreeNode *Node, if (Node->GetCostLwrBound() >= partialCost_) { ShouldPrune = true; - + + Node->SetLocalBestCost(Node->GetCostLwrBound()); if (Node->GetParent()) { Node->GetParent()->SetLocalBestCost(Node->GetCostLwrBound()); diff --git a/lib/Wrapper/OptimizingScheduler.cpp b/lib/Wrapper/OptimizingScheduler.cpp index 5ee7c7cd..b23b787d 100644 --- a/lib/Wrapper/OptimizingScheduler.cpp +++ b/lib/Wrapper/OptimizingScheduler.cpp @@ -435,7 +435,6 @@ void ScheduleDAGOptSched::schedule() { OST->createDDGWrapper(C, this, MM.get(), LatencyPrecision, RegionName, NumSolvers); int size = DDG.get()->getSize(); - DataDepGraph *dataDepGraph_ = static_cast(DDG.get()); int preFiltered = false; Logger::Info("fin create ddg"); @@ -445,9 +444,11 @@ void ScheduleDAGOptSched::schedule() { Logger::Info("DDG of size %d is outside limits, not parallelizing", size); Logger::Info("Limits: min (%d), max (%d)", MinDDGSize, 1000); preFiltered = true; + DDG = OST->createDDGWrapper(C, this, MM.get(), LatencyPrecision, RegionName, 1); //return; } - + DataDepGraph *dataDepGraph_ = static_cast(DDG.get()); + // In the second pass, ignore artificial edges before running the sequential // heuristic list scheduler. if (SecondPass) @@ -501,7 +502,7 @@ void ScheduleDAGOptSched::schedule() { Rslt = region->FindOptimalSchedule(CurrentRegionTimeout, CurrentLengthTimeout, IsEasy, NormBestCost, BestSchedLngth, NormHurstcCost, HurstcSchedLngth, Sched, - FilterByPerp, blocksToKeep(schedIni), ParallelBB); + FilterByPerp, blocksToKeep(schedIni), false); if ((!(Rslt == RES_SUCCESS || Rslt == RES_TIMEOUT) || Sched == NULL)) { @@ -549,7 +550,7 @@ void ScheduleDAGOptSched::schedule() { IsEasy, NormBestCost, BestSchedLngth, NormHurstcCost, HurstcSchedLngth, Sched, FilterByPerp, blocksToKeep(schedIni), ParallelBB); - + if ((!(Rslt == RES_SUCCESS || Rslt == RES_TIMEOUT) || Sched == NULL)) { LLVM_DEBUG( Logger::Info("OptSched run failed: rslt=%d, sched=%p. Falling back.", @@ -558,7 +559,6 @@ void ScheduleDAGOptSched::schedule() { // fallbackScheduler(); return; } - OST->finalizeRegion(Sched); if (!OST->shouldKeepSchedule()) { for (size_t i = 0; i < SUnits.size(); i++) { @@ -568,13 +568,12 @@ void ScheduleDAGOptSched::schedule() { return; } - // Count simulated spills. if (isSimRegAllocEnabled()) { SimulatedSpills += region->GetSimSpills(); } } - + // Convert back to LLVM. // Advance past initial DebugValues. CurrentTop = nextIfDebug(RegionBegin, RegionEnd);