#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
STATISTIC(UncondBranchTakenFreq,
"Potential frequency of taking unconditional branches");
+static cl::opt<unsigned> AlignAllBlock("align-all-blocks",
+ cl::desc("Force the alignment of all "
+ "blocks in the function."),
+ cl::init(0), cl::Hidden);
+
+// FIXME: Find a good default for this flag and remove the flag.
+static cl::opt<unsigned>
+ExitBlockBias("block-placement-exit-block-bias",
+ cl::desc("Block frequency percentage a loop exit block needs "
+ "over the original exit to be considered the new exit."),
+ cl::init(0), cl::Hidden);
+
namespace {
class BlockChain;
/// \brief Type for our function-wide basic block -> block chain mapping.
#ifndef NDEBUG
/// \brief Dump the blocks in this chain.
- void dump() LLVM_ATTRIBUTE_USED {
+ LLVM_DUMP_METHOD void dump() {
for (iterator I = begin(), E = end(); I != E; ++I)
(*I)->dump();
}
const TargetInstrInfo *TII;
/// \brief A handle to the target's lowering info.
- const TargetLowering *TLI;
+ const TargetLoweringBase *TLI;
/// \brief Allocator and owner of BlockChain structures.
///
// any CFG constraints.
if (SuccChain.LoopPredecessors != 0) {
if (SuccProb < HotProb) {
- DEBUG(dbgs() << " " << getBlockName(*SI) << " -> CFG conflict\n");
+ DEBUG(dbgs() << " " << getBlockName(*SI) << " -> " << SuccProb
+ << " (prob) (CFG conflict)\n");
continue;
}
}
}
if (BadCFGConflict) {
- DEBUG(dbgs() << " " << getBlockName(*SI)
- << " -> non-cold CFG conflict\n");
+ DEBUG(dbgs() << " " << getBlockName(*SI) << " -> " << SuccProb
+ << " (prob) (non-cold CFG conflict)\n");
continue;
}
}
assert(SuccChain.LoopPredecessors == 0 && "Found CFG-violating block");
BlockFrequency CandidateFreq = MBFI->getBlockFreq(*WBI);
- DEBUG(dbgs() << " " << getBlockName(*WBI) << " -> " << CandidateFreq
- << " (freq)\n");
+ DEBUG(dbgs() << " " << getBlockName(*WBI) << " -> ";
+ MBFI->printBlockFreq(dbgs(), CandidateFreq) << " (freq)\n");
if (BestBlock && BestFreq >= CandidateFreq)
continue;
BestBlock = *WBI;
if (!LoopBlockSet.count(Pred))
continue;
DEBUG(dbgs() << " header pred: " << getBlockName(Pred) << ", "
- << Pred->succ_size() << " successors, "
- << MBFI->getBlockFreq(Pred) << " freq\n");
+ << Pred->succ_size() << " successors, ";
+ MBFI->printBlockFreq(dbgs(), Pred) << " freq\n");
if (Pred->succ_size() > 1)
continue;
BlockFrequency ExitEdgeFreq = MBFI->getBlockFreq(*I) * SuccProb;
DEBUG(dbgs() << " exiting: " << getBlockName(*I) << " -> "
<< getBlockName(*SI) << " [L:" << SuccLoopDepth
- << "] (" << ExitEdgeFreq << ")\n");
- // Note that we slightly bias this toward an existing layout successor to
- // retain incoming order in the absence of better information.
- // FIXME: Should we bias this more strongly? It's pretty weak.
+ << "] (";
+ MBFI->printBlockFreq(dbgs(), ExitEdgeFreq) << ")\n");
+ // Note that we bias this toward an existing layout successor to retain
+ // incoming order in the absence of better information. The exit must have
+ // a frequency higher than the current exit before we consider breaking
+ // the layout.
+ BranchProbability Bias(100 - ExitBlockBias, 100);
if (!ExitingBB || BestExitLoopDepth < SuccLoopDepth ||
ExitEdgeFreq > BestExitEdgeFreq ||
((*I)->isLayoutSuccessor(*SI) &&
- !(ExitEdgeFreq < BestExitEdgeFreq))) {
+ !(ExitEdgeFreq < BestExitEdgeFreq * Bias))) {
BestExitEdgeFreq = ExitEdgeFreq;
ExitingBB = *I;
}
BlockChain &FunctionChain = *BlockToChain[&F.front()];
buildChain(&F.front(), FunctionChain, BlockWorkList);
+#ifndef NDEBUG
typedef SmallPtrSet<MachineBasicBlock *, 16> FunctionBlockSetType;
+#endif
DEBUG({
// Crash at the end so we get all of the debugging output first.
bool BadFunc = false;
Cond.clear();
MachineBasicBlock *TBB = 0, *FBB = 0; // For AnalyzeBranch.
if (!TII->AnalyzeBranch(*PrevBB, TBB, FBB, Cond)) {
+ // The "PrevBB" is not yet updated to reflect current code layout, so,
+ // o. it may fall-through to a block without explict "goto" instruction
+ // before layout, and no longer fall-through it after layout; or
+ // o. just opposite.
+ //
+ // AnalyzeBranch() may return erroneous value for FBB when these two
+ // situations take place. For the first scenario FBB is mistakenly set
+ // NULL; for the 2nd scenario, the FBB, which is expected to be NULL,
+ // is mistakenly pointing to "*BI".
+ //
+ bool needUpdateBr = true;
+ if (!Cond.empty() && (!FBB || FBB == *BI)) {
+ PrevBB->updateTerminator();
+ needUpdateBr = false;
+ Cond.clear();
+ TBB = FBB = 0;
+ if (TII->AnalyzeBranch(*PrevBB, TBB, FBB, Cond)) {
+ // FIXME: This should never take place.
+ TBB = FBB = 0;
+ }
+ }
+
// If PrevBB has a two-way branch, try to re-order the branches
// such that we branch to the successor with higher weight first.
if (TBB && !Cond.empty() && FBB &&
DebugLoc dl; // FIXME: this is nowhere
TII->RemoveBranch(*PrevBB);
TII->InsertBranch(*PrevBB, FBB, TBB, Cond, dl);
+ needUpdateBr = true;
}
- PrevBB->updateTerminator();
+ if (needUpdateBr)
+ PrevBB->updateTerminator();
}
}
}
// Align this block if the layout predecessor's edge into this block is
- // cold relative to the block. When this is true, othe predecessors make up
+ // cold relative to the block. When this is true, other predecessors make up
// all of the hot entries into the block and thus alignment is likely to be
// important.
BranchProbability LayoutProb = MBPI->getEdgeProbability(LayoutPred, *BI);
BlockToChain.clear();
ChainAllocator.DestroyAll();
+ if (AlignAllBlock)
+ // Align all of the blocks in the function to a specific alignment.
+ for (MachineFunction::iterator FI = F.begin(), FE = F.end();
+ FI != FE; ++FI)
+ FI->setAlignment(AlignAllBlock);
+
// We always return true as we have no way to track whether the final order
// differs from the original order.
return true;