ARM scheduler model: Swift has varying latencies, uops for simple ALU ops

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178842 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Arnold Schwaighofer 2013-04-05 04:42:00 +00:00
parent d4d7613af3
commit 08da486557
4 changed files with 57 additions and 5 deletions

View 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;
}

View 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

View File

@ -71,6 +71,8 @@ def : PredicateProlog<[{
(void)TII;
}]>;
def IsPredicatedPred : SchedPredicate<[{TII->isPredicated(MI)}]>;
//===----------------------------------------------------------------------===//
// Instruction Itinerary classes used for ARM
//

View 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>;
}