X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetSchedInfo.cpp;h=185f01ec9e859f578cf76c334de891420dc734a0;hb=233ad71051985511152385966f208eb2d83a8801;hp=c02654f03b68ead21ed523516ab35adc10f57c00;hpb=697954c15da58bd8b186dbafdedd8b06db770201;p=oota-llvm.git diff --git a/lib/Target/TargetSchedInfo.cpp b/lib/Target/TargetSchedInfo.cpp index c02654f03b6..185f01ec9e8 100644 --- a/lib/Target/TargetSchedInfo.cpp +++ b/lib/Target/TargetSchedInfo.cpp @@ -6,12 +6,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/MachineSchedInfo.h" - -// External object describing the machine instructions -// Initialized only when the TargetMachine class is created -// and reset when that class is destroyed. -// -const MachineInstrDescriptor* TargetInstrDescriptors = 0; +#include "llvm/Target/TargetMachine.h" resourceId_t MachineResource::nextId = 0; @@ -107,7 +102,7 @@ MachineSchedInfo::initializeResources() for (InstrSchedClass sc = 0; sc < numSchedClasses; sc++) { // instrRUForClasses.push_back(new InstrRUsage); instrRUForClasses[sc].setMaxSlots(getMaxNumIssueTotal()); - instrRUForClasses[sc] = classRUsages[sc]; + instrRUForClasses[sc].setTo(classRUsages[sc]); } computeInstrResources(instrRUForClasses); @@ -125,7 +120,7 @@ MachineSchedInfo::computeInstrResources(const std::vector& // First get the resource usage information from the class resource usages. for (MachineOpCode op = 0; op < numOpCodes; ++op) { InstrSchedClass sc = getSchedClass(op); - assert(sc >= 0 && sc < numSchedClasses); + assert(sc < numSchedClasses); instrRUsages[op] = instrRUForClasses[sc]; } @@ -150,11 +145,12 @@ MachineSchedInfo::computeIssueGaps(const std::vector& instrRUForClasses) { int numOpCodes = mii->getNumRealOpCodes(); - instrRUsages.resize(numOpCodes); - + issueGaps.resize(numOpCodes); + conflictLists.resize(numOpCodes); + assert(numOpCodes < (1 << MAX_OPCODE_SIZE) - 1 && "numOpCodes invalid for implementation of class OpCodePair!"); - + // First, compute issue gaps between pairs of classes based on common // resources usages for each class, because most instruction pairs will // usually behave the same as their class. @@ -167,27 +163,92 @@ MachineSchedInfo::computeIssueGaps(const std::vector& instrRUForClasses[toSC]); classPairGaps[fromSC][toSC] = classPairGap; } - + // Now, for each pair of instructions, use the class pair gap if both // instructions have identical resource usage as their respective classes. // If not, recompute the gap for the pair from scratch. - + longestIssueConflict = 0; - + for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++) for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) { - int instrPairGap = - (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) - ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] - : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); - - if (instrPairGap > 0) - { - issueGaps[OpCodePair(fromOp,toOp)] = instrPairGap; - conflictLists[fromOp].push_back(toOp); - longestIssueConflict = std::max(longestIssueConflict, instrPairGap); - } + int instrPairGap = + (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) + ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] + : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); + + if (instrPairGap > 0) + { + this->setGap(instrPairGap, fromOp, toOp); + conflictLists[fromOp].push_back(toOp); + longestIssueConflict=std::max(longestIssueConflict, instrPairGap); + } } } + +void InstrRUsage::setTo(const InstrClassRUsage& classRU) { + sameAsClass = true; + isSingleIssue = classRU.isSingleIssue; + breaksGroup = classRU.breaksGroup; + numBubbles = classRU.numBubbles; + + for (unsigned i=0; i < classRU.numSlots; i++) + { + unsigned slot = classRU.feasibleSlots[i]; + assert(slot < feasibleSlots.size() && "Invalid slot specified!"); + this->feasibleSlots[slot] = true; + } + + numCycles = classRU.totCycles; + resourcesByCycle.resize(this->numCycles); + + for (unsigned i=0; i < classRU.numRUEntries; i++) + for (unsigned c=classRU.V[i].startCycle, NC = c + classRU.V[i].numCycles; + c < NC; c++) + this->resourcesByCycle[c].push_back(classRU.V[i].resourceId); + + // Sort each resource usage vector by resourceId_t to speed up conflict checking + for (unsigned i=0; i < this->resourcesByCycle.size(); i++) + sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end()); + +} + +// Add the extra resource usage requirements specified in the delta. +// Note that a negative value of `numCycles' means one entry for that +// resource should be deleted for each cycle. +// +void InstrRUsage::addUsageDelta(const InstrRUsageDelta &delta) { + int NC = delta.numCycles; + sameAsClass = false; + + // resize the resources vector if more cycles are specified + unsigned maxCycles = this->numCycles; + maxCycles = std::max(maxCycles, delta.startCycle + abs(NC) - 1); + if (maxCycles > this->numCycles) + { + this->resourcesByCycle.resize(maxCycles); + this->numCycles = maxCycles; + } + + if (NC >= 0) + for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++) + this->resourcesByCycle[c].push_back(delta.resourceId); + else + // Remove the resource from all NC cycles. + for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++) + { + // Look for the resource backwards so we remove the last entry + // for that resource in each cycle. + std::vector& rvec = this->resourcesByCycle[c]; + int r; + for (r = (int) rvec.size(); r >= 0; r--) + if (rvec[r] == delta.resourceId) + {// found last entry for the resource + rvec.erase(rvec.begin() + r); + break; + } + assert(r >= 0 && "Resource to remove was unused in cycle c!"); + } +}