15 #ifndef LLVM_LIB_TRANSFORMS_INSTRUMENTATION_CFGMST_H 16 #define LLVM_LIB_TRANSFORMS_INSTRUMENTATION_CFGMST_H 30 #define DEBUG_TYPE "cfgmst" 38 template <
class Edge,
class BBInfo>
class CFGMST {
57 return static_cast<BBInfo *
>(G->Group);
70 if (BB1G->Rank < BB2G->Rank)
75 if (BB1G->Rank == BB2G->Rank)
83 auto It = BBInfos.
find(BB);
84 assert(It->second.get() !=
nullptr);
85 return *It->second.get();
90 auto It = BBInfos.
find(BB);
91 if (It == BBInfos.
end())
93 return It->second.get();
104 Edge *EntryIncoming =
nullptr, *EntryOutgoing =
nullptr,
105 *ExitOutgoing =
nullptr, *ExitIncoming =
nullptr;
106 uint64_t MaxEntryOutWeight = 0, MaxExitOutWeight = 0, MaxExitInWeight = 0;
109 EntryIncoming = &
addEdge(
nullptr, Entry, EntryWeight);
110 LLVM_DEBUG(
dbgs() <<
" Edge: from fake node to " << Entry->getName()
111 <<
" w = " << EntryWeight <<
"\n");
115 addEdge(Entry,
nullptr, EntryWeight);
119 static const uint32_t CriticalEdgeMultiplier = 1000;
130 uint64_t scaleFactor = BBWeight;
132 if (scaleFactor <
UINT64_MAX / CriticalEdgeMultiplier)
133 scaleFactor *= CriticalEdgeMultiplier;
139 auto *
E = &
addEdge(&*BB, TargetBB, Weight);
140 E->IsCritical = Critical;
142 << TargetBB->
getName() <<
" w=" << Weight <<
"\n");
146 if (Weight > MaxEntryOutWeight) {
147 MaxEntryOutWeight = Weight;
153 if (TargetTI && !TargetTI->getNumSuccessors()) {
154 if (Weight > MaxExitInWeight) {
155 MaxExitInWeight = Weight;
161 ExitBlockFound =
true;
162 Edge *ExitO = &
addEdge(&*BB,
nullptr, BBWeight);
163 if (BBWeight > MaxExitOutWeight) {
164 MaxExitOutWeight = BBWeight;
165 ExitOutgoing = ExitO;
167 LLVM_DEBUG(
dbgs() <<
" Edge: from " << BB->getName() <<
" to fake exit" 168 <<
" w = " << BBWeight <<
"\n");
182 uint64_t EntryInWeight = EntryWeight;
184 if (EntryInWeight >= MaxExitOutWeight &&
185 EntryInWeight * 2 < MaxExitOutWeight * 3) {
186 EntryIncoming->Weight = MaxExitOutWeight;
187 ExitOutgoing->Weight = EntryInWeight + 1;
190 if (MaxEntryOutWeight >= MaxExitInWeight &&
191 MaxEntryOutWeight * 2 < MaxExitInWeight * 3) {
192 EntryOutgoing->Weight = MaxExitInWeight;
193 ExitIncoming->Weight = MaxEntryOutWeight + 1;
199 std::stable_sort(AllEdges.begin(), AllEdges.end(),
200 [](
const std::unique_ptr<Edge> &Edge1,
201 const std::unique_ptr<Edge> &Edge2) {
202 return Edge1->Weight > Edge2->Weight;
212 for (
auto &Ei : AllEdges) {
215 if (Ei->IsCritical) {
216 if (Ei->DestBB && Ei->DestBB->isLandingPad()) {
223 for (
auto &Ei : AllEdges) {
228 if (!ExitBlockFound && Ei->SrcBB ==
nullptr)
237 if (!Message.
str().empty())
238 OS << Message <<
"\n";
239 OS <<
" Number of Basic Blocks: " << BBInfos.
size() <<
"\n";
240 for (
auto &BI : BBInfos) {
242 OS <<
" BB: " << (BB ==
nullptr ?
"FakeNode" : BB->
getName()) <<
" " 243 << BI.second->infoString() <<
"\n";
246 OS <<
" Number of Edges: " << AllEdges.size()
247 <<
" (*: Instrument, C: CriticalEdge, -: Removed)\n";
249 for (
auto &EI : AllEdges)
250 OS <<
" Edge " << Count++ <<
": " <<
getBBInfo(EI->SrcBB).Index <<
"-->" 251 <<
getBBInfo(EI->DestBB).Index << EI->infoString() <<
"\n";
257 auto Iter = BBInfos.
end();
259 std::tie(Iter, Inserted) = BBInfos.
insert(std::make_pair(Src,
nullptr));
262 Iter->second = std::move(llvm::make_unique<BBInfo>(Index));
265 std::tie(Iter, Inserted) = BBInfos.
insert(std::make_pair(Dest,
nullptr));
268 Iter->second = std::move(llvm::make_unique<BBInfo>(Index));
269 AllEdges.emplace_back(
new Edge(Src, Dest, W));
270 return *AllEdges.back();
279 : F(Func), BPI(BPI_), BFI(BFI_) {
288 #undef DEBUG_TYPE // "cfgmst" 290 #endif // LLVM_LIB_TRANSFORMS_INSTRUMENTATION_CFGMST_H This class represents lattice values for constants.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
std::vector< std::unique_ptr< Edge > > AllEdges
CFGMST(Function &Func, BranchProbabilityInfo *BPI_=nullptr, BlockFrequencyInfo *BFI_=nullptr)
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
An union-find based Minimum Spanning Tree for CFG.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool unionGroups(const BasicBlock *BB1, const BasicBlock *BB2)
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
iterator find(const_arg_type_t< KeyT > Val)
const BasicBlock & getEntryBlock() const
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM Basic Block Representation.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
DenseMap< const BasicBlock *, std::unique_ptr< BBInfo > > BBInfos
bool succ_empty(const Instruction *I)
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
BBInfo * findBBInfo(const BasicBlock *BB) const
uint64_t getEntryFreq() const
void computeMinimumSpanningTree()
Iterator for intrusive lists based on ilist_node.
BBInfo * findAndCompressGroup(BBInfo *G)
uint64_t scale(uint64_t Num) const
Scale a large integer.
void dumpEdges(raw_ostream &OS, const Twine &Message) const
BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
BranchProbabilityInfo * BPI
BBInfo & getBBInfo(const BasicBlock *BB) const
Analysis providing branch probability information.
Edge & addEdge(const BasicBlock *Src, const BasicBlock *Dest, uint64_t W)
StringRef getName() const
Return a constant reference to the value's name.
std::string str() const
Return the twine contents as a std::string.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
succ_range successors(Instruction *I)
This class implements an extremely fast bulk output stream that can only output to a stream...