diff options
author | Andrew Trick <atrick@apple.com> | 2012-10-17 17:27:10 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2012-10-17 17:27:10 +0000 |
commit | fdd6fa89b960088b368231ec08e56a0c0b1e6930 (patch) | |
tree | b4f573ba21c505fc3a0a7e39c85a11c9ce061d51 | |
parent | a747a84addb85ef0c34ba88f2a45679a413f8347 (diff) |
misched: Better handling of invalid latencies in the machine model
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166107 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCSchedule.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/TargetSchedule.cpp | 12 |
2 files changed, 15 insertions, 5 deletions
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 0504dc13c8..c9a060c79b 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -54,10 +54,12 @@ struct MCWriteProcResEntry { }; /// Specify the latency in cpu cycles for a particular scheduling class and def -/// index. Also identify the WriteResources of this def. When the operand -/// expands to a sequence of writes, this ID is the last write in the sequence. +/// index. -1 indicates an invalid latency. Heuristics would typically consider +/// an instruction with invalid latency to have infinite latency. Also identify +/// the WriteResources of this def. When the operand expands to a sequence of +/// writes, this ID is the last write in the sequence. struct MCWriteLatencyEntry { - unsigned Cycles; + int Cycles; unsigned WriteResourceID; bool operator==(const MCWriteLatencyEntry &Other) const { diff --git a/lib/CodeGen/TargetSchedule.cpp b/lib/CodeGen/TargetSchedule.cpp index 7a6e2604d7..6a096a16c4 100644 --- a/lib/CodeGen/TargetSchedule.cpp +++ b/lib/CodeGen/TargetSchedule.cpp @@ -58,6 +58,14 @@ unsigned TargetSchedModel::getNumMicroOps(MachineInstr *MI) const { return MI->isTransient() ? 0 : 1; } +// The machine model may explicitly specify an invalid latency, which +// effectively means infinite latency. Since users of the TargetSchedule API +// don't know how to handle this, we convert it to a very large latency that is +// easy to distinguish when debugging the DAG but won't induce overflow. +static unsigned convertLatency(int Cycles) { + return Cycles >= 0 ? Cycles : 1000; +} + /// If we can determine the operand latency from the def only, without machine /// model or itinerary lookup, do so. Otherwise return -1. int TargetSchedModel::getDefLatency(const MachineInstr *DefMI, @@ -178,7 +186,7 @@ unsigned TargetSchedModel::computeOperandLatency( const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc, DefIdx); unsigned WriteID = WLEntry->WriteResourceID; - unsigned Latency = WLEntry->Cycles; + unsigned Latency = convertLatency(WLEntry->Cycles); if (!UseMI) return Latency; @@ -219,7 +227,7 @@ unsigned TargetSchedModel::computeInstrLatency(const MachineInstr *MI) const { // Lookup the definition's write latency in SubtargetInfo. const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc, DefIdx); - Latency = std::max(Latency, WLEntry->Cycles); + Latency = std::max(Latency, convertLatency(WLEntry->Cycles)); } return Latency; } |