-#undef DEBUG_TYPE
-#define DEBUG_TYPE "ppc-vsx-fma-mutate"
-
-namespace {
- // PPCVSXFMAMutate pass - For copies between VSX registers and non-VSX registers
- // (Altivec and scalar floating-point registers), we need to transform the
- // copies into subregister copies with other restrictions.
- struct PPCVSXFMAMutate : public MachineFunctionPass {
- static char ID;
- PPCVSXFMAMutate() : MachineFunctionPass(ID) {
- initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry());
- }
-
- LiveIntervals *LIS;
-
- const PPCTargetMachine *TM;
- const PPCInstrInfo *TII;
-
-protected:
- bool processBlock(MachineBasicBlock &MBB) {
- bool Changed = false;
-
- MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
- for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
- I != IE; ++I) {
- MachineInstr *MI = I;
-
- // The default (A-type) VSX FMA form kills the addend (it is taken from
- // the target register, which is then updated to reflect the result of
- // the FMA). If the instruction, however, kills one of the registers
- // used for the product, then we can use the M-form instruction (which
- // will take that value from the to-be-defined register).
-
- int AltOpc = PPC::getAltVSXFMAOpcode(MI->getOpcode());
- if (AltOpc == -1)
- continue;
-
- // This pass is run after register coalescing, and so we're looking for
- // a situation like this:
- // ...
- // %vreg5<def> = COPY %vreg9; VSLRC:%vreg5,%vreg9
- // %vreg5<def,tied1> = XSMADDADP %vreg5<tied0>, %vreg17, %vreg16,
- // %RM<imp-use>; VSLRC:%vreg5,%vreg17,%vreg16
- // ...
- // %vreg9<def,tied1> = XSMADDADP %vreg9<tied0>, %vreg17, %vreg19,
- // %RM<imp-use>; VSLRC:%vreg9,%vreg17,%vreg19
- // ...
- // Where we can eliminate the copy by changing from the A-type to the
- // M-type instruction. Specifically, for this example, this means:
- // %vreg5<def,tied1> = XSMADDADP %vreg5<tied0>, %vreg17, %vreg16,
- // %RM<imp-use>; VSLRC:%vreg5,%vreg17,%vreg16
- // is replaced by:
- // %vreg16<def,tied1> = XSMADDMDP %vreg16<tied0>, %vreg18, %vreg9,
- // %RM<imp-use>; VSLRC:%vreg16,%vreg18,%vreg9
- // and we remove: %vreg5<def> = COPY %vreg9; VSLRC:%vreg5,%vreg9
-
- SlotIndex FMAIdx = LIS->getInstructionIndex(MI);
-
- VNInfo *AddendValNo =
- LIS->getInterval(MI->getOperand(1).getReg()).Query(FMAIdx).valueIn();
- MachineInstr *AddendMI = LIS->getInstructionFromIndex(AddendValNo->def);
-
- // The addend and this instruction must be in the same block.
-
- if (!AddendMI || AddendMI->getParent() != MI->getParent())
- continue;
-
- // The addend must be a full copy within the same register class.
-
- if (!AddendMI->isFullCopy())
- continue;
-
- unsigned AddendSrcReg = AddendMI->getOperand(1).getReg();
- if (TargetRegisterInfo::isVirtualRegister(AddendSrcReg)) {
- if (MRI.getRegClass(AddendMI->getOperand(0).getReg()) !=
- MRI.getRegClass(AddendSrcReg))
- continue;
- } else {
- // If AddendSrcReg is a physical register, make sure the destination
- // register class contains it.
- if (!MRI.getRegClass(AddendMI->getOperand(0).getReg())
- ->contains(AddendSrcReg))
- continue;
- }
-
- // 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;
- for (auto J = std::prev(I), JE = MachineBasicBlock::iterator(AddendMI);
- J != JE; --J)
- if (J->readsVirtualRegister(AddendMI->getOperand(0).getReg())) {
- OtherUsers = true;
- break;
- }
-
- if (OtherUsers)
- continue;
-
- // Find one of the product operands that is killed by this instruction.
-
- unsigned KilledProdOp = 0, OtherProdOp = 0;
- if (LIS->getInterval(MI->getOperand(2).getReg())
- .Query(FMAIdx).isKill()) {
- KilledProdOp = 2;
- OtherProdOp = 3;
- } else if (LIS->getInterval(MI->getOperand(3).getReg())
- .Query(FMAIdx).isKill()) {
- KilledProdOp = 3;
- OtherProdOp = 2;
- }
-
- // If there are no killed product operands, then this transformation is
- // likely not profitable.
- 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;
-
- // Transform: (O2 * O3) + O1 -> (O2 * O1) + O3.
-
- unsigned AddReg = AddendMI->getOperand(1).getReg();
- unsigned KilledProdReg = MI->getOperand(KilledProdOp).getReg();
- unsigned OtherProdReg = MI->getOperand(OtherProdOp).getReg();
-
- unsigned AddSubReg = AddendMI->getOperand(1).getSubReg();
- unsigned KilledProdSubReg = MI->getOperand(KilledProdOp).getSubReg();
- unsigned OtherProdSubReg = MI->getOperand(OtherProdOp).getSubReg();
-
- bool AddRegKill = AddendMI->getOperand(1).isKill();
- bool KilledProdRegKill = MI->getOperand(KilledProdOp).isKill();
- bool OtherProdRegKill = MI->getOperand(OtherProdOp).isKill();
-
- bool AddRegUndef = AddendMI->getOperand(1).isUndef();
- bool KilledProdRegUndef = MI->getOperand(KilledProdOp).isUndef();
- bool OtherProdRegUndef = MI->getOperand(OtherProdOp).isUndef();
-
- unsigned OldFMAReg = MI->getOperand(0).getReg();
-
- assert(OldFMAReg == AddendMI->getOperand(0).getReg() &&
- "Addend copy not tied to old FMA output!");
-
- DEBUG(dbgs() << "VSX FMA Mutation:\n " << *MI;);
-
- MI->getOperand(0).setReg(KilledProdReg);
- MI->getOperand(1).setReg(KilledProdReg);
- MI->getOperand(3).setReg(AddReg);
- MI->getOperand(2).setReg(OtherProdReg);
-
- MI->getOperand(0).setSubReg(KilledProdSubReg);
- MI->getOperand(1).setSubReg(KilledProdSubReg);
- MI->getOperand(3).setSubReg(AddSubReg);
- MI->getOperand(2).setSubReg(OtherProdSubReg);
-
- MI->getOperand(1).setIsKill(KilledProdRegKill);
- MI->getOperand(3).setIsKill(AddRegKill);
- MI->getOperand(2).setIsKill(OtherProdRegKill);
-
- MI->getOperand(1).setIsUndef(KilledProdRegUndef);
- MI->getOperand(3).setIsUndef(AddRegUndef);
- MI->getOperand(2).setIsUndef(OtherProdRegUndef);
-
- MI->setDesc(TII->get(AltOpc));
-
- DEBUG(dbgs() << " -> " << *MI);
-
- // The killed product operand was killed here, so we can reuse it now
- // for the result of the fma.
-
- LiveInterval &FMAInt = LIS->getInterval(OldFMAReg);
- VNInfo *FMAValNo = FMAInt.getVNInfoAt(FMAIdx.getRegSlot());
- for (auto UI = MRI.reg_nodbg_begin(OldFMAReg), UE = MRI.reg_nodbg_end();
- UI != UE;) {
- MachineOperand &UseMO = *UI;
- MachineInstr *UseMI = UseMO.getParent();
- ++UI;
-
- // Don't replace the result register of the copy we're about to erase.
- if (UseMI == AddendMI)
- continue;
-
- UseMO.setReg(KilledProdReg);
- UseMO.setSubReg(KilledProdSubReg);
- }
-
- // Extend the live intervals of the killed product operand to hold the
- // fma result.
-
- LiveInterval &NewFMAInt = LIS->getInterval(KilledProdReg);
- for (LiveInterval::iterator AI = FMAInt.begin(), AE = FMAInt.end();
- AI != AE; ++AI) {
- // Don't add the segment that corresponds to the original copy.
- if (AI->valno == AddendValNo)
- continue;
-
- VNInfo *NewFMAValNo =
- NewFMAInt.getNextValue(AI->start,
- LIS->getVNInfoAllocator());
-
- NewFMAInt.addSegment(LiveInterval::Segment(AI->start, AI->end,
- NewFMAValNo));
- }
- DEBUG(dbgs() << " extended: " << NewFMAInt << '\n');
-
- FMAInt.removeValNo(FMAValNo);
- DEBUG(dbgs() << " trimmed: " << FMAInt << '\n');
-
- // Remove the (now unused) copy.
-
- DEBUG(dbgs() << " removing: " << *AddendMI << '\n');
- LIS->RemoveMachineInstrFromMaps(AddendMI);
- AddendMI->eraseFromParent();
-
- Changed = true;
- }
-
- return Changed;
- }
-
-public:
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- LIS = &getAnalysis<LiveIntervals>();
-
- TM = static_cast<const PPCTargetMachine *>(&MF.getTarget());
- TII = TM->getInstrInfo();
-
- bool Changed = false;
-
- if (DisableVSXFMAMutate)
- return Changed;
-
- for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
- MachineBasicBlock &B = *I++;
- if (processBlock(B))
- Changed = true;
- }
-
- return Changed;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LiveIntervals>();
- AU.addPreserved<LiveIntervals>();
- AU.addRequired<SlotIndexes>();
- AU.addPreserved<SlotIndexes>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-}
-
-INITIALIZE_PASS_BEGIN(PPCVSXFMAMutate, DEBUG_TYPE,
- "PowerPC VSX FMA Mutation", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
-INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
-INITIALIZE_PASS_END(PPCVSXFMAMutate, DEBUG_TYPE,
- "PowerPC VSX FMA Mutation", false, false)
-
-char &llvm::PPCVSXFMAMutateID = PPCVSXFMAMutate::ID;
-
-char PPCVSXFMAMutate::ID = 0;
-FunctionPass*
-llvm::createPPCVSXFMAMutatePass() { return new PPCVSXFMAMutate(); }
-
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "ppc-vsx-copy"
-
-namespace llvm {
- void initializePPCVSXCopyPass(PassRegistry&);
-}
-
-namespace {
- // PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
- // (Altivec and scalar floating-point registers), we need to transform the
- // copies into subregister copies with other restrictions.
- struct PPCVSXCopy : public MachineFunctionPass {
- static char ID;
- PPCVSXCopy() : MachineFunctionPass(ID) {
- initializePPCVSXCopyPass(*PassRegistry::getPassRegistry());
- }
-
- const PPCTargetMachine *TM;
- const PPCInstrInfo *TII;
-
- bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
- MachineRegisterInfo &MRI) {
- if (TargetRegisterInfo::isVirtualRegister(Reg)) {
- return RC->hasSubClassEq(MRI.getRegClass(Reg));
- } else if (RC->contains(Reg)) {
- return true;
- }
-
- return false;
- }
-
- bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
- return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
- }
-
- bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
- return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
- }
-
- bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
- return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
- }
-
-protected:
- bool processBlock(MachineBasicBlock &MBB) {
- bool Changed = false;
-
- MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
- for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
- I != IE; ++I) {
- MachineInstr *MI = I;
- if (!MI->isFullCopy())
- continue;
-
- MachineOperand &DstMO = MI->getOperand(0);
- MachineOperand &SrcMO = MI->getOperand(1);
-
- if ( IsVSReg(DstMO.getReg(), MRI) &&
- !IsVSReg(SrcMO.getReg(), MRI)) {
- // This is a copy *to* a VSX register from a non-VSX register.
- Changed = true;
-
- const TargetRegisterClass *SrcRC =
- IsVRReg(SrcMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
- &PPC::VSLRCRegClass;
- assert((IsF8Reg(SrcMO.getReg(), MRI) ||
- IsVRReg(SrcMO.getReg(), MRI)) &&
- "Unknown source for a VSX copy");
-
- unsigned NewVReg = MRI.createVirtualRegister(SrcRC);
- BuildMI(MBB, MI, MI->getDebugLoc(),
- TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
- .addImm(1) // add 1, not 0, because there is no implicit clearing
- // of the high bits.
- .addOperand(SrcMO)
- .addImm(IsVRReg(SrcMO.getReg(), MRI) ? PPC::sub_128 :
- PPC::sub_64);
-
- // The source of the original copy is now the new virtual register.
- SrcMO.setReg(NewVReg);
- } else if (!IsVSReg(DstMO.getReg(), MRI) &&
- IsVSReg(SrcMO.getReg(), MRI)) {
- // This is a copy *from* a VSX register to a non-VSX register.
- Changed = true;
-
- const TargetRegisterClass *DstRC =
- IsVRReg(DstMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
- &PPC::VSLRCRegClass;
- assert((IsF8Reg(DstMO.getReg(), MRI) ||
- IsVRReg(DstMO.getReg(), MRI)) &&
- "Unknown destination for a VSX copy");
-
- // Copy the VSX value into a new VSX register of the correct subclass.
- unsigned NewVReg = MRI.createVirtualRegister(DstRC);
- BuildMI(MBB, MI, MI->getDebugLoc(),
- TII->get(TargetOpcode::COPY), NewVReg)
- .addOperand(SrcMO);
-
- // Transform the original copy into a subregister extraction copy.
- SrcMO.setReg(NewVReg);
- SrcMO.setSubReg(IsVRReg(DstMO.getReg(), MRI) ? PPC::sub_128 :
- PPC::sub_64);
- }
- }
-
- return Changed;
- }
-
-public:
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- TM = static_cast<const PPCTargetMachine *>(&MF.getTarget());
- TII = TM->getInstrInfo();
-
- bool Changed = false;
-
- for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
- MachineBasicBlock &B = *I++;
- if (processBlock(B))
- Changed = true;
- }
-
- return Changed;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-}
-
-INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
- "PowerPC VSX Copy Legalization", false, false)
-
-char PPCVSXCopy::ID = 0;
-FunctionPass*
-llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }
-
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "ppc-vsx-copy-cleanup"
-
-namespace llvm {
- void initializePPCVSXCopyCleanupPass(PassRegistry&);
-}
-
-namespace {
- // PPCVSXCopyCleanup pass - We sometimes end up generating self copies of VSX
- // registers (mostly because the ABI code still places all values into the
- // "traditional" floating-point and vector registers). Remove them here.
- struct PPCVSXCopyCleanup : public MachineFunctionPass {
- static char ID;
- PPCVSXCopyCleanup() : MachineFunctionPass(ID) {
- initializePPCVSXCopyCleanupPass(*PassRegistry::getPassRegistry());
- }
-
- const PPCTargetMachine *TM;
- const PPCInstrInfo *TII;
-
-protected:
- bool processBlock(MachineBasicBlock &MBB) {
- bool Changed = false;
-
- SmallVector<MachineInstr *, 4> ToDelete;
- for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
- I != IE; ++I) {
- MachineInstr *MI = I;
- if (MI->getOpcode() == PPC::XXLOR &&
- MI->getOperand(0).getReg() == MI->getOperand(1).getReg() &&
- MI->getOperand(0).getReg() == MI->getOperand(2).getReg())
- ToDelete.push_back(MI);
- }
-
- if (!ToDelete.empty())
- Changed = true;
-
- for (unsigned i = 0, ie = ToDelete.size(); i != ie; ++i) {
- DEBUG(dbgs() << "Removing VSX self-copy: " << *ToDelete[i]);
- ToDelete[i]->eraseFromParent();
- }
-
- return Changed;
- }
-
-public:
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- TM = static_cast<const PPCTargetMachine *>(&MF.getTarget());
- TII = TM->getInstrInfo();
-
- bool Changed = false;
-
- for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
- MachineBasicBlock &B = *I++;
- if (processBlock(B))
- Changed = true;
- }
-
- return Changed;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-}
-
-INITIALIZE_PASS(PPCVSXCopyCleanup, DEBUG_TYPE,
- "PowerPC VSX Copy Cleanup", false, false)
-
-char PPCVSXCopyCleanup::ID = 0;
-FunctionPass*
-llvm::createPPCVSXCopyCleanupPass() { return new PPCVSXCopyCleanup(); }
-
-#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 PPCTargetMachine *TM;
- const PPCInstrInfo *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 != 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();;) {
- 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.
- BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BLR));
- 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.
- BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BCCLR))
- .addImm(J->getOperand(0).getImm())
- .addReg(J->getOperand(1).getReg());
- 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.
- BuildMI(**PI, J, J->getDebugLoc(),
- TII->get(J->getOpcode() == PPC::BC ?
- PPC::BCLR : PPC::BCLRn))
- .addReg(J->getOperand(0).getReg());
- 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:
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- TM = static_cast<const PPCTargetMachine *>(&MF.getTarget());
- TII = TM->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;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-}
-
-INITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE,
- "PowerPC Early-Return Creation", false, false)
-
-char PPCEarlyReturn::ID = 0;
-FunctionPass*
-llvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }