mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
Introduce MachineBranchProbabilityInfo class, which has similar API to
BranchProbabilityInfo (expect setEdgeWeight which is not available here). Branch Weights are kept in MachineBasicBlocks. To turn off this analysis set -use-mbpi=false. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133184 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1300f3019e
commit
7cc2b07437
@ -25,6 +25,11 @@ class raw_ostream;
|
|||||||
class BranchProbabilityInfo : public FunctionPass {
|
class BranchProbabilityInfo : public FunctionPass {
|
||||||
|
|
||||||
// Default weight value. Used when we don't have information about the edge.
|
// Default weight value. Used when we don't have information about the edge.
|
||||||
|
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
|
||||||
|
// the successors have a weight yet. But it doesn't make sense when providing
|
||||||
|
// weight to an edge that may have siblings with non-zero weights. This can
|
||||||
|
// be handled various ways, but it's probably fine for an edge with unknown
|
||||||
|
// weight to just "inherit" the non-zero weight of an adjacent successor.
|
||||||
static const uint32_t DEFAULT_WEIGHT = 16;
|
static const uint32_t DEFAULT_WEIGHT = 16;
|
||||||
|
|
||||||
typedef std::pair<BasicBlock *, BasicBlock *> Edge;
|
typedef std::pair<BasicBlock *, BasicBlock *> Edge;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||||
#include "llvm/CodeGen/ValueTypes.h"
|
#include "llvm/CodeGen/ValueTypes.h"
|
||||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
@ -57,7 +58,7 @@ public:
|
|||||||
const Function *Fn;
|
const Function *Fn;
|
||||||
MachineFunction *MF;
|
MachineFunction *MF;
|
||||||
MachineRegisterInfo *RegInfo;
|
MachineRegisterInfo *RegInfo;
|
||||||
|
BranchProbabilityInfo *BPI;
|
||||||
/// CanLowerReturn - true iff the function's return value can be lowered to
|
/// CanLowerReturn - true iff the function's return value can be lowered to
|
||||||
/// registers.
|
/// registers.
|
||||||
bool CanLowerReturn;
|
bool CanLowerReturn;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -27,6 +28,7 @@ class MCSymbol;
|
|||||||
class SlotIndexes;
|
class SlotIndexes;
|
||||||
class StringRef;
|
class StringRef;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
class MachineBranchProbabilityInfo;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
|
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
|
||||||
@ -69,6 +71,13 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
|||||||
std::vector<MachineBasicBlock *> Predecessors;
|
std::vector<MachineBasicBlock *> Predecessors;
|
||||||
std::vector<MachineBasicBlock *> Successors;
|
std::vector<MachineBasicBlock *> Successors;
|
||||||
|
|
||||||
|
|
||||||
|
/// Weights - Keep track of the weights to the successors. This vector
|
||||||
|
/// has the same order as Successors, or it is empty if we don't use it
|
||||||
|
/// (disable optimization).
|
||||||
|
std::vector<uint32_t> Weights;
|
||||||
|
typedef std::vector<uint32_t>::iterator weight_iterator;
|
||||||
|
|
||||||
/// LiveIns - Keep track of the physical registers that are livein of
|
/// LiveIns - Keep track of the physical registers that are livein of
|
||||||
/// the basicblock.
|
/// the basicblock.
|
||||||
std::vector<unsigned> LiveIns;
|
std::vector<unsigned> LiveIns;
|
||||||
@ -246,9 +255,11 @@ public:
|
|||||||
// Machine-CFG mutators
|
// Machine-CFG mutators
|
||||||
|
|
||||||
/// addSuccessor - Add succ as a successor of this MachineBasicBlock.
|
/// addSuccessor - Add succ as a successor of this MachineBasicBlock.
|
||||||
/// The Predecessors list of succ is automatically updated.
|
/// The Predecessors list of succ is automatically updated. WEIGHT
|
||||||
|
/// parameter is stored in Weights list and it may be used by
|
||||||
|
/// MachineBranchProbabilityInfo analysis to calculate branch probability.
|
||||||
///
|
///
|
||||||
void addSuccessor(MachineBasicBlock *succ);
|
void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
|
||||||
|
|
||||||
/// removeSuccessor - Remove successor from the successors list of this
|
/// removeSuccessor - Remove successor from the successors list of this
|
||||||
/// MachineBasicBlock. The Predecessors list of succ is automatically updated.
|
/// MachineBasicBlock. The Predecessors list of succ is automatically updated.
|
||||||
@ -261,6 +272,11 @@ public:
|
|||||||
///
|
///
|
||||||
succ_iterator removeSuccessor(succ_iterator I);
|
succ_iterator removeSuccessor(succ_iterator I);
|
||||||
|
|
||||||
|
/// replaceSuccessor - Replace successor OLD with NEW and update weight info.
|
||||||
|
///
|
||||||
|
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
|
||||||
|
|
||||||
|
|
||||||
/// transferSuccessors - Transfers all the successors from MBB to this
|
/// transferSuccessors - Transfers all the successors from MBB to this
|
||||||
/// machine basic block (i.e., copies all the successors fromMBB and
|
/// machine basic block (i.e., copies all the successors fromMBB and
|
||||||
/// remove all the successors from fromMBB).
|
/// remove all the successors from fromMBB).
|
||||||
@ -397,7 +413,21 @@ public:
|
|||||||
///
|
///
|
||||||
MCSymbol *getSymbol() const;
|
MCSymbol *getSymbol() const;
|
||||||
|
|
||||||
private: // Methods used to maintain doubly linked list of blocks...
|
|
||||||
|
private:
|
||||||
|
/// getWeightIterator - Return weight iterator corresponding to the I
|
||||||
|
/// successor iterator.
|
||||||
|
weight_iterator getWeightIterator(succ_iterator I);
|
||||||
|
|
||||||
|
friend class MachineBranchProbabilityInfo;
|
||||||
|
|
||||||
|
/// getSuccWeight - Return weight of the edge from this block to MBB. This
|
||||||
|
/// method should NOT be called directly, but by using getEdgeWeight method
|
||||||
|
/// from MachineBranchProbabilityInfo class.
|
||||||
|
uint32_t getSuccWeight(MachineBasicBlock *succ);
|
||||||
|
|
||||||
|
|
||||||
|
// Methods used to maintain doubly linked list of blocks...
|
||||||
friend struct ilist_traits<MachineBasicBlock>;
|
friend struct ilist_traits<MachineBasicBlock>;
|
||||||
|
|
||||||
// Machine-CFG mutators
|
// Machine-CFG mutators
|
||||||
|
77
include/llvm/CodeGen/MachineBranchProbabilityInfo.h
Normal file
77
include/llvm/CodeGen/MachineBranchProbabilityInfo.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This pass is used to evaluate branch probabilties on machine basic blocks.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
|
||||||
|
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
|
||||||
|
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
#include "llvm/Support/BranchProbability.h"
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class raw_ostream;
|
||||||
|
|
||||||
|
class MachineBranchProbabilityInfo : public ImmutablePass {
|
||||||
|
|
||||||
|
// Default weight value. Used when we don't have information about the edge.
|
||||||
|
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
|
||||||
|
// the successors have a weight yet. But it doesn't make sense when providing
|
||||||
|
// weight to an edge that may have siblings with non-zero weights. This can
|
||||||
|
// be handled various ways, but it's probably fine for an edge with unknown
|
||||||
|
// weight to just "inherit" the non-zero weight of an adjacent successor.
|
||||||
|
static const uint32_t DEFAULT_WEIGHT = 16;
|
||||||
|
|
||||||
|
// Get sum of the block successors' weights.
|
||||||
|
uint32_t getSumForBlock(MachineBasicBlock *MBB) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
|
||||||
|
MachineBranchProbabilityInfo() : ImmutablePass(ID) {
|
||||||
|
PassRegistry &Registry = *PassRegistry::getPassRegistry();
|
||||||
|
initializeMachineBranchProbabilityInfoPass(Registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.setPreservesAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return edge weight. If we don't have any informations about it - return
|
||||||
|
// DEFAULT_WEIGHT.
|
||||||
|
uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
|
||||||
|
|
||||||
|
// A 'Hot' edge is an edge which probability is >= 80%.
|
||||||
|
bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
|
||||||
|
|
||||||
|
// Return a hot successor for the block BB or null if there isn't one.
|
||||||
|
MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
|
||||||
|
|
||||||
|
// Return a probability as a fraction between 0 (0% probability) and
|
||||||
|
// 1 (100% probability), however the value is never equal to 0, and can be 1
|
||||||
|
// only iff SRC block has only one successor.
|
||||||
|
BranchProbability getEdgeProbability(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const;
|
||||||
|
|
||||||
|
// Print value between 0 (0% probability) and 1 (100% probability),
|
||||||
|
// however the value is never equal to 0, and can be 1 only iff SRC block
|
||||||
|
// has only one successor.
|
||||||
|
raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -144,6 +144,7 @@ void initializeLowerIntrinsicsPass(PassRegistry&);
|
|||||||
void initializeLowerInvokePass(PassRegistry&);
|
void initializeLowerInvokePass(PassRegistry&);
|
||||||
void initializeLowerSetJmpPass(PassRegistry&);
|
void initializeLowerSetJmpPass(PassRegistry&);
|
||||||
void initializeLowerSwitchPass(PassRegistry&);
|
void initializeLowerSwitchPass(PassRegistry&);
|
||||||
|
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
|
||||||
void initializeMachineCSEPass(PassRegistry&);
|
void initializeMachineCSEPass(PassRegistry&);
|
||||||
void initializeMachineDominatorTreePass(PassRegistry&);
|
void initializeMachineDominatorTreePass(PassRegistry&);
|
||||||
void initializeMachineLICMPass(PassRegistry&);
|
void initializeMachineLICMPass(PassRegistry&);
|
||||||
|
@ -348,8 +348,8 @@ getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const {
|
|||||||
raw_ostream &
|
raw_ostream &
|
||||||
BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
|
BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
|
||||||
BasicBlock *Dst) const {
|
BasicBlock *Dst) const {
|
||||||
BranchProbability Prob = getEdgeProbability(Src, Dst);
|
|
||||||
|
|
||||||
|
const BranchProbability Prob = getEdgeProbability(Src, Dst);
|
||||||
OS << "edge " << Src->getNameStr() << " -> " << Dst->getNameStr()
|
OS << "edge " << Src->getNameStr() << " -> " << Dst->getNameStr()
|
||||||
<< " probability is " << Prob
|
<< " probability is " << Prob
|
||||||
<< (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
|
<< (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
|
||||||
|
@ -33,6 +33,7 @@ add_llvm_library(LLVMCodeGen
|
|||||||
LocalStackSlotAllocation.cpp
|
LocalStackSlotAllocation.cpp
|
||||||
LowerSubregs.cpp
|
LowerSubregs.cpp
|
||||||
MachineBasicBlock.cpp
|
MachineBasicBlock.cpp
|
||||||
|
MachineBranchProbabilityInfo.cpp
|
||||||
MachineCSE.cpp
|
MachineCSE.cpp
|
||||||
MachineDominators.cpp
|
MachineDominators.cpp
|
||||||
MachineFunction.cpp
|
MachineFunction.cpp
|
||||||
|
@ -339,25 +339,64 @@ void MachineBasicBlock::updateTerminator() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineBasicBlock::addSuccessor(MachineBasicBlock *succ) {
|
void MachineBasicBlock::addSuccessor(MachineBasicBlock *succ, uint32_t weight) {
|
||||||
Successors.push_back(succ);
|
|
||||||
succ->addPredecessor(this);
|
// If we see non-zero value for the first time it means we actually use Weight
|
||||||
}
|
// list, so we fill all Weights with 0's.
|
||||||
|
if (weight != 0 && Weights.empty())
|
||||||
|
Weights.resize(Successors.size());
|
||||||
|
|
||||||
|
if (weight != 0 || !Weights.empty())
|
||||||
|
Weights.push_back(weight);
|
||||||
|
|
||||||
|
Successors.push_back(succ);
|
||||||
|
succ->addPredecessor(this);
|
||||||
|
}
|
||||||
|
|
||||||
void MachineBasicBlock::removeSuccessor(MachineBasicBlock *succ) {
|
void MachineBasicBlock::removeSuccessor(MachineBasicBlock *succ) {
|
||||||
succ->removePredecessor(this);
|
succ->removePredecessor(this);
|
||||||
succ_iterator I = std::find(Successors.begin(), Successors.end(), succ);
|
succ_iterator I = std::find(Successors.begin(), Successors.end(), succ);
|
||||||
assert(I != Successors.end() && "Not a current successor!");
|
assert(I != Successors.end() && "Not a current successor!");
|
||||||
|
|
||||||
|
// If Weight list is empty it means we don't use it (disabled optimization).
|
||||||
|
if (!Weights.empty()) {
|
||||||
|
weight_iterator WI = getWeightIterator(I);
|
||||||
|
Weights.erase(WI);
|
||||||
|
}
|
||||||
|
|
||||||
Successors.erase(I);
|
Successors.erase(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineBasicBlock::succ_iterator
|
MachineBasicBlock::succ_iterator
|
||||||
MachineBasicBlock::removeSuccessor(succ_iterator I) {
|
MachineBasicBlock::removeSuccessor(succ_iterator I) {
|
||||||
assert(I != Successors.end() && "Not a current successor!");
|
assert(I != Successors.end() && "Not a current successor!");
|
||||||
|
|
||||||
|
// If Weight list is empty it means we don't use it (disabled optimization).
|
||||||
|
if (!Weights.empty()) {
|
||||||
|
weight_iterator WI = getWeightIterator(I);
|
||||||
|
Weights.erase(WI);
|
||||||
|
}
|
||||||
|
|
||||||
(*I)->removePredecessor(this);
|
(*I)->removePredecessor(this);
|
||||||
return Successors.erase(I);
|
return Successors.erase(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MachineBasicBlock::replaceSuccessor(MachineBasicBlock *Old,
|
||||||
|
MachineBasicBlock *New) {
|
||||||
|
uint32_t weight = 0;
|
||||||
|
succ_iterator SI = std::find(Successors.begin(), Successors.end(), Old);
|
||||||
|
|
||||||
|
// If Weight list is empty it means we don't use it (disabled optimization).
|
||||||
|
if (!Weights.empty()) {
|
||||||
|
weight_iterator WI = getWeightIterator(SI);
|
||||||
|
weight = *WI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the successor information.
|
||||||
|
removeSuccessor(SI);
|
||||||
|
addSuccessor(New, weight);
|
||||||
|
}
|
||||||
|
|
||||||
void MachineBasicBlock::addPredecessor(MachineBasicBlock *pred) {
|
void MachineBasicBlock::addPredecessor(MachineBasicBlock *pred) {
|
||||||
Predecessors.push_back(pred);
|
Predecessors.push_back(pred);
|
||||||
}
|
}
|
||||||
@ -374,7 +413,14 @@ void MachineBasicBlock::transferSuccessors(MachineBasicBlock *fromMBB) {
|
|||||||
|
|
||||||
while (!fromMBB->succ_empty()) {
|
while (!fromMBB->succ_empty()) {
|
||||||
MachineBasicBlock *Succ = *fromMBB->succ_begin();
|
MachineBasicBlock *Succ = *fromMBB->succ_begin();
|
||||||
addSuccessor(Succ);
|
uint32_t weight = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// If Weight list is empty it means we don't use it (disabled optimization).
|
||||||
|
if (!fromMBB->Weights.empty())
|
||||||
|
weight = *fromMBB->Weights.begin();
|
||||||
|
|
||||||
|
addSuccessor(Succ, weight);
|
||||||
fromMBB->removeSuccessor(Succ);
|
fromMBB->removeSuccessor(Succ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,8 +683,7 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the successor information.
|
// Update the successor information.
|
||||||
removeSuccessor(Old);
|
replaceSuccessor(Old, New);
|
||||||
addSuccessor(New);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the
|
/// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the
|
||||||
@ -720,6 +765,23 @@ MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
|
|||||||
return DL;
|
return DL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getSuccWeight - Return weight of the edge from this block to MBB.
|
||||||
|
///
|
||||||
|
uint32_t MachineBasicBlock::getSuccWeight(MachineBasicBlock *succ) {
|
||||||
|
succ_iterator I = std::find(Successors.begin(), Successors.end(), succ);
|
||||||
|
return *getWeightIterator(I);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getWeightIterator - Return wight iterator corresonding to the I successor
|
||||||
|
/// iterator
|
||||||
|
MachineBasicBlock::weight_iterator MachineBasicBlock::
|
||||||
|
getWeightIterator(MachineBasicBlock::succ_iterator I) {
|
||||||
|
assert(Weights.size() == Successors.size() && "Async weight list!");
|
||||||
|
size_t index = std::distance(Successors.begin(), I);
|
||||||
|
assert(index < Weights.size() && "Not a current successor!");
|
||||||
|
return Weights.begin() + index;
|
||||||
|
}
|
||||||
|
|
||||||
void llvm::WriteAsOperand(raw_ostream &OS, const MachineBasicBlock *MBB,
|
void llvm::WriteAsOperand(raw_ostream &OS, const MachineBasicBlock *MBB,
|
||||||
bool t) {
|
bool t) {
|
||||||
OS << "BB#" << MBB->getNumber();
|
OS << "BB#" << MBB->getNumber();
|
||||||
|
113
lib/CodeGen/MachineBranchProbabilityInfo.cpp
Normal file
113
lib/CodeGen/MachineBranchProbabilityInfo.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This analysis uses probability info stored in Machine Basic Blocks.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||||
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfo, "machine-branch-prob",
|
||||||
|
"Machine Branch Probability Analysis", false, true)
|
||||||
|
INITIALIZE_PASS_END(MachineBranchProbabilityInfo, "machine-branch-prob",
|
||||||
|
"Machine Branch Probability Analysis", false, true)
|
||||||
|
|
||||||
|
char MachineBranchProbabilityInfo::ID = 0;
|
||||||
|
|
||||||
|
uint32_t MachineBranchProbabilityInfo::
|
||||||
|
getSumForBlock(MachineBasicBlock *MBB) const {
|
||||||
|
uint32_t Sum = 0;
|
||||||
|
|
||||||
|
for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
|
||||||
|
E = MBB->succ_end(); I != E; ++I) {
|
||||||
|
MachineBasicBlock *Succ = *I;
|
||||||
|
uint32_t Weight = getEdgeWeight(MBB, Succ);
|
||||||
|
uint32_t PrevSum = Sum;
|
||||||
|
|
||||||
|
Sum += Weight;
|
||||||
|
assert(Sum > PrevSum); (void) PrevSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
MachineBranchProbabilityInfo::getEdgeWeight(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const {
|
||||||
|
uint32_t Weight = Src->getSuccWeight(Dst);
|
||||||
|
if (!Weight)
|
||||||
|
return DEFAULT_WEIGHT;
|
||||||
|
return Weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MachineBranchProbabilityInfo::isEdgeHot(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const {
|
||||||
|
// Hot probability is at least 4/5 = 80%
|
||||||
|
uint32_t Weight = getEdgeWeight(Src, Dst);
|
||||||
|
uint32_t Sum = getSumForBlock(Src);
|
||||||
|
|
||||||
|
// FIXME: Implement BranchProbability::compare then change this code to
|
||||||
|
// compare this BranchProbability against a static "hot" BranchProbability.
|
||||||
|
return (uint64_t)Weight * 5 > (uint64_t)Sum * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *
|
||||||
|
MachineBranchProbabilityInfo::getHotSucc(MachineBasicBlock *MBB) const {
|
||||||
|
uint32_t Sum = 0;
|
||||||
|
uint32_t MaxWeight = 0;
|
||||||
|
MachineBasicBlock *MaxSucc = 0;
|
||||||
|
|
||||||
|
for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
|
||||||
|
E = MBB->succ_end(); I != E; ++I) {
|
||||||
|
MachineBasicBlock *Succ = *I;
|
||||||
|
uint32_t Weight = getEdgeWeight(MBB, Succ);
|
||||||
|
uint32_t PrevSum = Sum;
|
||||||
|
|
||||||
|
Sum += Weight;
|
||||||
|
assert(Sum > PrevSum); (void) PrevSum;
|
||||||
|
|
||||||
|
if (Weight > MaxWeight) {
|
||||||
|
MaxWeight = Weight;
|
||||||
|
MaxSucc = Succ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Use BranchProbability::compare.
|
||||||
|
if ((uint64_t)MaxWeight * 5 >= (uint64_t)Sum * 4)
|
||||||
|
return MaxSucc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BranchProbability
|
||||||
|
MachineBranchProbabilityInfo::getEdgeProbability(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const {
|
||||||
|
uint32_t N = getEdgeWeight(Src, Dst);
|
||||||
|
uint32_t D = getSumForBlock(Src);
|
||||||
|
|
||||||
|
return BranchProbability(N, D);
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_ostream &MachineBranchProbabilityInfo::
|
||||||
|
printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) const {
|
||||||
|
|
||||||
|
const BranchProbability Prob = getEdgeProbability(Src, Dst);
|
||||||
|
OS << "edge MBB#" << Src->getNumber() << " -> MBB#" << Dst->getNumber()
|
||||||
|
<< " probability is " << Prob
|
||||||
|
<< (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
|
||||||
|
|
||||||
|
return OS;
|
||||||
|
}
|
@ -1279,6 +1279,24 @@ bool SelectionDAGBuilder::isExportableFromCurrentBlock(const Value *V,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return branch probability calculated by BranchProbabilityInfo for IR blocks.
|
||||||
|
uint32_t SelectionDAGBuilder::getEdgeWeight(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) {
|
||||||
|
BranchProbabilityInfo *BPI = FuncInfo.BPI;
|
||||||
|
if (!BPI)
|
||||||
|
return 0;
|
||||||
|
BasicBlock *SrcBB = const_cast<BasicBlock*>(Src->getBasicBlock());
|
||||||
|
BasicBlock *DstBB = const_cast<BasicBlock*>(Dst->getBasicBlock());
|
||||||
|
return BPI->getEdgeWeight(SrcBB, DstBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionDAGBuilder::addSuccessorWithWeight(MachineBasicBlock *Src,
|
||||||
|
MachineBasicBlock *Dst) {
|
||||||
|
uint32_t weight = getEdgeWeight(Src, Dst);
|
||||||
|
Src->addSuccessor(Dst, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool InBlock(const Value *V, const BasicBlock *BB) {
|
static bool InBlock(const Value *V, const BasicBlock *BB) {
|
||||||
if (const Instruction *I = dyn_cast<Instruction>(V))
|
if (const Instruction *I = dyn_cast<Instruction>(V))
|
||||||
return I->getParent() == BB;
|
return I->getParent() == BB;
|
||||||
@ -1548,8 +1566,8 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update successor info
|
// Update successor info
|
||||||
SwitchBB->addSuccessor(CB.TrueBB);
|
addSuccessorWithWeight(SwitchBB, CB.TrueBB);
|
||||||
SwitchBB->addSuccessor(CB.FalseBB);
|
addSuccessorWithWeight(SwitchBB, CB.FalseBB);
|
||||||
|
|
||||||
// Set NextBlock to be the MBB immediately after the current one, if any.
|
// Set NextBlock to be the MBB immediately after the current one, if any.
|
||||||
// This is used to avoid emitting unnecessary branches to the next block.
|
// This is used to avoid emitting unnecessary branches to the next block.
|
||||||
@ -1693,8 +1711,8 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B,
|
|||||||
|
|
||||||
MachineBasicBlock* MBB = B.Cases[0].ThisBB;
|
MachineBasicBlock* MBB = B.Cases[0].ThisBB;
|
||||||
|
|
||||||
SwitchBB->addSuccessor(B.Default);
|
addSuccessorWithWeight(SwitchBB, B.Default);
|
||||||
SwitchBB->addSuccessor(MBB);
|
addSuccessorWithWeight(SwitchBB, MBB);
|
||||||
|
|
||||||
SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
|
SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
|
||||||
MVT::Other, CopyTo, RangeCmp,
|
MVT::Other, CopyTo, RangeCmp,
|
||||||
@ -1739,8 +1757,8 @@ void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB,
|
|||||||
ISD::SETNE);
|
ISD::SETNE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitchBB->addSuccessor(B.TargetBB);
|
addSuccessorWithWeight(SwitchBB, B.TargetBB);
|
||||||
SwitchBB->addSuccessor(NextMBB);
|
addSuccessorWithWeight(SwitchBB, NextMBB);
|
||||||
|
|
||||||
SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
|
SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(),
|
||||||
MVT::Other, getControlRoot(),
|
MVT::Other, getControlRoot(),
|
||||||
@ -1980,8 +1998,9 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR,
|
|||||||
// table.
|
// table.
|
||||||
MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB);
|
MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB);
|
||||||
CurMF->insert(BBI, JumpTableBB);
|
CurMF->insert(BBI, JumpTableBB);
|
||||||
CR.CaseBB->addSuccessor(Default);
|
|
||||||
CR.CaseBB->addSuccessor(JumpTableBB);
|
addSuccessorWithWeight(CR.CaseBB, Default);
|
||||||
|
addSuccessorWithWeight(CR.CaseBB, JumpTableBB);
|
||||||
|
|
||||||
// Build a vector of destination BBs, corresponding to each target
|
// Build a vector of destination BBs, corresponding to each target
|
||||||
// of the jump table. If the value of the jump table slot corresponds to
|
// of the jump table. If the value of the jump table slot corresponds to
|
||||||
@ -2008,7 +2027,7 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR,
|
|||||||
E = DestBBs.end(); I != E; ++I) {
|
E = DestBBs.end(); I != E; ++I) {
|
||||||
if (!SuccsHandled[(*I)->getNumber()]) {
|
if (!SuccsHandled[(*I)->getNumber()]) {
|
||||||
SuccsHandled[(*I)->getNumber()] = true;
|
SuccsHandled[(*I)->getNumber()] = true;
|
||||||
JumpTableBB->addSuccessor(*I);
|
addSuccessorWithWeight(JumpTableBB, *I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2427,8 +2446,10 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) {
|
|||||||
succs.push_back(I.getSuccessor(i));
|
succs.push_back(I.getSuccessor(i));
|
||||||
array_pod_sort(succs.begin(), succs.end());
|
array_pod_sort(succs.begin(), succs.end());
|
||||||
succs.erase(std::unique(succs.begin(), succs.end()), succs.end());
|
succs.erase(std::unique(succs.begin(), succs.end()), succs.end());
|
||||||
for (unsigned i = 0, e = succs.size(); i != e; ++i)
|
for (unsigned i = 0, e = succs.size(); i != e; ++i) {
|
||||||
IndirectBrMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]);
|
MachineBasicBlock *Succ = FuncInfo.MBBMap[succs[i]];
|
||||||
|
addSuccessorWithWeight(IndirectBrMBB, Succ);
|
||||||
|
}
|
||||||
|
|
||||||
DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(),
|
DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(),
|
||||||
MVT::Other, getControlRoot(),
|
MVT::Other, getControlRoot(),
|
||||||
|
@ -434,6 +434,9 @@ private:
|
|||||||
const Value* SV,
|
const Value* SV,
|
||||||
MachineBasicBlock* Default,
|
MachineBasicBlock* Default,
|
||||||
MachineBasicBlock *SwitchBB);
|
MachineBasicBlock *SwitchBB);
|
||||||
|
|
||||||
|
uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst);
|
||||||
|
void addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst);
|
||||||
public:
|
public:
|
||||||
void visitSwitchCase(CaseBlock &CB,
|
void visitSwitchCase(CaseBlock &CB,
|
||||||
MachineBasicBlock *SwitchBB);
|
MachineBasicBlock *SwitchBB);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
||||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||||
#include "llvm/Analysis/DebugInfo.h"
|
#include "llvm/Analysis/DebugInfo.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
@ -68,6 +69,11 @@ static cl::opt<bool>
|
|||||||
EnableFastISelAbort("fast-isel-abort", cl::Hidden,
|
EnableFastISelAbort("fast-isel-abort", cl::Hidden,
|
||||||
cl::desc("Enable abort calls when \"fast\" instruction fails"));
|
cl::desc("Enable abort calls when \"fast\" instruction fails"));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
UseMBPI("use-mbpi",
|
||||||
|
cl::desc("use Machine Branch Probability Info"),
|
||||||
|
cl::init(true), cl::Hidden);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
|
ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
|
||||||
@ -186,6 +192,7 @@ SelectionDAGISel::SelectionDAGISel(const TargetMachine &tm,
|
|||||||
DAGSize(0) {
|
DAGSize(0) {
|
||||||
initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
|
initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
|
||||||
initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
|
initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
|
||||||
|
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionDAGISel::~SelectionDAGISel() {
|
SelectionDAGISel::~SelectionDAGISel() {
|
||||||
@ -199,6 +206,8 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addPreserved<AliasAnalysis>();
|
AU.addPreserved<AliasAnalysis>();
|
||||||
AU.addRequired<GCModuleInfo>();
|
AU.addRequired<GCModuleInfo>();
|
||||||
AU.addPreserved<GCModuleInfo>();
|
AU.addPreserved<GCModuleInfo>();
|
||||||
|
if (UseMBPI && OptLevel != CodeGenOpt::None)
|
||||||
|
AU.addRequired<BranchProbabilityInfo>();
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +271,12 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
|
|
||||||
CurDAG->init(*MF);
|
CurDAG->init(*MF);
|
||||||
FuncInfo->set(Fn, *MF);
|
FuncInfo->set(Fn, *MF);
|
||||||
|
|
||||||
|
if (UseMBPI && OptLevel != CodeGenOpt::None)
|
||||||
|
FuncInfo->BPI = &getAnalysis<BranchProbabilityInfo>();
|
||||||
|
else
|
||||||
|
FuncInfo->BPI = 0;
|
||||||
|
|
||||||
SDB->init(GFI, *AA);
|
SDB->init(GFI, *AA);
|
||||||
|
|
||||||
SelectAllBasicBlocks(Fn);
|
SelectAllBasicBlocks(Fn);
|
||||||
|
Loading…
Reference in New Issue
Block a user