diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCInstrInfo.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 9bac91d..daf8790 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -75,7 +75,7 @@ PPCInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 || Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) { const InstrItineraryData *II = - &static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData(); + static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData(); return new ScoreboardHazardRecognizer(II, DAG); } @@ -331,6 +331,11 @@ void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, BuildMI(MBB, MI, DL, get(Opcode)); } +/// getNoopForMachoTarget - Return the noop instruction to use for a noop. +void PPCInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { + NopInst.setOpcode(PPC::NOP); +} + // Branch analysis. // Note: If the condition register is set to CTR or CTR8 then this is a // BDNZ (imm == 1) or BDZ (imm == 0) branch. @@ -1617,6 +1622,7 @@ protected: bool Changed = false; MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); + const TargetRegisterInfo *TRI = &TII->getRegisterInfo(); for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end(); I != IE; ++I) { MachineInstr *MI = I; @@ -1682,16 +1688,26 @@ protected: // In theory, there could be other uses of the addend copy before this // fma. We could deal with this, but that would require additional // logic below and I suspect it will not occur in any relevant - // situations. - bool OtherUsers = false; + // situations. Additionally, check whether the copy source is killed + // prior to the fma. In order to replace the addend here with the + // source of the copy, it must still be live here. We can't use + // interval testing for a physical register, so as long as we're + // walking the MIs we may as well test liveness here. + bool OtherUsers = false, KillsAddendSrc = false; for (auto J = std::prev(I), JE = MachineBasicBlock::iterator(AddendMI); - J != JE; --J) + J != JE; --J) { if (J->readsVirtualRegister(AddendMI->getOperand(0).getReg())) { OtherUsers = true; break; } + if (J->modifiesRegister(AddendSrcReg, TRI) || + J->killsRegister(AddendSrcReg, TRI)) { + KillsAddendSrc = true; + break; + } + } - if (OtherUsers) + if (OtherUsers || KillsAddendSrc) continue; // Find one of the product operands that is killed by this instruction. @@ -1712,10 +1728,11 @@ protected: if (!KilledProdOp) continue; - // In order to replace the addend here with the source of the copy, - // it must still be live here. - if (!LIS->getInterval(AddendMI->getOperand(1).getReg()).liveAt(FMAIdx)) - continue; + // For virtual registers, verify that the addend source register + // is live here (as should have been assured above). + assert((!TargetRegisterInfo::isVirtualRegister(AddendSrcReg) || + LIS->getInterval(AddendSrcReg).liveAt(FMAIdx)) && + "Addend source register is not live!"); // Transform: (O2 * O3) + O1 -> (O2 * O1) + O3. @@ -1737,6 +1754,12 @@ protected: unsigned OldFMAReg = MI->getOperand(0).getReg(); + // The transformation doesn't work well with things like: + // %vreg5 = A-form-op %vreg5, %vreg11, %vreg5; + // so leave such things alone. + if (OldFMAReg == KilledProdReg) + continue; + assert(OldFMAReg == AddendMI->getOperand(0).getReg() && "Addend copy not tied to old FMA output!"); @@ -1827,7 +1850,7 @@ public: LIS = &getAnalysis<LiveIntervals>(); - TII = TM->getInstrInfo(); + TII = TM->getSubtargetImpl()->getInstrInfo(); bool Changed = false; @@ -1980,7 +2003,7 @@ public: // If we don't have VSX on the subtarget, don't do anything. if (!TM->getSubtargetImpl()->hasVSX()) return false; - TII = TM->getInstrInfo(); + TII = TM->getSubtargetImpl()->getInstrInfo(); bool Changed = false; @@ -2057,7 +2080,7 @@ public: // If we don't have VSX don't bother doing anything here. if (!TM->getSubtargetImpl()->hasVSX()) return false; - TII = TM->getInstrInfo(); + TII = TM->getSubtargetImpl()->getInstrInfo(); bool Changed = false; @@ -2214,7 +2237,7 @@ protected: public: bool runOnMachineFunction(MachineFunction &MF) override { TM = static_cast<const PPCTargetMachine *>(&MF.getTarget()); - TII = TM->getInstrInfo(); + TII = TM->getSubtargetImpl()->getInstrInfo(); bool Changed = false; |