PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
: PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
- Subtarget(STI), RI(STI) {}
+ Subtarget(STI), RI(STI.getTargetMachine()) {}
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
/// this target when scheduling the DAG.
const MachineOperand &DefMO = DefMI->getOperand(DefIdx);
unsigned Reg = DefMO.getReg();
- const TargetRegisterInfo *TRI = &getRegisterInfo();
bool IsRegCR;
- if (TRI->isVirtualRegister(Reg)) {
+ if (TargetRegisterInfo::isVirtualRegister(Reg)) {
const MachineRegisterInfo *MRI =
&DefMI->getParent()->getParent()->getRegInfo();
IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
case PPC::RESTORE_CRBIT:
case PPC::LVX:
case PPC::LXVD2X:
+ case PPC::QVLFDX:
+ case PPC::QVLFSXs:
+ case PPC::QVLFDXb:
case PPC::RESTORE_VRSAVE:
// Check for the operands added by addFrameReference (the immediate is the
// offset which defaults to 0).
case PPC::SPILL_CRBIT:
case PPC::STVX:
case PPC::STXVD2X:
+ case PPC::QVSTFDX:
+ case PPC::QVSTFSXs:
+ case PPC::QVSTFDXb:
case PPC::SPILL_VRSAVE:
// Check for the operands added by addFrameReference (the immediate is the
// offset which defaults to 0).
.addReg(Cond[1].getReg(), 0, SubIdx);
}
+static unsigned getCRBitValue(unsigned CRBit) {
+ unsigned Ret = 4;
+ if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
+ CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
+ CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
+ CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
+ Ret = 3;
+ if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
+ CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
+ CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
+ CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
+ Ret = 2;
+ if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
+ CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
+ CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
+ CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
+ Ret = 1;
+ if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
+ CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
+ CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
+ CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
+ Ret = 0;
+
+ assert(Ret != 4 && "Invalid CR bit register");
+ return Ret;
+}
+
void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
// legalization. Promote them here.
const TargetRegisterInfo *TRI = &getRegisterInfo();
if (PPC::F8RCRegClass.contains(DestReg) &&
- PPC::VSLRCRegClass.contains(SrcReg)) {
+ PPC::VSRCRegClass.contains(SrcReg)) {
unsigned SuperReg =
TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
DestReg = SuperReg;
} else if (PPC::VRRCRegClass.contains(DestReg) &&
- PPC::VSHRCRegClass.contains(SrcReg)) {
+ PPC::VSRCRegClass.contains(SrcReg)) {
unsigned SuperReg =
TRI->getMatchingSuperReg(DestReg, PPC::sub_128, &PPC::VSRCRegClass);
DestReg = SuperReg;
} else if (PPC::F8RCRegClass.contains(SrcReg) &&
- PPC::VSLRCRegClass.contains(DestReg)) {
+ PPC::VSRCRegClass.contains(DestReg)) {
unsigned SuperReg =
TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
SrcReg = SuperReg;
} else if (PPC::VRRCRegClass.contains(SrcReg) &&
- PPC::VSHRCRegClass.contains(DestReg)) {
+ PPC::VSRCRegClass.contains(DestReg)) {
unsigned SuperReg =
TRI->getMatchingSuperReg(SrcReg, PPC::sub_128, &PPC::VSRCRegClass);
SrcReg = SuperReg;
}
+ // Different class register copy
+ if (PPC::CRBITRCRegClass.contains(SrcReg) &&
+ PPC::GPRCRegClass.contains(DestReg)) {
+ unsigned CRReg = getCRFromCRBit(SrcReg);
+ BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)
+ .addReg(CRReg), getKillRegState(KillSrc);
+ // Rotate the CR bit in the CR fields to be the least significant bit and
+ // then mask with 0x1 (MB = ME = 31).
+ BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)
+ .addReg(DestReg, RegState::Kill)
+ .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))
+ .addImm(31)
+ .addImm(31);
+ return;
+ } else if (PPC::CRRCRegClass.contains(SrcReg) &&
+ PPC::G8RCRegClass.contains(DestReg)) {
+ BuildMI(MBB, I, DL, get(PPC::MFOCRF8), DestReg)
+ .addReg(SrcReg), getKillRegState(KillSrc);
+ return;
+ } else if (PPC::CRRCRegClass.contains(SrcReg) &&
+ PPC::GPRCRegClass.contains(DestReg)) {
+ BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg)
+ .addReg(SrcReg), getKillRegState(KillSrc);
+ return;
+ }
+
unsigned Opc;
if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
Opc = PPC::OR;
Opc = PPC::XXLOR;
else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg))
Opc = PPC::XXLORf;
+ else if (PPC::QFRCRegClass.contains(DestReg, SrcReg))
+ Opc = PPC::QVFMR;
+ else if (PPC::QSRCRegClass.contains(DestReg, SrcReg))
+ Opc = PPC::QVFMRs;
+ else if (PPC::QBRCRegClass.contains(DestReg, SrcReg))
+ Opc = PPC::QVFMRb;
else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
Opc = PPC::CROR;
else
getKillRegState(isKill)),
FrameIdx));
SpillsVRS = true;
+ } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFDX))
+ .addReg(SrcReg,
+ getKillRegState(isKill)),
+ FrameIdx));
+ NonRI = true;
+ } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFSXs))
+ .addReg(SrcReg,
+ getKillRegState(isKill)),
+ FrameIdx));
+ NonRI = true;
+ } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVSTFDXb))
+ .addReg(SrcReg,
+ getKillRegState(isKill)),
+ FrameIdx));
+ NonRI = true;
} else {
llvm_unreachable("Unknown regclass!");
}
DestReg),
FrameIdx));
SpillsVRS = true;
+ } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFDX), DestReg),
+ FrameIdx));
+ NonRI = true;
+ } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFSXs), DestReg),
+ FrameIdx));
+ NonRI = true;
+ } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) {
+ NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::QVLFDXb), DestReg),
+ FrameIdx));
+ NonRI = true;
} else {
llvm_unreachable("Unknown regclass!");
}
}
}
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "ppc-early-ret"
-STATISTIC(NumBCLR, "Number of early conditional returns");
-STATISTIC(NumBLR, "Number of early returns");
-
-namespace llvm {
- void initializePPCEarlyReturnPass(PassRegistry&);
-}
-
-namespace {
- // PPCEarlyReturn pass - For simple functions without epilogue code, move
- // returns up, and create conditional returns, to avoid unnecessary
- // branch-to-blr sequences.
- struct PPCEarlyReturn : public MachineFunctionPass {
- static char ID;
- PPCEarlyReturn() : MachineFunctionPass(ID) {
- initializePPCEarlyReturnPass(*PassRegistry::getPassRegistry());
- }
-
- const TargetInstrInfo *TII;
-
-protected:
- bool processBlock(MachineBasicBlock &ReturnMBB) {
- bool Changed = false;
-
- MachineBasicBlock::iterator I = ReturnMBB.begin();
- I = ReturnMBB.SkipPHIsAndLabels(I);
-
- // The block must be essentially empty except for the blr.
- if (I == ReturnMBB.end() ||
- (I->getOpcode() != PPC::BLR && I->getOpcode() != PPC::BLR8) ||
- I != ReturnMBB.getLastNonDebugInstr())
- return Changed;
-
- SmallVector<MachineBasicBlock*, 8> PredToRemove;
- for (MachineBasicBlock::pred_iterator PI = ReturnMBB.pred_begin(),
- PIE = ReturnMBB.pred_end(); PI != PIE; ++PI) {
- bool OtherReference = false, BlockChanged = false;
- for (MachineBasicBlock::iterator J = (*PI)->getLastNonDebugInstr();;) {
- MachineInstrBuilder MIB;
- if (J->getOpcode() == PPC::B) {
- if (J->getOperand(0).getMBB() == &ReturnMBB) {
- // This is an unconditional branch to the return. Replace the
- // branch with a blr.
- MIB =
- BuildMI(**PI, J, J->getDebugLoc(), TII->get(I->getOpcode()));
- MIB.copyImplicitOps(I);
- MachineBasicBlock::iterator K = J--;
- K->eraseFromParent();
- BlockChanged = true;
- ++NumBLR;
- continue;
- }
- } else if (J->getOpcode() == PPC::BCC) {
- if (J->getOperand(2).getMBB() == &ReturnMBB) {
- // This is a conditional branch to the return. Replace the branch
- // with a bclr.
- MIB = BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BCCLR))
- .addImm(J->getOperand(0).getImm())
- .addReg(J->getOperand(1).getReg());
- MIB.copyImplicitOps(I);
- MachineBasicBlock::iterator K = J--;
- K->eraseFromParent();
- BlockChanged = true;
- ++NumBCLR;
- continue;
- }
- } else if (J->getOpcode() == PPC::BC || J->getOpcode() == PPC::BCn) {
- if (J->getOperand(1).getMBB() == &ReturnMBB) {
- // This is a conditional branch to the return. Replace the branch
- // with a bclr.
- MIB = BuildMI(**PI, J, J->getDebugLoc(),
- TII->get(J->getOpcode() == PPC::BC ?
- PPC::BCLR : PPC::BCLRn))
- .addReg(J->getOperand(0).getReg());
- MIB.copyImplicitOps(I);
- MachineBasicBlock::iterator K = J--;
- K->eraseFromParent();
- BlockChanged = true;
- ++NumBCLR;
- continue;
- }
- } else if (J->isBranch()) {
- if (J->isIndirectBranch()) {
- if (ReturnMBB.hasAddressTaken())
- OtherReference = true;
- } else
- for (unsigned i = 0; i < J->getNumOperands(); ++i)
- if (J->getOperand(i).isMBB() &&
- J->getOperand(i).getMBB() == &ReturnMBB)
- OtherReference = true;
- } else if (!J->isTerminator() && !J->isDebugValue())
- break;
-
- if (J == (*PI)->begin())
- break;
-
- --J;
- }
-
- if ((*PI)->canFallThrough() && (*PI)->isLayoutSuccessor(&ReturnMBB))
- OtherReference = true;
-
- // Predecessors are stored in a vector and can't be removed here.
- if (!OtherReference && BlockChanged) {
- PredToRemove.push_back(*PI);
- }
-
- if (BlockChanged)
- Changed = true;
- }
-
- for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i)
- PredToRemove[i]->removeSuccessor(&ReturnMBB);
-
- if (Changed && !ReturnMBB.hasAddressTaken()) {
- // We now might be able to merge this blr-only block into its
- // by-layout predecessor.
- if (ReturnMBB.pred_size() == 1 &&
- (*ReturnMBB.pred_begin())->isLayoutSuccessor(&ReturnMBB)) {
- // Move the blr into the preceding block.
- MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin();
- PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I);
- PrevMBB.removeSuccessor(&ReturnMBB);
- }
-
- if (ReturnMBB.pred_empty())
- ReturnMBB.eraseFromParent();
- }
-
- return Changed;
- }
-
-public:
- bool runOnMachineFunction(MachineFunction &MF) override {
- TII = MF.getSubtarget().getInstrInfo();
-
- bool Changed = false;
-
- // If the function does not have at least two blocks, then there is
- // nothing to do.
- if (MF.size() < 2)
- return Changed;
-
- for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
- MachineBasicBlock &B = *I++;
- if (processBlock(B))
- Changed = true;
- }
-
- return Changed;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-}
-
-INITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE,
- "PowerPC Early-Return Creation", false, false)
-
-char PPCEarlyReturn::ID = 0;
-FunctionPass*
-llvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }