summaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetSchedule.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-11-06 07:10:38 +0000
committerAndrew Trick <atrick@apple.com>2012-11-06 07:10:38 +0000
commit8d4abb2446f80986ad5136bbec30c5da18cd6f4b (patch)
treea4337cf1caade4cd909ac3244330c83e838d7129 /lib/CodeGen/TargetSchedule.cpp
parent2276453e2be12badb07f84f8be9cf89626da48b6 (diff)
downloadllvm-8d4abb2446f80986ad5136bbec30c5da18cd6f4b.tar.gz
llvm-8d4abb2446f80986ad5136bbec30c5da18cd6f4b.tar.bz2
llvm-8d4abb2446f80986ad5136bbec30c5da18cd6f4b.tar.xz
misched: TargetSchedule interface for machine resources.
Expose the processor resources defined by the machine model to the scheduler and other clients through the TargetSchedule interface. Normalize each resource count with respect to other kinds of resources. This allows scheduling heuristics to balance resources against other kinds of resources and latency. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167444 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetSchedule.cpp')
-rw-r--r--lib/CodeGen/TargetSchedule.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/CodeGen/TargetSchedule.cpp b/lib/CodeGen/TargetSchedule.cpp
index 6a096a16c4..ca3b0e0b11 100644
--- a/lib/CodeGen/TargetSchedule.cpp
+++ b/lib/CodeGen/TargetSchedule.cpp
@@ -36,6 +36,21 @@ bool TargetSchedModel::hasInstrItineraries() const {
return EnableSchedItins && !InstrItins.isEmpty();
}
+static unsigned gcd(unsigned Dividend, unsigned Divisor) {
+ // Dividend and Divisor will be naturally swapped as needed.
+ while(Divisor) {
+ unsigned Rem = Dividend % Divisor;
+ Dividend = Divisor;
+ Divisor = Rem;
+ };
+ return Dividend;
+}
+static unsigned lcm(unsigned A, unsigned B) {
+ unsigned LCM = (uint64_t(A) * B) / gcd(A, B);
+ assert((LCM >= A && LCM >= B) && "LCM overflow");
+ return LCM;
+}
+
void TargetSchedModel::init(const MCSchedModel &sm,
const TargetSubtargetInfo *sti,
const TargetInstrInfo *tii) {
@@ -43,17 +58,33 @@ void TargetSchedModel::init(const MCSchedModel &sm,
STI = sti;
TII = tii;
STI->initInstrItins(InstrItins);
+
+ unsigned NumRes = SchedModel.getNumProcResourceKinds();
+ ResourceFactors.resize(NumRes);
+ ResourceLCM = SchedModel.IssueWidth;
+ for (unsigned Idx = 0; Idx < NumRes; ++Idx) {
+ unsigned NumUnits = SchedModel.getProcResource(Idx)->NumUnits;
+ if (NumUnits > 0)
+ ResourceLCM = lcm(ResourceLCM, NumUnits);
+ }
+ MicroOpFactor = ResourceLCM / SchedModel.IssueWidth;
+ for (unsigned Idx = 0; Idx < NumRes; ++Idx) {
+ unsigned NumUnits = SchedModel.getProcResource(Idx)->NumUnits;
+ ResourceFactors[Idx] = NumUnits ? (ResourceLCM / NumUnits) : 0;
+ }
}
-unsigned TargetSchedModel::getNumMicroOps(MachineInstr *MI) const {
+unsigned TargetSchedModel::getNumMicroOps(const MachineInstr *MI,
+ const MCSchedClassDesc *SC) const {
if (hasInstrItineraries()) {
int UOps = InstrItins.getNumMicroOps(MI->getDesc().getSchedClass());
return (UOps >= 0) ? UOps : TII->getNumMicroOps(&InstrItins, MI);
}
if (hasInstrSchedModel()) {
- const MCSchedClassDesc *SCDesc = resolveSchedClass(MI);
- if (SCDesc->isValid())
- return SCDesc->NumMicroOps;
+ if (!SC)
+ SC = resolveSchedClass(MI);
+ if (SC->isValid())
+ return SC->NumMicroOps;
}
return MI->isTransient() ? 0 : 1;
}