ARM scheduler model: Swift has varying latencies, uops for simple ALU ops
authorArnold Schwaighofer <aschwaighofer@apple.com>
Fri, 5 Apr 2013 04:42:00 +0000 (04:42 +0000)
committerArnold Schwaighofer <aschwaighofer@apple.com>
Fri, 5 Apr 2013 04:42:00 +0000 (04:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178842 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMBaseInstrInfo.h
lib/Target/ARM/ARMSchedule.td
lib/Target/ARM/ARMScheduleSwift.td

index 126f160f6dede6e6fe9240ce56c31e204c2d9ab5..9e68ff44890e1d9cb455eb8a2ca22617f95071bb 100644 (file)
@@ -4123,3 +4123,15 @@ breakPartialRegDependency(MachineBasicBlock::iterator MI,
 bool ARMBaseInstrInfo::hasNOP() const {
   return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
 }
+
+bool ARMBaseInstrInfo::isSwiftFastImmShift(const MachineInstr *MI) const {
+  unsigned ShOpVal = MI->getOperand(3).getImm();
+  unsigned ShImm = ARM_AM::getSORegOffset(ShOpVal);
+  // Swift supports faster shifts for: lsl 2, lsl 1, and lsr 1.
+  if ((ShImm == 1 && ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsr) ||
+      ((ShImm == 1 || ShImm == 2) &&
+       ARM_AM::getSORegShOp(ShOpVal) == ARM_AM::lsl))
+    return true;
+
+  return false;
+}
index 2698132d2d57bf938e478bf505e7a141878433ce..7c107bb419512e0ddd84de1bd2c350dda3854e97 100644 (file)
@@ -314,6 +314,10 @@ public:
   bool canCauseFpMLxStall(unsigned Opcode) const {
     return MLxHazardOpcodes.count(Opcode);
   }
+
+  /// Returns true if the instruction has a shift by immediate that can be
+  /// executed in one cycle less.
+  bool isSwiftFastImmShift(const MachineInstr *MI) const;
 };
 
 static inline
index 7eb5ff665a6efe8bf17213ea59f6063df6655f8a..136a90aa95cea5be7eb600be041b8771ca4b3225 100644 (file)
@@ -71,6 +71,8 @@ def : PredicateProlog<[{
   (void)TII;
 }]>;
 
+def IsPredicatedPred : SchedPredicate<[{TII->isPredicated(MI)}]>;
+
 //===----------------------------------------------------------------------===//
 // Instruction Itinerary classes used for ARM
 //
index 28bb429feb0b81575a0c49ace9503c790866a5cf..4a87faaac03a495049e678bddb806084e5bee371 100644 (file)
@@ -1083,6 +1083,9 @@ def SwiftModel : SchedMachineModel {
   let Itineraries = SwiftItineraries;
 }
 
+// Swift predicates.
+def IsFastImmShiftSwiftPred : SchedPredicate<[{TII->isSwiftFastImmShift(MI)}]>;
+
 // Swift resource mapping.
 let SchedModel = SwiftModel in {
   // Processor resources.
@@ -1092,15 +1095,46 @@ let SchedModel = SwiftModel in {
   def SwiftUnitP2 : ProcResource<1>; // LS unit.
   def SwiftUnitDiv : ProcResource<1>;
 
+  // Generic resource requirements.
+  def SwiftWriteP01TwoCycle : SchedWriteRes<[SwiftUnitP01]> { let Latency = 2; }
+  def SwiftWriteP01ThreeCycleTwoUops :
+    SchedWriteRes<[SwiftUnitP01, SwiftUnitP01]> {
+    let Latency = 3;
+    let NumMicroOps = 2;
+  }
+  def SwiftWriteP0ThreeCycleThreeUops : SchedWriteRes<[SwiftUnitP0]> {
+    let Latency = 3;
+    let NumMicroOps = 3;
+    let ResourceCycles = [3];
+  }
+
   // 4.2.4 Arithmetic and Logical.
+  // ALU operation register shifted by immediate variant.
+  def SwiftWriteALUsi : SchedWriteVariant<[
+    // lsl #2, lsl #1, or lsr #1.
+    SchedVar<IsFastImmShiftSwiftPred, [SwiftWriteP01TwoCycle]>,
+    // Arbitrary imm shift.
+    SchedVar<NoSchedPred,             [WriteALU]>
+  ]>;
+  def SwiftWriteALUsr : SchedWriteVariant<[
+    SchedVar<IsPredicatedPred, [SwiftWriteP01ThreeCycleTwoUops]>,
+    SchedVar<NoSchedPred, [SwiftWriteP01TwoCycle]>
+  ]>;
+  def SwiftWriteALUSsr : SchedWriteVariant<[
+    SchedVar<IsPredicatedPred, [SwiftWriteP0ThreeCycleThreeUops]>,
+    SchedVar<NoSchedPred, [SwiftWriteP01TwoCycle]>
+  ]>;
+  def SwiftReadAdvanceALUsr : SchedReadVariant<[
+    SchedVar<IsPredicatedPred, [SchedReadAdvance<2>]>,
+    SchedVar<NoSchedPred, [NoReadAdvance]>
+  ]>;
   // ADC,ADD,NEG,RSB,RSC,SBC,SUB,ADR
   // AND,BIC, EOR,ORN,ORR
   // CLZ,RBIT,REV,REV16,REVSH,PKH
-  // Single cycle.
   def : WriteRes<WriteALU, [SwiftUnitP01]>;
-  def : WriteRes<WriteALUsi, [SwiftUnitP01]>;
-  def : WriteRes<WriteALUsr, [SwiftUnitP01]>;
-  def : WriteRes<WriteALUSsr, [SwiftUnitP01]>;
+  def : SchedAlias<WriteALUsi, SwiftWriteALUsi>;
+  def : SchedAlias<WriteALUsr, SwiftWriteALUsr>;
+  def : SchedAlias<WriteALUSsr, SwiftWriteALUSsr>;
   def : ReadAdvance<ReadALU, 0>;
-  def : ReadAdvance<ReadALUsr, 2>;
+  def : SchedAlias<ReadALUsr, SwiftReadAdvanceALUsr>;
 }