//===----------------------------------------------------------------------===//
#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;
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);
// 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];
}
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.
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<resourceId_t>& 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!");
+ }
+}