Skip to content

Commit

Permalink
Codegen: Tail-duplicate during placement.
Browse files Browse the repository at this point in the history
The tail duplication pass uses an assumed layout when making duplication
decisions. This is fine, but passes up duplication opportunities that
may arise when blocks are outlined. Because we want the updated CFG to
affect subsequent placement decisions, this change must occur during
placement.

In order to achieve this goal, TailDuplicationPass is split into a
utility class, TailDuplicator, and the pass itself. The pass delegates
nearly everything to the TailDuplicator object, except for looping over
the blocks in a function. This allows the same code to be used for tail
duplication in both places.

This change, in concert with outlining optional branches, allows
triangle shaped code to perform much better, esepecially when the
taken/untaken branches are correlated, as it creates a second spine when
the tests are small enough.

Issue from previous rollback fixed, and a new test was added for that
case as well. Issue was worklist/scheduling/taildup issue in layout.

Issue from 2nd rollback fixed, with 2 additional tests. Issue was
tail merging/loop info/tail-duplication causing issue with loops that share
a header block.

Differential revision: https://reviews.llvm.org/D18226

llvm-svn: 283619
  • Loading branch information
Kyle Butt committed Oct 7, 2016
1 parent 609e669 commit 37e676d
Show file tree
Hide file tree
Showing 24 changed files with 884 additions and 95 deletions.
9 changes: 7 additions & 2 deletions llvm/include/llvm/Analysis/LoopInfoImpl.h
Expand Up @@ -186,8 +186,13 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const {
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) {
assert((Blocks.empty() || LIB[getHeader()] == this) &&
"Incorrect LI specified for this loop!");
#ifndef NDEBUG
if (!Blocks.empty()) {
auto SameHeader = LIB[getHeader()];
assert(contains(SameHeader) && getHeader() == SameHeader->getHeader()
&& "Incorrect LI specified for this loop!");
}
#endif
assert(NewBB && "Cannot add a null basic block to the loop!");
assert(!LIB[NewBB] && "BasicBlock already in the loop!");

Expand Down
26 changes: 21 additions & 5 deletions llvm/include/llvm/CodeGen/TailDuplicator.h
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_CODEGEN_TAILDUPLICATOR_H
#define LLVM_CODEGEN_TAILDUPLICATOR_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
Expand All @@ -37,6 +38,7 @@ class TailDuplicator {
MachineRegisterInfo *MRI;
MachineFunction *MF;
bool PreRegAlloc;
bool LayoutMode;
unsigned TailDupSize;

// A list of virtual registers for which to update SSA form.
Expand All @@ -50,10 +52,16 @@ class TailDuplicator {

public:
/// Prepare to run on a specific machine function.
/// @param TailDupSize - Maxmimum size of blocks to tail-duplicate.
/// @param MF - Function that will be processed
/// @param MBPI - Branch Probability Info. Used to propagate correct
/// probabilities when modifying the CFG.
/// @param LayoutMode - When true, don't use the existing layout to make
/// decisions.
/// @param TailDupSize - Maxmimum size of blocks to tail-duplicate. Zero
/// default implies using the command line value TailDupSize.
void initMF(MachineFunction &MF,
const MachineBranchProbabilityInfo *MBPI,
unsigned TailDupSize = 0);
bool LayoutMode, unsigned TailDupSize = 0);
bool tailDuplicateBlocks();
static bool isSimpleBB(MachineBasicBlock *TailBB);
bool shouldTailDuplicate(bool IsSimple, MachineBasicBlock &TailBB);
Expand All @@ -63,9 +71,13 @@ class TailDuplicator {
/// up.
/// If \p DuplicatePreds is not null, it will be updated to contain the list
/// of predecessors that received a copy of \p MBB.
/// If \p RemovalCallback is non-null. It will be called before MBB is
/// deleted.
bool tailDuplicateAndUpdate(
bool IsSimple, MachineBasicBlock *MBB,
SmallVectorImpl<MachineBasicBlock*> *DuplicatedPreds = nullptr);
MachineBasicBlock *ForcedLayoutPred,
SmallVectorImpl<MachineBasicBlock*> *DuplicatedPreds = nullptr,
llvm::function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);

private:
typedef TargetInstrInfo::RegSubRegPair RegSubRegPair;
Expand All @@ -89,14 +101,18 @@ class TailDuplicator {
SmallVectorImpl<MachineBasicBlock *> &TDBBs,
const DenseSet<unsigned> &RegsUsedByPhi,
SmallVectorImpl<MachineInstr *> &Copies);
bool tailDuplicate(bool IsSimple, MachineBasicBlock *TailBB,
bool tailDuplicate(bool IsSimple,
MachineBasicBlock *TailBB,
MachineBasicBlock *ForcedLayoutPred,
SmallVectorImpl<MachineBasicBlock *> &TDBBs,
SmallVectorImpl<MachineInstr *> &Copies);
void appendCopies(MachineBasicBlock *MBB,
SmallVectorImpl<std::pair<unsigned,RegSubRegPair>> &CopyInfos,
SmallVectorImpl<MachineInstr *> &Copies);

void removeDeadBlock(MachineBasicBlock *MBB);
void removeDeadBlock(
MachineBasicBlock *MBB,
llvm::function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
};

} // End llvm namespace
Expand Down

0 comments on commit 37e676d

Please sign in to comment.