[PATCH] Separate Machine IR from CodeGen: Move SplitCriticalEdge out of MachineBasicBlock
Alex L
arphaman at gmail.com
Wed May 27 11:36:01 PDT 2015
2015-05-27 10:15 GMT-07:00 Duncan P. N. Exon Smith <dexonsmith at apple.com>:
>
> > On 2015 May 27, at 09:49, Alex Lorenz <arphaman at gmail.com> wrote:
> >
> > Hi dexonsmith, bogner, bob.wilson,
> >
> > This patch is related to my proposal for separating machine IR from
> CodeGen: http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-May/086063.html.
> >
> > This patch moves the SplitCriticalEdge method out of MachineBasicBlock
> class so that MachineBasicBlock.cpp won't have to include several header
> > files that declare passes that won't be moved from CodeGen to the new
> Machine IR library.
> >
> > REPOSITORY
> > rL LLVM
> >
> > http://reviews.llvm.org/D10064
> >
> > Files:
> > include/llvm/CodeGen/MachineBasicBlock.h
> > include/llvm/CodeGen/MachineIRUtils.h
> > lib/CodeGen/CMakeLists.txt
> > lib/CodeGen/MachineBasicBlock.cpp
> > lib/CodeGen/MachineIRUtils.cpp
> > lib/CodeGen/MachineLICM.cpp
> > lib/CodeGen/MachineSink.cpp
> > lib/CodeGen/PHIElimination.cpp
> >
> > EMAIL PREFERENCES
> > http://reviews.llvm.org/settings/panel/emailpreferences/
> > <D10064.26608.patch>
>
> > Index: include/llvm/CodeGen/MachineBasicBlock.h
> > ===================================================================
> > --- include/llvm/CodeGen/MachineBasicBlock.h
> > +++ include/llvm/CodeGen/MachineBasicBlock.h
> > @@ -21,7 +21,6 @@
> >
> > namespace llvm {
> >
> > -class Pass;
> > class BasicBlock;
> > class MachineFunction;
> > class MCSymbol;
> > @@ -472,14 +471,6 @@
> > iterator getLastNonDebugInstr();
> > const_iterator getLastNonDebugInstr() const;
> >
> > - /// SplitCriticalEdge - Split the critical edge from this block to the
> > - /// given successor block, and return the newly created block, or null
> > - /// if splitting is not possible.
> > - ///
> > - /// This function updates LiveVariables, MachineDominatorTree, and
> > - /// MachineLoopInfo, as applicable.
> > - MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass
> *P);
> > -
> > void pop_front() { Insts.pop_front(); }
> > void pop_back() { Insts.pop_back(); }
> > void push_back(MachineInstr *MI) { Insts.push_back(MI); }
> > Index: include/llvm/CodeGen/MachineIRUtils.h
> > ===================================================================
> > --- /dev/null
> > +++ include/llvm/CodeGen/MachineIRUtils.h
>
> This name is pretty generic. Is there a list of things you're planning
> to add here? If not, `SplitCriticalEdge.h` seems like a better name.
> If so, it'd be good to get a high-level view of all the code motion
> you're going to do up front.
>
You're right about this. I wasn't sure about what will have to be moved
and decoupled when I was working on this patch, but now I have a
good idea of those things, so I think the generic name isn't required here.
I renamed the file in the updated patch.
>
> > @@ -0,0 +1,38 @@
> > +//===-- llvm/CodeGen/MachineIRUtils.h ---------------------------*- C++
> -*-===//
> > +//
> > +// The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This file contains the declarations of functions that implement
> machine IR
> > +// utility algorithms.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_CODEGEN_MACHINEIRUTILS_H
> > +#define LLVM_CODEGEN_MACHINEIRUTILS_H
> > +
> > +namespace llvm {
> > +
> > +class Pass;
> > +class MachineBasicBlock;
> > +
> > +namespace MachineIRUtils {
>
> Do we need the extra namespace?
>
> > +
> > +/// SplitCriticalEdge - Split the critical edge from this block to the
>
> Since you're moving this anyway, please fix up the old-style comment
> (stop repeating the function name).
>
> Also, the comment talks about "this" block, but should probably refer
> to "BB".
>
> > +/// given successor block, and return the newly created block, or null
> > +/// if splitting is not possible.
> > +///
> > +/// This function updates LiveVariables, MachineDominatorTree, and
> > +/// MachineLoopInfo, as applicable.
> > +MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *BB,
> > + MachineBasicBlock *Succ, Pass *P);
>
> Since you're moving this and updating all the callers anyway, please
> take the opportunity to fix the function name. It should be
> `splitCriticalEdge()`.
>
> > +
> > +} // End namespace MachineIRUtils
> > +
> > +} // End namespace llvm
> > +
> > +#endif
> > Index: lib/CodeGen/CMakeLists.txt
> > ===================================================================
> > --- lib/CodeGen/CMakeLists.txt
> > +++ lib/CodeGen/CMakeLists.txt
> > @@ -58,6 +58,7 @@
> > MachineFunctionPrinterPass.cpp
> > MachineInstr.cpp
> > MachineInstrBundle.cpp
> > + MachineIRUtils.cpp
> > MachineLICM.cpp
> > MachineLoopInfo.cpp
> > MachineModuleInfo.cpp
> > Index: lib/CodeGen/MachineBasicBlock.cpp
> > ===================================================================
> > --- lib/CodeGen/MachineBasicBlock.cpp
> > +++ lib/CodeGen/MachineBasicBlock.cpp
> > @@ -14,12 +14,8 @@
> > #include "llvm/CodeGen/MachineBasicBlock.h"
> > #include "llvm/ADT/SmallPtrSet.h"
> > #include "llvm/ADT/SmallString.h"
> > -#include "llvm/CodeGen/LiveIntervalAnalysis.h"
> > -#include "llvm/CodeGen/LiveVariables.h"
> > -#include "llvm/CodeGen/MachineDominators.h"
> > #include "llvm/CodeGen/MachineFunction.h"
> > #include "llvm/CodeGen/MachineInstrBuilder.h"
> > -#include "llvm/CodeGen/MachineLoopInfo.h"
> > #include "llvm/CodeGen/MachineRegisterInfo.h"
> > #include "llvm/CodeGen/SlotIndexes.h"
> > #include "llvm/IR/BasicBlock.h"
> > @@ -664,270 +660,6 @@
> > return FBB == nullptr;
> > }
> >
> > -MachineBasicBlock *
> > -MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
> > - // Splitting the critical edge to a landing pad block is non-trivial.
> Don't do
> > - // it in this generic function.
> > - if (Succ->isLandingPad())
> > - return nullptr;
> > -
> > - MachineFunction *MF = getParent();
> > - DebugLoc dl; // FIXME: this is nowhere
> > -
> > - // Performance might be harmed on HW that implements branching using
> exec mask
> > - // where both sides of the branches are always executed.
> > - if (MF->getTarget().requiresStructuredCFG())
> > - return nullptr;
> > -
> > - // We may need to update this's terminator, but we can't do that if
> > - // AnalyzeBranch fails. If this uses a jump table, we won't touch it.
> > - const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
> > - MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
> > - SmallVector<MachineOperand, 4> Cond;
> > - if (TII->AnalyzeBranch(*this, TBB, FBB, Cond))
> > - return nullptr;
> > -
> > - // Avoid bugpoint weirdness: A block may end with a conditional
> branch but
> > - // jumps to the same MBB is either case. We have duplicate CFG edges
> in that
> > - // case that we can't handle. Since this never happens in properly
> optimized
> > - // code, just skip those edges.
> > - if (TBB && TBB == FBB) {
> > - DEBUG(dbgs() << "Won't split critical edge after degenerate BB#"
> > - << getNumber() << '\n');
> > - return nullptr;
> > - }
> > -
> > - MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();
> > - MF->insert(std::next(MachineFunction::iterator(this)), NMBB);
> > - DEBUG(dbgs() << "Splitting critical edge:"
> > - " BB#" << getNumber()
> > - << " -- BB#" << NMBB->getNumber()
> > - << " -- BB#" << Succ->getNumber() << '\n');
> > -
> > - LiveIntervals *LIS = P->getAnalysisIfAvailable<LiveIntervals>();
> > - SlotIndexes *Indexes = P->getAnalysisIfAvailable<SlotIndexes>();
> > - if (LIS)
> > - LIS->insertMBBInMaps(NMBB);
> > - else if (Indexes)
> > - Indexes->insertMBBInMaps(NMBB);
> > -
> > - // On some targets like Mips, branches may kill virtual registers.
> Make sure
> > - // that LiveVariables is properly updated after updateTerminator
> replaces the
> > - // terminators.
> > - LiveVariables *LV = P->getAnalysisIfAvailable<LiveVariables>();
> > -
> > - // Collect a list of virtual registers killed by the terminators.
> > - SmallVector<unsigned, 4> KilledRegs;
> > - if (LV)
> > - for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
> > - I != E; ++I) {
> > - MachineInstr *MI = I;
> > - for (MachineInstr::mop_iterator OI = MI->operands_begin(),
> > - OE = MI->operands_end(); OI != OE; ++OI) {
> > - if (!OI->isReg() || OI->getReg() == 0 ||
> > - !OI->isUse() || !OI->isKill() || OI->isUndef())
> > - continue;
> > - unsigned Reg = OI->getReg();
> > - if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
> > - LV->getVarInfo(Reg).removeKill(MI)) {
> > - KilledRegs.push_back(Reg);
> > - DEBUG(dbgs() << "Removing terminator kill: " << *MI);
> > - OI->setIsKill(false);
> > - }
> > - }
> > - }
> > -
> > - SmallVector<unsigned, 4> UsedRegs;
> > - if (LIS) {
> > - for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
> > - I != E; ++I) {
> > - MachineInstr *MI = I;
> > -
> > - for (MachineInstr::mop_iterator OI = MI->operands_begin(),
> > - OE = MI->operands_end(); OI != OE; ++OI) {
> > - if (!OI->isReg() || OI->getReg() == 0)
> > - continue;
> > -
> > - unsigned Reg = OI->getReg();
> > - if (std::find(UsedRegs.begin(), UsedRegs.end(), Reg) ==
> UsedRegs.end())
> > - UsedRegs.push_back(Reg);
> > - }
> > - }
> > - }
> > -
> > - ReplaceUsesOfBlockWith(Succ, NMBB);
> > -
> > - // If updateTerminator() removes instructions, we need to remove them
> from
> > - // SlotIndexes.
> > - SmallVector<MachineInstr*, 4> Terminators;
> > - if (Indexes) {
> > - for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
> > - I != E; ++I)
> > - Terminators.push_back(I);
> > - }
> > -
> > - updateTerminator();
> > -
> > - if (Indexes) {
> > - SmallVector<MachineInstr*, 4> NewTerminators;
> > - for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
> > - I != E; ++I)
> > - NewTerminators.push_back(I);
> > -
> > - for (SmallVectorImpl<MachineInstr*>::iterator I =
> Terminators.begin(),
> > - E = Terminators.end(); I != E; ++I) {
> > - if (std::find(NewTerminators.begin(), NewTerminators.end(), *I) ==
> > - NewTerminators.end())
> > - Indexes->removeMachineInstrFromMaps(*I);
> > - }
> > - }
> > -
> > - // Insert unconditional "jump Succ" instruction in NMBB if necessary.
> > - NMBB->addSuccessor(Succ);
> > - if (!NMBB->isLayoutSuccessor(Succ)) {
> > - Cond.clear();
> > - MF->getSubtarget().getInstrInfo()->InsertBranch(*NMBB, Succ,
> nullptr, Cond,
> > - dl);
> > -
> > - if (Indexes) {
> > - for (instr_iterator I = NMBB->instr_begin(), E =
> NMBB->instr_end();
> > - I != E; ++I) {
> > - // Some instructions may have been moved to NMBB by
> updateTerminator(),
> > - // so we first remove any instruction that already has an index.
> > - if (Indexes->hasIndex(I))
> > - Indexes->removeMachineInstrFromMaps(I);
> > - Indexes->insertMachineInstrInMaps(I);
> > - }
> > - }
> > - }
> > -
> > - // Fix PHI nodes in Succ so they refer to NMBB instead of this
> > - for (MachineBasicBlock::instr_iterator
> > - i = Succ->instr_begin(),e = Succ->instr_end();
> > - i != e && i->isPHI(); ++i)
> > - for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2)
> > - if (i->getOperand(ni+1).getMBB() == this)
> > - i->getOperand(ni+1).setMBB(NMBB);
> > -
> > - // Inherit live-ins from the successor
> > - for (MachineBasicBlock::livein_iterator I = Succ->livein_begin(),
> > - E = Succ->livein_end(); I != E; ++I)
> > - NMBB->addLiveIn(*I);
> > -
> > - // Update LiveVariables.
> > - const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
> > - if (LV) {
> > - // Restore kills of virtual registers that were killed by the
> terminators.
> > - while (!KilledRegs.empty()) {
> > - unsigned Reg = KilledRegs.pop_back_val();
> > - for (instr_iterator I = instr_end(), E = instr_begin(); I != E;) {
> > - if (!(--I)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */
> false))
> > - continue;
> > - if (TargetRegisterInfo::isVirtualRegister(Reg))
> > - LV->getVarInfo(Reg).Kills.push_back(I);
> > - DEBUG(dbgs() << "Restored terminator kill: " << *I);
> > - break;
> > - }
> > - }
> > - // Update relevant live-through information.
> > - LV->addNewBlock(NMBB, this, Succ);
> > - }
> > -
> > - if (LIS) {
> > - // After splitting the edge and updating SlotIndexes, live
> intervals may be
> > - // in one of two situations, depending on whether this block was
> the last in
> > - // the function. If the original block was the last in the
> function, all live
> > - // intervals will end prior to the beginning of the new split
> block. If the
> > - // original block was not at the end of the function, all live
> intervals will
> > - // extend to the end of the new split block.
> > -
> > - bool isLastMBB =
> > - std::next(MachineFunction::iterator(NMBB)) == getParent()->end();
> > -
> > - SlotIndex StartIndex = Indexes->getMBBEndIdx(this);
> > - SlotIndex PrevIndex = StartIndex.getPrevSlot();
> > - SlotIndex EndIndex = Indexes->getMBBEndIdx(NMBB);
> > -
> > - // Find the registers used from NMBB in PHIs in Succ.
> > - SmallSet<unsigned, 8> PHISrcRegs;
> > - for (MachineBasicBlock::instr_iterator
> > - I = Succ->instr_begin(), E = Succ->instr_end();
> > - I != E && I->isPHI(); ++I) {
> > - for (unsigned ni = 1, ne = I->getNumOperands(); ni != ne; ni +=
> 2) {
> > - if (I->getOperand(ni+1).getMBB() == NMBB) {
> > - MachineOperand &MO = I->getOperand(ni);
> > - unsigned Reg = MO.getReg();
> > - PHISrcRegs.insert(Reg);
> > - if (MO.isUndef())
> > - continue;
> > -
> > - LiveInterval &LI = LIS->getInterval(Reg);
> > - VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
> > - assert(VNI && "PHI sources should be live out of their
> predecessors.");
> > - LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex,
> VNI));
> > - }
> > - }
> > - }
> > -
> > - MachineRegisterInfo *MRI = &getParent()->getRegInfo();
> > - for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
> > - unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
> > - if (PHISrcRegs.count(Reg) || !LIS->hasInterval(Reg))
> > - continue;
> > -
> > - LiveInterval &LI = LIS->getInterval(Reg);
> > - if (!LI.liveAt(PrevIndex))
> > - continue;
> > -
> > - bool isLiveOut = LI.liveAt(LIS->getMBBStartIdx(Succ));
> > - if (isLiveOut && isLastMBB) {
> > - VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
> > - assert(VNI && "LiveInterval should have VNInfo where it is
> live.");
> > - LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
> > - } else if (!isLiveOut && !isLastMBB) {
> > - LI.removeSegment(StartIndex, EndIndex);
> > - }
> > - }
> > -
> > - // Update all intervals for registers whose uses may have been
> modified by
> > - // updateTerminator().
> > - LIS->repairIntervalsInRange(this, getFirstTerminator(), end(),
> UsedRegs);
> > - }
> > -
> > - if (MachineDominatorTree *MDT =
> > - P->getAnalysisIfAvailable<MachineDominatorTree>())
> > - MDT->recordSplitCriticalEdge(this, Succ, NMBB);
> > -
> > - if (MachineLoopInfo *MLI =
> P->getAnalysisIfAvailable<MachineLoopInfo>())
> > - if (MachineLoop *TIL = MLI->getLoopFor(this)) {
> > - // If one or the other blocks were not in a loop, the new block
> is not
> > - // either, and thus LI doesn't need to be updated.
> > - if (MachineLoop *DestLoop = MLI->getLoopFor(Succ)) {
> > - if (TIL == DestLoop) {
> > - // Both in the same loop, the NMBB joins loop.
> > - DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase());
> > - } else if (TIL->contains(DestLoop)) {
> > - // Edge from an outer loop to an inner loop. Add to the
> outer loop.
> > - TIL->addBasicBlockToLoop(NMBB, MLI->getBase());
> > - } else if (DestLoop->contains(TIL)) {
> > - // Edge from an inner loop to an outer loop. Add to the
> outer loop.
> > - DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase());
> > - } else {
> > - // Edge from two loops with no containment relation. Because
> these
> > - // are natural loops, we know that the destination block must
> be the
> > - // header of its loop (adding a branch into a loop elsewhere
> would
> > - // create an irreducible loop).
> > - assert(DestLoop->getHeader() == Succ &&
> > - "Should not create irreducible loops!");
> > - if (MachineLoop *P = DestLoop->getParentLoop())
> > - P->addBasicBlockToLoop(NMBB, MLI->getBase());
> > - }
> > - }
> > - }
> > -
> > - return NMBB;
> > -}
> > -
> > /// Prepare MI to be removed from its bundle. This fixes bundle flags
> on MI's
> > /// neighboring instructions so the bundle won't be broken by removing
> MI.
> > static void unbundleSingleMI(MachineInstr *MI) {
> > Index: lib/CodeGen/MachineIRUtils.cpp
> > ===================================================================
> > --- /dev/null
> > +++ lib/CodeGen/MachineIRUtils.cpp
> > @@ -0,0 +1,308 @@
> > +//===-- llvm/CodeGen/MachineIRUtils.cpp -------------------------*- C++
> -*-===//
> > +//
> > +// The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This file implements the implement machine IR utility algorithms.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "llvm/CodeGen/MachineIRUtils.h"
> > +#include "llvm/CodeGen/LiveIntervalAnalysis.h"
> > +#include "llvm/CodeGen/LiveVariables.h"
> > +#include "llvm/CodeGen/MachineDominators.h"
> > +#include "llvm/CodeGen/MachineFunction.h"
> > +#include "llvm/CodeGen/MachineLoopInfo.h"
> > +#include "llvm/CodeGen/MachineRegisterInfo.h"
> > +#include "llvm/CodeGen/SlotIndexes.h"
> > +#include "llvm/Support/Debug.h"
> > +#include "llvm/Support/raw_ostream.h"
> > +#include "llvm/Target/TargetInstrInfo.h"
> > +#include "llvm/Target/TargetMachine.h"
> > +#include "llvm/Target/TargetRegisterInfo.h"
> > +#include <algorithm>
> > +using namespace llvm;
> > +
> > +#define DEBUG_TYPE "codegen"
> > +
> > +MachineBasicBlock *MachineIRUtils::SplitCriticalEdge(MachineBasicBlock
> *BB,
> > + MachineBasicBlock
> *Succ,
> > + Pass *P) {
> > + // Splitting the critical edge to a landing pad block is non-trivial.
> Don't do
> > + // it in this generic function.
> > + if (Succ->isLandingPad())
> > + return nullptr;
> > +
> > + MachineFunction *MF = BB->getParent();
> > + DebugLoc dl; // FIXME: this is nowhere
> > +
> > + // Performance might be harmed on HW that implements branching using
> exec mask
> > + // where both sides of the branches are always executed.
> > + if (MF->getTarget().requiresStructuredCFG())
> > + return nullptr;
> > +
> > + // We may need to update this's terminator, but we can't do that if
> > + // AnalyzeBranch fails. If this uses a jump table, we won't touch it.
> > + const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
> > + MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
> > + SmallVector<MachineOperand, 4> Cond;
> > + if (TII->AnalyzeBranch(*BB, TBB, FBB, Cond))
> > + return nullptr;
> > +
> > + // Avoid bugpoint weirdness: A block may end with a conditional
> branch but
> > + // jumps to the same MBB is either case. We have duplicate CFG edges
> in that
> > + // case that we can't handle. Since this never happens in properly
> optimized
> > + // code, just skip those edges.
> > + if (TBB && TBB == FBB) {
> > + DEBUG(dbgs() << "Won't split critical edge after degenerate BB#"
> > + << BB->getNumber() << '\n');
> > + return nullptr;
> > + }
> > +
> > + MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();
> > + MF->insert(std::next(MachineFunction::iterator(BB)), NMBB);
> > + DEBUG(dbgs() << "Splitting critical edge:"
> > + " BB#" << BB->getNumber() << " -- BB#" <<
> NMBB->getNumber()
> > + << " -- BB#" << Succ->getNumber() << '\n');
> > +
> > + LiveIntervals *LIS = P->getAnalysisIfAvailable<LiveIntervals>();
> > + SlotIndexes *Indexes = P->getAnalysisIfAvailable<SlotIndexes>();
> > + if (LIS)
> > + LIS->insertMBBInMaps(NMBB);
> > + else if (Indexes)
> > + Indexes->insertMBBInMaps(NMBB);
> > +
> > + // On some targets like Mips, branches may kill virtual registers.
> Make sure
> > + // that LiveVariables is properly updated after updateTerminator
> replaces the
> > + // terminators.
> > + LiveVariables *LV = P->getAnalysisIfAvailable<LiveVariables>();
> > +
> > + // Collect a list of virtual registers killed by the terminators.
> > + SmallVector<unsigned, 4> KilledRegs;
> > + if (LV)
> > + for (MachineBasicBlock::instr_iterator I =
> BB->getFirstInstrTerminator(),
> > + E = BB->instr_end();
> > + I != E; ++I) {
> > + MachineInstr *MI = I;
> > + for (MachineInstr::mop_iterator OI = MI->operands_begin(),
> > + OE = MI->operands_end();
> > + OI != OE; ++OI) {
> > + if (!OI->isReg() || OI->getReg() == 0 || !OI->isUse() ||
> > + !OI->isKill() || OI->isUndef())
> > + continue;
> > + unsigned Reg = OI->getReg();
> > + if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
> > + LV->getVarInfo(Reg).removeKill(MI)) {
> > + KilledRegs.push_back(Reg);
> > + DEBUG(dbgs() << "Removing terminator kill: " << *MI);
> > + OI->setIsKill(false);
> > + }
> > + }
> > + }
> > +
> > + SmallVector<unsigned, 4> UsedRegs;
> > + if (LIS) {
> > + for (MachineBasicBlock::instr_iterator I =
> BB->getFirstInstrTerminator(),
> > + E = BB->instr_end();
> > + I != E; ++I) {
> > + MachineInstr *MI = I;
> > +
> > + for (MachineInstr::mop_iterator OI = MI->operands_begin(),
> > + OE = MI->operands_end();
> > + OI != OE; ++OI) {
> > + if (!OI->isReg() || OI->getReg() == 0)
> > + continue;
> > +
> > + unsigned Reg = OI->getReg();
> > + if (std::find(UsedRegs.begin(), UsedRegs.end(), Reg) ==
> UsedRegs.end())
> > + UsedRegs.push_back(Reg);
> > + }
> > + }
> > + }
> > +
> > + BB->ReplaceUsesOfBlockWith(Succ, NMBB);
> > +
> > + // If updateTerminator() removes instructions, we need to remove them
> from
> > + // SlotIndexes.
> > + SmallVector<MachineInstr *, 4> Terminators;
> > + if (Indexes) {
> > + for (MachineBasicBlock::instr_iterator I =
> BB->getFirstInstrTerminator(),
> > + E = BB->instr_end();
> > + I != E; ++I)
> > + Terminators.push_back(I);
> > + }
> > +
> > + BB->updateTerminator();
> > +
> > + if (Indexes) {
> > + SmallVector<MachineInstr *, 4> NewTerminators;
> > + for (MachineBasicBlock::instr_iterator I =
> BB->getFirstInstrTerminator(),
> > + E = BB->instr_end();
> > + I != E; ++I)
> > + NewTerminators.push_back(I);
> > +
> > + for (SmallVectorImpl<MachineInstr *>::iterator I =
> Terminators.begin(),
> > + E =
> Terminators.end();
> > + I != E; ++I) {
> > + if (std::find(NewTerminators.begin(), NewTerminators.end(), *I) ==
> > + NewTerminators.end())
> > + Indexes->removeMachineInstrFromMaps(*I);
> > + }
> > + }
> > +
> > + // Insert unconditional "jump Succ" instruction in NMBB if necessary.
> > + NMBB->addSuccessor(Succ);
> > + if (!NMBB->isLayoutSuccessor(Succ)) {
> > + Cond.clear();
> > + MF->getSubtarget().getInstrInfo()->InsertBranch(*NMBB, Succ,
> nullptr, Cond,
> > + dl);
> > +
> > + if (Indexes) {
> > + for (MachineBasicBlock::instr_iterator I = NMBB->instr_begin(),
> > + E = NMBB->instr_end();
> > + I != E; ++I) {
> > + // Some instructions may have been moved to NMBB by
> updateTerminator(),
> > + // so we first remove any instruction that already has an index.
> > + if (Indexes->hasIndex(I))
> > + Indexes->removeMachineInstrFromMaps(I);
> > + Indexes->insertMachineInstrInMaps(I);
> > + }
> > + }
> > + }
> > +
> > + // Fix PHI nodes in Succ so they refer to NMBB instead of this
> > + for (MachineBasicBlock::instr_iterator i = Succ->instr_begin(),
> > + e = Succ->instr_end();
> > + i != e && i->isPHI(); ++i)
> > + for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2)
> > + if (i->getOperand(ni + 1).getMBB() == BB)
> > + i->getOperand(ni + 1).setMBB(NMBB);
> > +
> > + // Inherit live-ins from the successor
> > + for (MachineBasicBlock::livein_iterator I = Succ->livein_begin(),
> > + E = Succ->livein_end();
> > + I != E; ++I)
> > + NMBB->addLiveIn(*I);
> > +
> > + // Update LiveVariables.
> > + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
> > + if (LV) {
> > + // Restore kills of virtual registers that were killed by the
> terminators.
> > + while (!KilledRegs.empty()) {
> > + unsigned Reg = KilledRegs.pop_back_val();
> > + for (MachineBasicBlock::instr_iterator I = BB->instr_end(),
> > + E = BB->instr_begin();
> > + I != E;) {
> > + if (!(--I)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */
> false))
> > + continue;
> > + if (TargetRegisterInfo::isVirtualRegister(Reg))
> > + LV->getVarInfo(Reg).Kills.push_back(I);
> > + DEBUG(dbgs() << "Restored terminator kill: " << *I);
> > + break;
> > + }
> > + }
> > + // Update relevant live-through information.
> > + LV->addNewBlock(NMBB, BB, Succ);
> > + }
> > +
> > + if (LIS) {
> > + // After splitting the edge and updating SlotIndexes, live
> intervals may be
> > + // in one of two situations, depending on whether this block was
> the last in
> > + // the function. If the original block was the last in the
> function, all
> > + // live
> > + // intervals will end prior to the beginning of the new split
> block. If the
> > + // original block was not at the end of the function, all live
> intervals
> > + // will
> > + // extend to the end of the new split block.
> > +
> > + bool isLastMBB = std::next(MachineFunction::iterator(NMBB)) ==
> MF->end();
> > +
> > + SlotIndex StartIndex = Indexes->getMBBEndIdx(BB);
> > + SlotIndex PrevIndex = StartIndex.getPrevSlot();
> > + SlotIndex EndIndex = Indexes->getMBBEndIdx(NMBB);
> > +
> > + // Find the registers used from NMBB in PHIs in Succ.
> > + SmallSet<unsigned, 8> PHISrcRegs;
> > + for (MachineBasicBlock::instr_iterator I = Succ->instr_begin(),
> > + E = Succ->instr_end();
> > + I != E && I->isPHI(); ++I) {
> > + for (unsigned ni = 1, ne = I->getNumOperands(); ni != ne; ni +=
> 2) {
> > + if (I->getOperand(ni + 1).getMBB() == NMBB) {
> > + MachineOperand &MO = I->getOperand(ni);
> > + unsigned Reg = MO.getReg();
> > + PHISrcRegs.insert(Reg);
> > + if (MO.isUndef())
> > + continue;
> > +
> > + LiveInterval &LI = LIS->getInterval(Reg);
> > + VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
> > + assert(VNI &&
> > + "PHI sources should be live out of their
> predecessors.");
> > + LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex,
> VNI));
> > + }
> > + }
> > + }
> > +
> > + MachineRegisterInfo *MRI = &MF->getRegInfo();
> > + for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
> > + unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
> > + if (PHISrcRegs.count(Reg) || !LIS->hasInterval(Reg))
> > + continue;
> > +
> > + LiveInterval &LI = LIS->getInterval(Reg);
> > + if (!LI.liveAt(PrevIndex))
> > + continue;
> > +
> > + bool isLiveOut = LI.liveAt(LIS->getMBBStartIdx(Succ));
> > + if (isLiveOut && isLastMBB) {
> > + VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
> > + assert(VNI && "LiveInterval should have VNInfo where it is
> live.");
> > + LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
> > + } else if (!isLiveOut && !isLastMBB) {
> > + LI.removeSegment(StartIndex, EndIndex);
> > + }
> > + }
> > +
> > + // Update all intervals for registers whose uses may have been
> modified by
> > + // updateTerminator().
> > + LIS->repairIntervalsInRange(BB, BB->getFirstTerminator(), BB->end(),
> > + UsedRegs);
> > + }
> > +
> > + if (MachineDominatorTree *MDT =
> > + P->getAnalysisIfAvailable<MachineDominatorTree>())
> > + MDT->recordSplitCriticalEdge(BB, Succ, NMBB);
> > +
> > + if (MachineLoopInfo *MLI =
> P->getAnalysisIfAvailable<MachineLoopInfo>())
> > + if (MachineLoop *TIL = MLI->getLoopFor(BB)) {
> > + // If one or the other blocks were not in a loop, the new block
> is not
> > + // either, and thus LI doesn't need to be updated.
> > + if (MachineLoop *DestLoop = MLI->getLoopFor(Succ)) {
> > + if (TIL == DestLoop) {
> > + // Both in the same loop, the NMBB joins loop.
> > + DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase());
> > + } else if (TIL->contains(DestLoop)) {
> > + // Edge from an outer loop to an inner loop. Add to the
> outer loop.
> > + TIL->addBasicBlockToLoop(NMBB, MLI->getBase());
> > + } else if (DestLoop->contains(TIL)) {
> > + // Edge from an inner loop to an outer loop. Add to the
> outer loop.
> > + DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase());
> > + } else {
> > + // Edge from two loops with no containment relation. Because
> these
> > + // are natural loops, we know that the destination block must
> be the
> > + // header of its loop (adding a branch into a loop elsewhere
> would
> > + // create an irreducible loop).
> > + assert(DestLoop->getHeader() == Succ &&
> > + "Should not create irreducible loops!");
> > + if (MachineLoop *P = DestLoop->getParentLoop())
> > + P->addBasicBlockToLoop(NMBB, MLI->getBase());
> > + }
> > + }
> > + }
> > +
> > + return NMBB;
> > +}
> > Index: lib/CodeGen/MachineLICM.cpp
> > ===================================================================
> > --- lib/CodeGen/MachineLICM.cpp
> > +++ lib/CodeGen/MachineLICM.cpp
> > @@ -23,6 +23,7 @@
> > #include "llvm/Analysis/AliasAnalysis.h"
> > #include "llvm/CodeGen/MachineDominators.h"
> > #include "llvm/CodeGen/MachineFrameInfo.h"
> > +#include "llvm/CodeGen/MachineIRUtils.h"
> > #include "llvm/CodeGen/MachineLoopInfo.h"
> > #include "llvm/CodeGen/MachineMemOperand.h"
> > #include "llvm/CodeGen/MachineRegisterInfo.h"
> > @@ -1459,7 +1460,8 @@
> > return nullptr;
> > }
> >
> > - CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(),
> this);
> > + CurPreheader =
> > + MachineIRUtils::SplitCriticalEdge(Pred, CurLoop->getHeader(),
> this);
> > if (!CurPreheader) {
> > CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
> > return nullptr;
> > Index: lib/CodeGen/MachineSink.cpp
> > ===================================================================
> > --- lib/CodeGen/MachineSink.cpp
> > +++ lib/CodeGen/MachineSink.cpp
> > @@ -24,6 +24,7 @@
> > #include "llvm/Analysis/AliasAnalysis.h"
> > #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
> > #include "llvm/CodeGen/MachineDominators.h"
> > +#include "llvm/CodeGen/MachineIRUtils.h"
> > #include "llvm/CodeGen/MachineLoopInfo.h"
> > #include "llvm/CodeGen/MachinePostDominators.h"
> > #include "llvm/CodeGen/MachineRegisterInfo.h"
> > @@ -275,7 +276,8 @@
> >
> > // If we have anything we marked as toSplit, split it now.
> > for (auto &Pair : ToSplit) {
> > - auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, this);
> > + auto NewSucc =
> > + MachineIRUtils::SplitCriticalEdge(Pair.first, Pair.second,
> this);
> > if (NewSucc != nullptr) {
> > DEBUG(dbgs() << " *** Splitting critical edge:"
> > " BB#" << Pair.first->getNumber()
> > Index: lib/CodeGen/PHIElimination.cpp
> > ===================================================================
> > --- lib/CodeGen/PHIElimination.cpp
> > +++ lib/CodeGen/PHIElimination.cpp
> > @@ -23,6 +23,7 @@
> > #include "llvm/CodeGen/MachineDominators.h"
> > #include "llvm/CodeGen/MachineInstr.h"
> > #include "llvm/CodeGen/MachineInstrBuilder.h"
> > +#include "llvm/CodeGen/MachineIRUtils.h"
> > #include "llvm/CodeGen/MachineLoopInfo.h"
> > #include "llvm/CodeGen/MachineRegisterInfo.h"
> > #include "llvm/IR/Function.h"
> > @@ -612,7 +613,7 @@
> > }
> > if (!ShouldSplit && !SplitAllCriticalEdges)
> > continue;
> > - if (!PreMBB->SplitCriticalEdge(&MBB, this)) {
> > + if (!MachineIRUtils::SplitCriticalEdge(PreMBB, &MBB, this)) {
> > DEBUG(dbgs() << "Failed to split critical edge.\n");
> > continue;
> > }
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150527/bc25ccac/attachment.html>
More information about the llvm-commits
mailing list