diff --git a/lib/Target/PowerPC/PPCMachineBasicBlockUtils.h b/lib/Target/PowerPC/PPCMachineBasicBlockUtils.h deleted file mode 100644 index 628ea2ab9fe..00000000000 --- a/lib/Target/PowerPC/PPCMachineBasicBlockUtils.h +++ /dev/null @@ -1,198 +0,0 @@ -//==-- PPCMachineBasicBlockUtils.h - Functions for common MBB operations ---==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines utility functions for commonly used operations on -// MachineBasicBlock's. -// NOTE: Include this file after defining DEBUG_TYPE so that the debug messages -// can be emitted for the pass that is using this. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_PPC_MACHINE_BASIC_BLOCK_UTILS_H -#define LLVM_LIB_TARGET_PPC_MACHINE_BASIC_BLOCK_UTILS_H - -#include "PPCInstrInfo.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" - -#ifndef DEBUG_TYPE -#define DEBUG_TYPE "ppc-generic-mbb-utilities" -#endif - -using namespace llvm; - -/// Given a basic block \p Successor that potentially contains PHIs, this -/// function will look for any incoming values in the PHIs that are supposed to -/// be coming from \p OrigMBB but whose definition is actually in \p NewMBB. -/// Any such PHIs will be updated to reflect reality. -static void updatePHIs(MachineBasicBlock *Successor, MachineBasicBlock *OrigMBB, - MachineBasicBlock *NewMBB, MachineRegisterInfo *MRI) { - for (auto &MI : Successor->instrs()) { - if (!MI.isPHI()) - continue; - // This is a really ugly-looking loop, but it was pillaged directly from - // MachineBasicBlock::transferSuccessorsAndUpdatePHIs(). - for (unsigned i = 2, e = MI.getNumOperands()+1; i != e; i += 2) { - MachineOperand &MO = MI.getOperand(i); - if (MO.getMBB() == OrigMBB) { - // Check if the instruction is actualy defined in NewMBB. - if (MI.getOperand(i-1).isReg()) { - MachineInstr *DefMI = MRI->getVRegDef(MI.getOperand(i-1).getReg()); - if (DefMI->getParent() == NewMBB || !OrigMBB->isSuccessor(Successor)) { - MO.setMBB(NewMBB); - break; - } - } - } - } - } -} - -/// Given a basic block \p Successor that potentially contains PHIs, this -/// function will look for PHIs that have an incoming value from \p OrigMBB -/// and will add the same incoming value from \p NewMBB. -/// NOTE: This should only be used if \p NewMBB is an immediate dominator of -/// \p OrigMBB. -static void addIncomingValuesToPHIs(MachineBasicBlock *Successor, - MachineBasicBlock *OrigMBB, - MachineBasicBlock *NewMBB, - MachineRegisterInfo *MRI) { - assert(OrigMBB->isSuccessor(NewMBB) && "NewMBB must be a sucessor of OrigMBB"); - for (auto &MI : Successor->instrs()) { - if (!MI.isPHI()) - continue; - // This is a really ugly-looking loop, but it was pillaged directly from - // MachineBasicBlock::transferSuccessorsAndUpdatePHIs(). - for (unsigned i = 2, e = MI.getNumOperands()+1; i != e; i += 2) { - MachineOperand &MO = MI.getOperand(i); - if (MO.getMBB() == OrigMBB) { - MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI); - MIB.addReg(MI.getOperand(i-1).getReg()).addMBB(NewMBB); - break; - } - } - } -} - -struct BlockSplitInfo { - MachineInstr *OrigBranch; - MachineInstr *SplitBefore; - MachineInstr *SplitCond; - bool InvertNewBranch; - bool InvertOrigBranch; - bool BranchToFallThrough; - const MachineBranchProbabilityInfo *MBPI; - MachineInstr *MIToDelete; - MachineInstr *NewCond; - bool allInstrsInSameMBB() { - if (!OrigBranch || !SplitBefore || !SplitCond) - return false; - MachineBasicBlock *MBB = OrigBranch->getParent(); - if (SplitBefore->getParent() != MBB || - SplitCond->getParent() != MBB) - return false; - if (MIToDelete && MIToDelete->getParent() != MBB) - return false; - if (NewCond && NewCond->getParent() != MBB) - return false; - return true; - } -}; - -/// Splits a MachineBasicBlock to branch before \p SplitBefore. The original -/// branch is \p OrigBranch. The target of the new branch can either be the same -/// as the target of the original branch or the fallthrough successor of the -/// original block as determined by \p BranchToFallThrough. The branch -/// conditions will be inverted according to \p InvertNewBranch and -/// \p InvertOrigBranch. If an instruction that previously fed the branch is to -/// be deleted, it is provided in \p MIToDelete and \p NewCond will be used as -/// the branch condition. The branch probabilities will be set if the -/// MachineBranchProbabilityInfo isn't null. -static bool splitMBB(BlockSplitInfo &BSI) { - assert(BSI.allInstrsInSameMBB() && - "All instructions must be in the same block."); - - MachineBasicBlock *ThisMBB = BSI.OrigBranch->getParent(); - MachineFunction *MF = ThisMBB->getParent(); - MachineRegisterInfo *MRI = &MF->getRegInfo(); - assert(MRI->isSSA() && "Can only do this while the function is in SSA form."); - if (ThisMBB->succ_size() != 2) { - DEBUG(dbgs() << "Don't know how to handle blocks that don't have exactly" - << " two succesors.\n"); - return false; - } - - const PPCInstrInfo *TII = MF->getSubtarget().getInstrInfo(); - unsigned OrigBROpcode = BSI.OrigBranch->getOpcode(); - unsigned InvertedOpcode = - OrigBROpcode == PPC::BC ? PPC::BCn : - OrigBROpcode == PPC::BCn ? PPC::BC : - OrigBROpcode == PPC::BCLR ? PPC::BCLRn : PPC::BCLR; - unsigned NewBROpcode = BSI.InvertNewBranch ? InvertedOpcode : OrigBROpcode; - MachineBasicBlock *OrigTarget = BSI.OrigBranch->getOperand(1).getMBB(); - MachineBasicBlock *OrigFallThrough = - OrigTarget == *ThisMBB->succ_begin() ? *ThisMBB->succ_rbegin() : - *ThisMBB->succ_begin(); - MachineBasicBlock *NewBRTarget = - BSI.BranchToFallThrough ? OrigFallThrough : OrigTarget; - BranchProbability ProbToNewTarget = - !BSI.MBPI ? BranchProbability::getUnknown() : - BSI.MBPI->getEdgeProbability(ThisMBB, NewBRTarget); - - // Create a new basic block. - MachineBasicBlock::iterator InsertPoint = BSI.SplitBefore; - const BasicBlock *LLVM_BB = ThisMBB->getBasicBlock(); - MachineFunction::iterator It = ThisMBB->getIterator(); - MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(LLVM_BB); - MF->insert(++It, NewMBB); - - // Move everything after SplitBefore into the new block. - NewMBB->splice(NewMBB->end(), ThisMBB, InsertPoint, ThisMBB->end()); - NewMBB->transferSuccessors(ThisMBB); - - // Add the two successors to ThisMBB. The probabilities come from the - // existing blocks if available. - ThisMBB->addSuccessor(NewBRTarget, ProbToNewTarget); - ThisMBB->addSuccessor(NewMBB, ProbToNewTarget.getCompl()); - - // Add the branches to ThisMBB. - BuildMI(*ThisMBB, ThisMBB->end(), BSI.SplitBefore->getDebugLoc(), - TII->get(NewBROpcode)).addReg(BSI.SplitCond->getOperand(0).getReg()) - .addMBB(NewBRTarget); - BuildMI(*ThisMBB, ThisMBB->end(), BSI.SplitBefore->getDebugLoc(), - TII->get(PPC::B)).addMBB(NewMBB); - if (BSI.MIToDelete) - BSI.MIToDelete->eraseFromParent(); - - // Change the condition on the original branch and invert it if requested. - auto FirstTerminator = NewMBB->getFirstTerminator(); - if (BSI.NewCond) { - assert(FirstTerminator->getOperand(0).isReg() && - "Can't update condition of unconditional branch."); - FirstTerminator->getOperand(0).setReg(BSI.NewCond->getOperand(0).getReg()); - } - if (BSI.InvertOrigBranch) - FirstTerminator->setDesc(TII->get(InvertedOpcode)); - - // If any of the PHIs in the successors of NewMBB reference values that - // now come from NewMBB, they need to be updated. - for (auto *Succ : NewMBB->successors()) { - updatePHIs(Succ, ThisMBB, NewMBB, MRI); - } - addIncomingValuesToPHIs(NewBRTarget, ThisMBB, NewMBB, MRI); - - DEBUG(dbgs() << "After splitting, ThisMBB:\n"; ThisMBB->dump()); - DEBUG(dbgs() << "NewMBB:\n"; NewMBB->dump()); - DEBUG(dbgs() << "New branch-to block:\n"; NewBRTarget->dump()); - return true; -} - - -#endif diff --git a/lib/Target/PowerPC/PPCReduceCRLogicals.cpp b/lib/Target/PowerPC/PPCReduceCRLogicals.cpp index 5b2d7191683..acbd331aa18 100644 --- a/lib/Target/PowerPC/PPCReduceCRLogicals.cpp +++ b/lib/Target/PowerPC/PPCReduceCRLogicals.cpp @@ -15,18 +15,20 @@ // //===---------------------------------------------------------------------===// -#include "PPCInstrInfo.h" #include "PPC.h" +#include "PPCInstrInfo.h" #include "PPCTargetMachine.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/Debug.h" using namespace llvm; #define DEBUG_TYPE "ppc-reduce-cr-ops" -#include "PPCMachineBasicBlockUtils.h" STATISTIC(NumContainedSingleUseBinOps, "Number of single-use binary CR logical ops contained in a block"); @@ -50,7 +52,176 @@ namespace llvm { void initializePPCReduceCRLogicalsPass(PassRegistry&); } -namespace { +/// Given a basic block \p Successor that potentially contains PHIs, this +/// function will look for any incoming values in the PHIs that are supposed to +/// be coming from \p OrigMBB but whose definition is actually in \p NewMBB. +/// Any such PHIs will be updated to reflect reality. +static void updatePHIs(MachineBasicBlock *Successor, MachineBasicBlock *OrigMBB, + MachineBasicBlock *NewMBB, MachineRegisterInfo *MRI) { + for (auto &MI : Successor->instrs()) { + if (!MI.isPHI()) + continue; + // This is a really ugly-looking loop, but it was pillaged directly from + // MachineBasicBlock::transferSuccessorsAndUpdatePHIs(). + for (unsigned i = 2, e = MI.getNumOperands() + 1; i != e; i += 2) { + MachineOperand &MO = MI.getOperand(i); + if (MO.getMBB() == OrigMBB) { + // Check if the instruction is actualy defined in NewMBB. + if (MI.getOperand(i - 1).isReg()) { + MachineInstr *DefMI = MRI->getVRegDef(MI.getOperand(i - 1).getReg()); + if (DefMI->getParent() == NewMBB || + !OrigMBB->isSuccessor(Successor)) { + MO.setMBB(NewMBB); + break; + } + } + } + } + } +} + +/// Given a basic block \p Successor that potentially contains PHIs, this +/// function will look for PHIs that have an incoming value from \p OrigMBB +/// and will add the same incoming value from \p NewMBB. +/// NOTE: This should only be used if \p NewMBB is an immediate dominator of +/// \p OrigMBB. +static void addIncomingValuesToPHIs(MachineBasicBlock *Successor, + MachineBasicBlock *OrigMBB, + MachineBasicBlock *NewMBB, + MachineRegisterInfo *MRI) { + assert(OrigMBB->isSuccessor(NewMBB) && + "NewMBB must be a sucessor of OrigMBB"); + for (auto &MI : Successor->instrs()) { + if (!MI.isPHI()) + continue; + // This is a really ugly-looking loop, but it was pillaged directly from + // MachineBasicBlock::transferSuccessorsAndUpdatePHIs(). + for (unsigned i = 2, e = MI.getNumOperands() + 1; i != e; i += 2) { + MachineOperand &MO = MI.getOperand(i); + if (MO.getMBB() == OrigMBB) { + MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI); + MIB.addReg(MI.getOperand(i - 1).getReg()).addMBB(NewMBB); + break; + } + } + } +} + +struct BlockSplitInfo { + MachineInstr *OrigBranch; + MachineInstr *SplitBefore; + MachineInstr *SplitCond; + bool InvertNewBranch; + bool InvertOrigBranch; + bool BranchToFallThrough; + const MachineBranchProbabilityInfo *MBPI; + MachineInstr *MIToDelete; + MachineInstr *NewCond; + bool allInstrsInSameMBB() { + if (!OrigBranch || !SplitBefore || !SplitCond) + return false; + MachineBasicBlock *MBB = OrigBranch->getParent(); + if (SplitBefore->getParent() != MBB || SplitCond->getParent() != MBB) + return false; + if (MIToDelete && MIToDelete->getParent() != MBB) + return false; + if (NewCond && NewCond->getParent() != MBB) + return false; + return true; + } +}; + +/// Splits a MachineBasicBlock to branch before \p SplitBefore. The original +/// branch is \p OrigBranch. The target of the new branch can either be the same +/// as the target of the original branch or the fallthrough successor of the +/// original block as determined by \p BranchToFallThrough. The branch +/// conditions will be inverted according to \p InvertNewBranch and +/// \p InvertOrigBranch. If an instruction that previously fed the branch is to +/// be deleted, it is provided in \p MIToDelete and \p NewCond will be used as +/// the branch condition. The branch probabilities will be set if the +/// MachineBranchProbabilityInfo isn't null. +static bool splitMBB(BlockSplitInfo &BSI) { + assert(BSI.allInstrsInSameMBB() && + "All instructions must be in the same block."); + + MachineBasicBlock *ThisMBB = BSI.OrigBranch->getParent(); + MachineFunction *MF = ThisMBB->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + assert(MRI->isSSA() && "Can only do this while the function is in SSA form."); + if (ThisMBB->succ_size() != 2) { + DEBUG(dbgs() << "Don't know how to handle blocks that don't have exactly" + << " two succesors.\n"); + return false; + } + + const PPCInstrInfo *TII = MF->getSubtarget().getInstrInfo(); + unsigned OrigBROpcode = BSI.OrigBranch->getOpcode(); + unsigned InvertedOpcode = + OrigBROpcode == PPC::BC + ? PPC::BCn + : OrigBROpcode == PPC::BCn + ? PPC::BC + : OrigBROpcode == PPC::BCLR ? PPC::BCLRn : PPC::BCLR; + unsigned NewBROpcode = BSI.InvertNewBranch ? InvertedOpcode : OrigBROpcode; + MachineBasicBlock *OrigTarget = BSI.OrigBranch->getOperand(1).getMBB(); + MachineBasicBlock *OrigFallThrough = OrigTarget == *ThisMBB->succ_begin() + ? *ThisMBB->succ_rbegin() + : *ThisMBB->succ_begin(); + MachineBasicBlock *NewBRTarget = + BSI.BranchToFallThrough ? OrigFallThrough : OrigTarget; + BranchProbability ProbToNewTarget = + !BSI.MBPI ? BranchProbability::getUnknown() + : BSI.MBPI->getEdgeProbability(ThisMBB, NewBRTarget); + + // Create a new basic block. + MachineBasicBlock::iterator InsertPoint = BSI.SplitBefore; + const BasicBlock *LLVM_BB = ThisMBB->getBasicBlock(); + MachineFunction::iterator It = ThisMBB->getIterator(); + MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MF->insert(++It, NewMBB); + + // Move everything after SplitBefore into the new block. + NewMBB->splice(NewMBB->end(), ThisMBB, InsertPoint, ThisMBB->end()); + NewMBB->transferSuccessors(ThisMBB); + + // Add the two successors to ThisMBB. The probabilities come from the + // existing blocks if available. + ThisMBB->addSuccessor(NewBRTarget, ProbToNewTarget); + ThisMBB->addSuccessor(NewMBB, ProbToNewTarget.getCompl()); + + // Add the branches to ThisMBB. + BuildMI(*ThisMBB, ThisMBB->end(), BSI.SplitBefore->getDebugLoc(), + TII->get(NewBROpcode)) + .addReg(BSI.SplitCond->getOperand(0).getReg()) + .addMBB(NewBRTarget); + BuildMI(*ThisMBB, ThisMBB->end(), BSI.SplitBefore->getDebugLoc(), + TII->get(PPC::B)) + .addMBB(NewMBB); + if (BSI.MIToDelete) + BSI.MIToDelete->eraseFromParent(); + + // Change the condition on the original branch and invert it if requested. + auto FirstTerminator = NewMBB->getFirstTerminator(); + if (BSI.NewCond) { + assert(FirstTerminator->getOperand(0).isReg() && + "Can't update condition of unconditional branch."); + FirstTerminator->getOperand(0).setReg(BSI.NewCond->getOperand(0).getReg()); + } + if (BSI.InvertOrigBranch) + FirstTerminator->setDesc(TII->get(InvertedOpcode)); + + // If any of the PHIs in the successors of NewMBB reference values that + // now come from NewMBB, they need to be updated. + for (auto *Succ : NewMBB->successors()) { + updatePHIs(Succ, ThisMBB, NewMBB, MRI); + } + addIncomingValuesToPHIs(NewBRTarget, ThisMBB, NewMBB, MRI); + + DEBUG(dbgs() << "After splitting, ThisMBB:\n"; ThisMBB->dump()); + DEBUG(dbgs() << "NewMBB:\n"; NewMBB->dump()); + DEBUG(dbgs() << "New branch-to block:\n"; NewBRTarget->dump()); + return true; +} static bool isBinary(MachineInstr &MI) { return MI.getNumOperands() == 3; @@ -149,6 +320,8 @@ computeBranchTargetAndInversion(unsigned CROp, unsigned BROp, bool UsingDef1, llvm_unreachable("Don't know how to handle this branch."); } +namespace { + class PPCReduceCRLogicals : public MachineFunctionPass { public: