diff options
author | Andrew Trick <atrick@apple.com> | 2012-06-07 19:42:04 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2012-06-07 19:42:04 +0000 |
commit | 397f4e3583b36b23047fec06b1648f0771cd6fe3 (patch) | |
tree | dd69572e275b8071fb5123ff6773e4769e16e989 /lib/Target/TargetInstrInfo.cpp | |
parent | 68b16541cc58411c7b0607ca4c0fb497222b668d (diff) | |
download | llvm-397f4e3583b36b23047fec06b1648f0771cd6fe3.tar.gz llvm-397f4e3583b36b23047fec06b1648f0771cd6fe3.tar.bz2 llvm-397f4e3583b36b23047fec06b1648f0771cd6fe3.tar.xz |
Continue factoring computeOperandLatency. Use it for ARM hasHighOperandLatency.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158164 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/TargetInstrInfo.cpp')
-rw-r--r-- | lib/Target/TargetInstrInfo.cpp | 88 |
1 files changed, 65 insertions, 23 deletions
diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index ae38732065..613efea731 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -83,28 +83,15 @@ TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); } -/// computeOperandLatency - Compute and return the latency of the given data -/// dependent def and use. DefMI must be a valid def. UseMI may be NULL for an -/// unknown use. Depending on the subtarget's itinerary properties, this may or -/// may not need to call getOperandLatency(). -/// -/// FindMin may be set to get the minimum vs. expected latency. Minimum -/// latency is used for scheduling groups, while expected latency is for -/// instruction cost and critical path. -/// -/// For most subtargets, we don't need DefIdx or UseIdx to compute min latency. -/// DefMI must be a valid definition, but UseMI may be NULL for an unknown use. -unsigned TargetInstrInfo:: -computeOperandLatency(const InstrItineraryData *ItinData, - const TargetRegisterInfo *TRI, - const MachineInstr *DefMI, const MachineInstr *UseMI, - unsigned Reg, bool FindMin) const { +/// If we can determine the operand latency from the def only, without itinerary +/// lookup, do so. Otherwise return -1. +static int computeDefOperandLatency( + const TargetInstrInfo *TII, const InstrItineraryData *ItinData, + const MachineInstr *DefMI, bool FindMin) { - // Default to one cycle for missing itinerary. Empty itineraries still have - // a properties. We have one hard-coded exception for loads, to preserve - // existing behavior. + // Let the target hook getInstrLatency handle missing itineraries. if (!ItinData) - return DefMI->mayLoad() ? 2 : 1; + return TII->getInstrLatency(ItinData, DefMI); // Return a latency based on the itinerary properties and defining instruction // if possible. Some common subtargets don't require per-operand latency, @@ -113,7 +100,7 @@ computeOperandLatency(const InstrItineraryData *ItinData, // If MinLatency is valid, call getInstrLatency. This uses Stage latency if // it exists before defaulting to MinLatency. if (ItinData->Props.MinLatency >= 0) - return getInstrLatency(ItinData, DefMI); + return TII->getInstrLatency(ItinData, DefMI); // If MinLatency is invalid, OperandLatency is interpreted as MinLatency. // For empty itineraries, short-cirtuit the check and default to one cycle. @@ -121,9 +108,63 @@ computeOperandLatency(const InstrItineraryData *ItinData, return 1; } else if(ItinData->isEmpty()) - return defaultDefLatency(ItinData, DefMI); + return TII->defaultDefLatency(ItinData, DefMI); // ...operand lookup required +return -1; +} + +/// computeOperandLatency - Compute and return the latency of the given data +/// dependent def and use when the operand indices are already known. +/// +/// FindMin may be set to get the minimum vs. expected latency. +unsigned TargetInstrInfo:: +computeOperandLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, unsigned DefIdx, + const MachineInstr *UseMI, unsigned UseIdx, + bool FindMin) const { + + int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin); + if (DefLatency >= 0) + return DefLatency; + + assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail"); + + int OperLatency = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx); + if (OperLatency >= 0) + return OperLatency; + + // No operand latency was found. + unsigned InstrLatency = getInstrLatency(ItinData, DefMI); + + // Expected latency is the max of the stage latency and itinerary props. + if (!FindMin) + InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI)); + return InstrLatency; +} + +/// computeOperandLatency - Compute and return the latency of the given data +/// dependent def and use. DefMI must be a valid def. UseMI may be NULL for an +/// unknown use. Depending on the subtarget's itinerary properties, this may or +/// may not need to call getOperandLatency(). +/// +/// FindMin may be set to get the minimum vs. expected latency. Minimum +/// latency is used for scheduling groups, while expected latency is for +/// instruction cost and critical path. +/// +/// For most subtargets, we don't need DefIdx or UseIdx to compute min latency. +/// DefMI must be a valid definition, but UseMI may be NULL for an unknown use. +unsigned TargetInstrInfo:: +computeOperandLatency(const InstrItineraryData *ItinData, + const TargetRegisterInfo *TRI, + const MachineInstr *DefMI, const MachineInstr *UseMI, + unsigned Reg, bool FindMin) const { + + int DefLatency = computeDefOperandLatency(this, ItinData, DefMI, FindMin); + if (DefLatency >= 0) + return DefLatency; + + assert(ItinData && !ItinData->isEmpty() && "computeDefOperandLatency fail"); // Find the definition of the register in the defining instruction. int DefIdx = DefMI->findRegisterDefOperandIdx(Reg); @@ -168,6 +209,7 @@ computeOperandLatency(const InstrItineraryData *ItinData, } // No operand latency was found. unsigned InstrLatency = getInstrLatency(ItinData, DefMI); + // Expected latency is the max of the stage latency and itinerary props. if (!FindMin) InstrLatency = std::max(InstrLatency, defaultDefLatency(ItinData, DefMI)); @@ -180,7 +222,7 @@ unsigned TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, // Default to one cycle for no itinerary. However, an "empty" itinerary may // still have a MinLatency property, which getStageLatency checks. if (!ItinData) - return 1; + return MI->mayLoad() ? 2 : 1; return ItinData->getStageLatency(MI->getDesc().getSchedClass()); } |