llvm.org GIT mirror llvm / 3ef1c87
Teach if-converter to be more careful with predicating instructions that would take multiple cycles to decode. For the current if-converter clients (actually only ARM), the instructions that are predicated on false are not nops. They would still take machine cycles to decode. Micro-coded instructions such as LDM / STM can potentially take multiple cycles to decode. If-converter should take treat them as non-micro-coded simple instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113570 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
28 changed file(s) with 164 addition(s) and 84 deletion(s). Raw diff Collapse all Expand all
7474 };
7575
7676 // Itinerary data for the target.
77 const InstrItineraryData &ItinData;
77 const InstrItineraryData *ItinData;
7878
7979 ScoreBoard ReservedScoreboard;
8080 ScoreBoard RequiredScoreboard;
8181
8282 public:
83 PostRAHazardRecognizer(const InstrItineraryData &ItinData);
83 PostRAHazardRecognizer(const InstrItineraryData *ItinData);
8484
8585 virtual HazardType getHazardType(SUnit *SU);
8686 virtual void Reset();
574574 /// to use for this target when scheduling the machine instructions after
575575 /// register allocation.
576576 virtual ScheduleHazardRecognizer*
577 CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const = 0;
577 CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const = 0;
578578
579579 /// AnalyzeCompare - For a comparison instruction, return the source register
580580 /// in SrcReg and the value it compares against in CmpValue. Return true if
594594 /// getNumMicroOps - Return the number of u-operations the given machine
595595 /// instruction will be decoded to on the target cpu.
596596 virtual unsigned getNumMicroOps(const MachineInstr *MI,
597 const InstrItineraryData &ItinData) const;
597 const InstrItineraryData *ItinData) const;
598598 };
599599
600600 /// TargetInstrInfoImpl - This is the default implementation of
630630 const MachineFunction &MF) const;
631631
632632 virtual ScheduleHazardRecognizer *
633 CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const;
633 CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const;
634634 };
635635
636636 } // End llvm namespace
180180
181181 return (int)OperandCycles[FirstIdx + OperandIdx];
182182 }
183
184 /// isMicroCoded - Return true if the instructions in the given class decode
185 /// to more than one micro-ops.
186 bool isMicroCoded(unsigned ItinClassIndx) const {
187 if (isEmpty())
188 return false;
189 return Itineratries[ItinClassIndx].NumMicroOps != 1;
190 }
183191 };
184192
185193
151151 /// getInstrItineraryData - Returns instruction itinerary data for the target
152152 /// or specific subtarget.
153153 ///
154 virtual const InstrItineraryData getInstrItineraryData() const {
155 return InstrItineraryData();
154 virtual const InstrItineraryData *getInstrItineraryData() const {
155 return 0;
156156 }
157157
158158 /// getELFWriterInfo - If this target supports an ELF writer, return
1717 #include "llvm/CodeGen/MachineModuleInfo.h"
1818 #include "llvm/CodeGen/MachineFunctionPass.h"
1919 #include "llvm/Target/TargetInstrInfo.h"
20 #include "llvm/Target/TargetInstrItineraries.h"
2021 #include "llvm/Target/TargetLowering.h"
2122 #include "llvm/Target/TargetMachine.h"
2223 #include "llvm/Target/TargetRegisterInfo.h"
149150 const TargetLowering *TLI;
150151 const TargetInstrInfo *TII;
151152 const TargetRegisterInfo *TRI;
153 const InstrItineraryData *InstrItins;
152154 bool MadeChange;
153155 int FnNum;
154156 public:
237239 TLI = MF.getTarget().getTargetLowering();
238240 TII = MF.getTarget().getInstrInfo();
239241 TRI = MF.getTarget().getRegisterInfo();
242 InstrItins = MF.getTarget().getInstrItineraryData();
240243 if (!TII) return false;
241244
242245 // Tail merge tend to expose more if-conversion opportunities.
640643 bool isCondBr = BBI.IsBrAnalyzable && TID.isConditionalBranch();
641644
642645 if (!isCondBr) {
643 if (!isPredicated)
644 BBI.NonPredSize++;
645 else if (!AlreadyPredicated) {
646 if (!isPredicated) {
647 unsigned NumOps = TII->getNumMicroOps(&*I, InstrItins);
648 BBI.NonPredSize += NumOps;
649 } else if (!AlreadyPredicated) {
646650 // FIXME: This instruction is already predicated before the
647651 // if-conversion pass. It's probably something like a conditional move.
648652 // Mark this block unpredicable for now.
13631367
13641368 MachineInstr *MI = MF.CloneMachineInstr(I);
13651369 ToBBI.BB->insert(ToBBI.BB->end(), MI);
1366 ToBBI.NonPredSize++;
1370 unsigned NumOps = TII->getNumMicroOps(MI, InstrItins);
1371 ToBBI.NonPredSize += NumOps;
13671372
13681373 if (!TII->isPredicated(I) && !MI->isDebugValue()) {
13691374 if (!TII->PredicateInstruction(MI, Cond)) {
2222 using namespace llvm;
2323
2424 PostRAHazardRecognizer::
25 PostRAHazardRecognizer(const InstrItineraryData &LItinData) :
25 PostRAHazardRecognizer(const InstrItineraryData *LItinData) :
2626 ScheduleHazardRecognizer(), ItinData(LItinData) {
2727 // Determine the maximum depth of any itinerary. This determines the
2828 // depth of the scoreboard. We always make the scoreboard at least 1
2929 // cycle deep to avoid dealing with the boundary condition.
3030 unsigned ScoreboardDepth = 1;
31 if (!ItinData.isEmpty()) {
31 if (ItinData && !ItinData->isEmpty()) {
3232 for (unsigned idx = 0; ; ++idx) {
33 if (ItinData.isEndMarker(idx))
33 if (ItinData->isEndMarker(idx))
3434 break;
3535
36 const InstrStage *IS = ItinData.beginStage(idx);
37 const InstrStage *E = ItinData.endStage(idx);
36 const InstrStage *IS = ItinData->beginStage(idx);
37 const InstrStage *E = ItinData->endStage(idx);
3838 unsigned ItinDepth = 0;
3939 for (; IS != E; ++IS)
4040 ItinDepth += IS->getCycles();
7373
7474 ScheduleHazardRecognizer::HazardType
7575 PostRAHazardRecognizer::getHazardType(SUnit *SU) {
76 if (ItinData.isEmpty())
76 if (!ItinData || ItinData->isEmpty())
7777 return NoHazard;
7878
7979 unsigned cycle = 0;
8181 // Use the itinerary for the underlying instruction to check for
8282 // free FU's in the scoreboard at the appropriate future cycles.
8383 unsigned idx = SU->getInstr()->getDesc().getSchedClass();
84 for (const InstrStage *IS = ItinData.beginStage(idx),
85 *E = ItinData.endStage(idx); IS != E; ++IS) {
84 for (const InstrStage *IS = ItinData->beginStage(idx),
85 *E = ItinData->endStage(idx); IS != E; ++IS) {
8686 // We must find one of the stage's units free for every cycle the
8787 // stage is occupied. FIXME it would be more accurate to find the
8888 // same unit free in all the cycles.
120120 }
121121
122122 void PostRAHazardRecognizer::EmitInstruction(SUnit *SU) {
123 if (ItinData.isEmpty())
123 if (!ItinData || ItinData->isEmpty())
124124 return;
125125
126126 unsigned cycle = 0;
128128 // Use the itinerary for the underlying instruction to reserve FU's
129129 // in the scoreboard at the appropriate future cycles.
130130 unsigned idx = SU->getInstr()->getDesc().getSchedClass();
131 for (const InstrStage *IS = ItinData.beginStage(idx),
132 *E = ItinData.endStage(idx); IS != E; ++IS) {
131 for (const InstrStage *IS = ItinData->beginStage(idx),
132 *E = ItinData->endStage(idx); IS != E; ++IS) {
133133 // We must reserve one of the stage's units for every cycle the
134134 // stage is occupied. FIXME it would be more accurate to reserve
135135 // the same unit free in all the cycles.
212212 const MachineLoopInfo &MLI = getAnalysis();
213213 const MachineDominatorTree &MDT = getAnalysis();
214214 const TargetMachine &TM = Fn.getTarget();
215 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
215 const InstrItineraryData *InstrItins = TM.getInstrItineraryData();
216216 ScheduleHazardRecognizer *HR =
217217 TM.getInstrInfo()->CreateTargetPostRAHazardRecognizer(InstrItins);
218218 AntiDepBreaker *ADB =
3131 ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
3232 const MachineLoopInfo &mli,
3333 const MachineDominatorTree &mdt)
34 : ScheduleDAG(mf), MLI(mli), MDT(mdt), Defs(TRI->getNumRegs()),
35 Uses(TRI->getNumRegs()), LoopRegs(MLI, MDT) {
36 MFI = mf.getFrameInfo();
34 : ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()),
35 InstrItins(mf.getTarget().getInstrItineraryData()),
36 Defs(TRI->getNumRegs()), Uses(TRI->getNumRegs()), LoopRegs(MLI, MDT) {
3737 DbgValueVec.clear();
3838 }
3939
497497 }
498498
499499 void ScheduleDAGInstrs::ComputeLatency(SUnit *SU) {
500 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
501
502500 // Compute the latency for the node.
503 SU->Latency =
504 InstrItins.getStageLatency(SU->getInstr()->getDesc().getSchedClass());
505
506 // Simplistic target-independent heuristic: assume that loads take
507 // extra time.
508 if (InstrItins.isEmpty())
501 if (!InstrItins || InstrItins->isEmpty()) {
502 SU->Latency = 1;
503
504 // Simplistic target-independent heuristic: assume that loads take
505 // extra time.
509506 if (SU->getInstr()->getDesc().mayLoad())
510507 SU->Latency += 2;
508 } else
509 SU->Latency =
510 InstrItins->getStageLatency(SU->getInstr()->getDesc().getSchedClass());
511511 }
512512
513513 void ScheduleDAGInstrs::ComputeOperandLatency(SUnit *Def, SUnit *Use,
514514 SDep& dep) const {
515 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
516 if (InstrItins.isEmpty())
515 if (!InstrItins || InstrItins->isEmpty())
517516 return;
518517
519518 // For a data dependency with a known register...
527526 MachineInstr *DefMI = Def->getInstr();
528527 int DefIdx = DefMI->findRegisterDefOperandIdx(Reg);
529528 if (DefIdx != -1) {
530 int DefCycle = InstrItins.getOperandCycle(DefMI->getDesc().getSchedClass(),
531 DefIdx);
529 int DefCycle = InstrItins->getOperandCycle(DefMI->getDesc().getSchedClass(),
530 DefIdx);
532531 if (DefCycle >= 0) {
533532 MachineInstr *UseMI = Use->getInstr();
534533 const unsigned UseClass = UseMI->getDesc().getSchedClass();
543542 if (MOReg != Reg)
544543 continue;
545544
546 int UseCycle = InstrItins.getOperandCycle(UseClass, i);
545 int UseCycle = InstrItins->getOperandCycle(UseClass, i);
547546 if (UseCycle >= 0)
548547 Latency = std::max(Latency, DefCycle - UseCycle + 1);
549548 }
100100 const MachineLoopInfo &MLI;
101101 const MachineDominatorTree &MDT;
102102 const MachineFrameInfo *MFI;
103 const InstrItineraryData *InstrItins;
103104
104105 /// Defs, Uses - Remember where defs and uses of each physical register
105106 /// are as we iterate upward through the instructions. This is allocated
3333 STATISTIC(LoadsClustered, "Number of loads clustered together");
3434
3535 ScheduleDAGSDNodes::ScheduleDAGSDNodes(MachineFunction &mf)
36 : ScheduleDAG(mf) {
37 }
36 : ScheduleDAG(mf),
37 InstrItins(mf.getTarget().getInstrItineraryData()) {}
3838
3939 /// Run - perform scheduling.
4040 ///
428428 return;
429429 }
430430
431 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
432 if (InstrItins.isEmpty()) {
431 if (!InstrItins || InstrItins->isEmpty()) {
433432 SU->Latency = 1;
434433 return;
435434 }
439438 SU->Latency = 0;
440439 for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
441440 if (N->isMachineOpcode()) {
442 SU->Latency += InstrItins.
441 SU->Latency += InstrItins->
443442 getStageLatency(TII->get(N->getMachineOpcode()).getSchedClass());
444443 }
445444 }
450449 if (ForceUnitLatencies())
451450 return;
452451
453 const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
454 if (InstrItins.isEmpty())
452 if (!InstrItins || InstrItins->isEmpty())
455453 return;
456454
457455 if (dep.getKind() != SDep::Data)
462460 const TargetInstrDesc &II = TII->get(Def->getMachineOpcode());
463461 if (DefIdx >= II.getNumDefs())
464462 return;
465 int DefCycle = InstrItins.getOperandCycle(II.getSchedClass(), DefIdx);
463 int DefCycle = InstrItins->getOperandCycle(II.getSchedClass(), DefIdx);
466464 if (DefCycle < 0)
467465 return;
468466 int UseCycle = 1;
469467 if (Use->isMachineOpcode()) {
470468 const unsigned UseClass = TII->get(Use->getMachineOpcode()).getSchedClass();
471 UseCycle = InstrItins.getOperandCycle(UseClass, OpIdx);
469 UseCycle = InstrItins->getOperandCycle(UseClass, OpIdx);
472470 }
473471 if (UseCycle >= 0) {
474472 int Latency = DefCycle - UseCycle + 1;
3535 class ScheduleDAGSDNodes : public ScheduleDAG {
3636 public:
3737 SelectionDAG *DAG; // DAG of the current basic block
38 const InstrItineraryData *InstrItins;
3839
3940 explicit ScheduleDAGSDNodes(MachineFunction &mf);
4041
415415
416416 // Default implementation of CreateTargetPostRAHazardRecognizer.
417417 ScheduleHazardRecognizer *TargetInstrInfoImpl::
418 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
418 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const {
419419 return (ScheduleHazardRecognizer *)new PostRAHazardRecognizer(II);
420420 }
9090
9191 include "ARMSchedule.td"
9292
93 // ARM processor families.
94 def ProcOthers : SubtargetFeature<"others", "ARMProcFamily", "Others",
95 "One of the other ARM processor families">;
96 def ProcA8 : SubtargetFeature<"a8", "ARMProcFamily", "CortexA8",
97 "Cortex-A8 ARM processors",
98 [FeatureSlowFPBrcc, FeatureNEONForFP]>;
99 def ProcA9 : SubtargetFeature<"a9", "ARMProcFamily", "CortexA9",
100 "Cortex-A9 ARM processors">;
101
93102 class ProcNoItin Features>
94103 : Processor;
95104
149158
150159 // V7 Processors.
151160 def : Processor<"cortex-a8", CortexA8Itineraries,
152 [ArchV7A, FeatureHasSlowVMLx,
153 FeatureSlowFPBrcc, FeatureNEONForFP, FeatureT2XtPk]>;
161 [ArchV7A, ProcA8,
162 FeatureHasSlowVMLx, FeatureT2XtPk]>;
154163 def : Processor<"cortex-a9", CortexA9Itineraries,
155 [ArchV7A, FeatureT2XtPk]>;
164 [ArchV7A, ProcA9, FeatureT2XtPk]>;
156165
157166 // V7M Processors.
158167 def : ProcNoItin<"cortex-m3", [ArchV7M]>;
14141414
14151415 unsigned
14161416 ARMBaseInstrInfo::getNumMicroOps(const MachineInstr *MI,
1417 const InstrItineraryData &ItinData) const {
1418 if (ItinData.isEmpty())
1417 const InstrItineraryData *ItinData) const {
1418 if (!ItinData || ItinData->isEmpty())
14191419 return 1;
14201420
14211421 const TargetInstrDesc &Desc = MI->getDesc();
14221422 unsigned Class = Desc.getSchedClass();
1423 unsigned UOps = ItinData.Itineratries[Class].NumMicroOps;
1423 unsigned UOps = ItinData->Itineratries[Class].NumMicroOps;
14241424 if (UOps)
14251425 return UOps;
14261426
14291429 default:
14301430 llvm_unreachable("Unexpected multi-uops instruction!");
14311431 break;
1432 case ARM::VLDMQ:
14321433 case ARM::VSTMQ:
14331434 return 2;
14341435
14351436 // The number of uOps for load / store multiple are determined by the number
14361437 // registers.
1437 // On Cortex-A8, each odd / even pair of register loads / stores
1438 // (e.g. r5 + r6) can be completed on the same cycle. The minimum is
1439 // 2. For VFP / NEON load / store multiple, the formula is
1438 // On Cortex-A8, each pair of register loads / stores can be scheduled on the
1439 // same cycle. The scheduling for the first load / store must be done
1440 // separately by assuming the the address is not 64-bit aligned.
1441 // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2). If the address
1442 // is not 64-bit aligned, then AGU would take an extra cycle.
1443 // For VFP / NEON load / store multiple, the formula is
14401444 // (#reg / 2) + (#reg % 2) + 1.
1441 // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2).
14421445 case ARM::VLDMD:
14431446 case ARM::VLDMS:
14441447 case ARM::VLDMD_UPD:
14661469 case ARM::t2LDM_UPD:
14671470 case ARM::t2STM:
14681471 case ARM::t2STM_UPD: {
1469 // FIXME: Distinquish between Cortex-A8 / Cortex-A9 and other processor
1470 // families.
1471 unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
1472 UOps = (NumRegs / 2) + (NumRegs % 2);
1473 return (UOps > 2) ? UOps : 2;
1474 }
1475 }
1476 }
1472 unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands() + 1;
1473 if (Subtarget.isCortexA8()) {
1474 // 4 registers would be issued: 1, 2, 1.
1475 // 5 registers would be issued: 1, 2, 2.
1476 return 1 + (NumRegs / 2);
1477 } else if (Subtarget.isCortexA9()) {
1478 UOps = (NumRegs / 2);
1479 // If there are odd number of registers or if it's not 64-bit aligned,
1480 // then it takes an extra AGU (Address Generation Unit) cycle.
1481 if ((NumRegs % 2) ||
1482 !MI->hasOneMemOperand() ||
1483 (*MI->memoperands_begin())->getAlignment() < 8)
1484 ++UOps;
1485 return UOps;
1486 } else {
1487 // Assume the worst.
1488 return NumRegs;
1489 }
1490 }
1491 }
1492 }
349349 MachineInstr *CmpInstr) const;
350350
351351 virtual unsigned getNumMicroOps(const MachineInstr *MI,
352 const InstrItineraryData &ItinData) const;
352 const InstrItineraryData *ItinData) const;
353353 };
354354
355355 static inline
176176 : TargetLowering(TM, createTLOF(TM)) {
177177 Subtarget = &TM.getSubtarget();
178178 RegInfo = TM.getRegisterInfo();
179 Itins = TM.getInstrItineraryData();
179180
180181 if (Subtarget->isTargetDarwin()) {
181182 // Uses VFP for Thumb libfuncs if available.
748749 if (TID.mayLoad())
749750 return Sched::Latency;
750751
751 const InstrItineraryData &Itins = getTargetMachine().getInstrItineraryData();
752 if (!Itins.isEmpty() && Itins.getStageLatency(TID.getSchedClass()) > 2)
752 if (!Itins->isEmpty() && Itins->getStageLatency(TID.getSchedClass()) > 2)
753753 return Sched::Latency;
754754 return Sched::RegPressure;
755755 }
299299 const ARMSubtarget *Subtarget;
300300
301301 const TargetRegisterInfo *RegInfo;
302
303 const InstrItineraryData *Itins;
302304
303305 /// ARMPCLabelIndex - Keep track of the number of ARM PC labels created.
304306 ///
2929 ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
3030 bool isT)
3131 : ARMArchVersion(V4)
32 , ARMProcFamily(Others)
3233 , ARMFPUType(None)
3334 , UseNEONForSinglePrecisionFP(false)
3435 , SlowVMLx(false)
4950 , CPUString("generic")
5051 , TargetType(isELF) // Default to ELF unless otherwise specified.
5152 , TargetABI(ARM_ABI_APCS) {
52 // default to soft float ABI
53 // Default to soft float ABI
5354 if (FloatABIType == FloatABI::Default)
5455 FloatABIType = FloatABI::Soft;
5556
2828 V4, V4T, V5T, V5TE, V6, V6M, V6T2, V7A, V7M
2929 };
3030
31 enum ARMProcFamilyEnum {
32 Others, CortexA8, CortexA9
33 };
34
3135 enum ARMFPEnum {
3236 None, VFPv2, VFPv3, NEON
3337 };
4044 /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
4145 /// V6, V6T2, V7A, V7M.
4246 ARMArchEnum ARMArchVersion;
47
48 /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others.
49 ARMProcFamilyEnum ARMProcFamily;
4350
4451 /// ARMFPUType - Floating Point Unit type.
4552 ARMFPEnum ARMFPUType;
141148 bool hasV6Ops() const { return ARMArchVersion >= V6; }
142149 bool hasV6T2Ops() const { return ARMArchVersion >= V6T2; }
143150 bool hasV7Ops() const { return ARMArchVersion >= V7A; }
151
152 bool isCortexA8() const { return ARMProcFamily == CortexA8; }
153 bool isCortexA9() const { return ARMProcFamily == CortexA9; }
144154
145155 bool hasARMOps() const { return !NoARM; }
146156
4444 virtual const ARMFrameInfo *getFrameInfo() const { return &FrameInfo; }
4545 virtual ARMJITInfo *getJITInfo() { return &JITInfo; }
4646 virtual const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; }
47 virtual const InstrItineraryData getInstrItineraryData() const {
48 return InstrItins;
47 virtual const InstrItineraryData *getInstrItineraryData() const {
48 return &InstrItins;
4949 }
5050
5151 // Pass Pipeline Configuration
2525 MachineInstr *ITBlockMIs[4];
2626
2727 public:
28 Thumb2HazardRecognizer(const InstrItineraryData &ItinData) :
28 Thumb2HazardRecognizer(const InstrItineraryData *ItinData) :
2929 PostRAHazardRecognizer(ItinData) {}
3030
3131 virtual HazardType getHazardType(SUnit *SU);
193193 }
194194
195195 ScheduleHazardRecognizer *Thumb2InstrInfo::
196 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
196 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const {
197197 return (ScheduleHazardRecognizer *)new Thumb2HazardRecognizer(II);
198198 }
199199
7171 const Thumb2RegisterInfo &getRegisterInfo() const { return RI; }
7272
7373 ScheduleHazardRecognizer *
74 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const;
74 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II) const;
7575 };
7676
7777 /// getITInstrPredicate - Valid only in Thumb2 mode. This function is identical
7474 return &DataLayout;
7575 }
7676
77 virtual const InstrItineraryData getInstrItineraryData() const {
78 return InstrItins;
77 virtual const InstrItineraryData *getInstrItineraryData() const {
78 return &InstrItins;
7979 }
8080
8181 // Pass Pipeline Configuration
5757
5858 virtual const TargetData *getTargetData() const { return &DataLayout; }
5959 virtual const PPCSubtarget *getSubtargetImpl() const { return &Subtarget; }
60 virtual const InstrItineraryData getInstrItineraryData() const {
61 return InstrItins;
60 virtual const InstrItineraryData *getInstrItineraryData() const {
61 return &InstrItins;
6262 }
6363
6464 // Pass Pipeline Configuration
4949
5050 unsigned
5151 TargetInstrInfo::getNumMicroOps(const MachineInstr *MI,
52 const InstrItineraryData &ItinData) const {
53 if (ItinData.isEmpty())
52 const InstrItineraryData *ItinData) const {
53 if (!ItinData || ItinData->isEmpty())
5454 return 1;
5555
5656 unsigned Class = MI->getDesc().getSchedClass();
57 unsigned UOps = ItinData.Itineratries[Class].NumMicroOps;
57 unsigned UOps = ItinData->Itineratries[Class].NumMicroOps;
5858 if (UOps)
5959 return UOps;
6060
0 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s
1 ; rdar://8402126
2 ; Make sure if-converter is not predicating vldmia and ldmia. These are
3 ; micro-coded and would have long issue latency even if predicated on
4 ; false predicate.
5
6 %0 = type { float, float, float, float }
7 %pln = type { %vec, float }
8 %vec = type { [4 x float] }
9
10 define arm_aapcs_vfpcc float @aaa(%vec* nocapture %ustart, %vec* nocapture %udir, %vec* nocapture %vstart, %vec* nocapture %vdir, %vec* %upoint, %vec* %vpoint) {
11 ; CHECK: aaa:
12 ; CHECK: vldr.32
13 ; CHECK-NOT: vldrne
14 ; CHECK-NOT: vldmiane
15 ; CHECK-NOT: ldmiane
16 ; CHECK: vldmia sp!
17 ; CHECK: ldmia sp!
18 entry:
19 br i1 undef, label %bb81, label %bb48
20
21 bb48: ; preds = %entry
22 %0 = call arm_aapcs_vfpcc %0 @bbb(%pln* undef, %vec* %vstart, %vec* undef) nounwind ; <%0> [#uses=0]
23 ret float 0.000000e+00
24
25 bb81: ; preds = %entry
26 ret float 0.000000e+00
27 }
28
29 declare arm_aapcs_vfpcc %0 @bbb(%pln* nocapture, %vec* nocapture, %vec* nocapture) nounwind
None ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -O3 -relocation-model=pic -mcpu=cortex-a8 | FileCheck %s
0 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -O3 -relocation-model=pic | FileCheck %s
11 ; rdar://8115404
22 ; Tail merging must not split an IT block.
33