3030#include " llvm/IR/Metadata.h"
3131#include " llvm/IR/PassManager.h"
3232#include " llvm/IR/PatternMatch.h"
33+ #include " llvm/IR/ProfDataUtils.h"
3334#include " llvm/IR/Type.h"
3435#include " llvm/IR/Use.h"
3536#include " llvm/IR/Value.h"
@@ -85,7 +86,43 @@ using PhiMap = MapVector<PHINode *, BBValueVector>;
8586using BB2BBVecMap = MapVector<BasicBlock *, BBVector>;
8687
8788using BBPhiMap = DenseMap<BasicBlock *, PhiMap>;
88- using BBPredicates = DenseMap<BasicBlock *, Value *>;
89+
90+ using MaybeCondBranchWeights = std::optional<class CondBranchWeights >;
91+
92+ class CondBranchWeights {
93+ uint32_t TrueWeight;
94+ uint32_t FalseWeight;
95+
96+ CondBranchWeights (uint32_t T, uint32_t F) : TrueWeight(T), FalseWeight(F) {}
97+
98+ public:
99+ static MaybeCondBranchWeights tryParse (const BranchInst &Br) {
100+ assert (Br.isConditional ());
101+
102+ uint64_t T, F;
103+ if (!extractBranchWeights (Br, T, F))
104+ return std::nullopt ;
105+
106+ return CondBranchWeights (T, F);
107+ }
108+
109+ static void setMetadata (BranchInst &Br,
110+ const MaybeCondBranchWeights &Weights) {
111+ assert (Br.isConditional ());
112+ if (!Weights)
113+ return ;
114+ uint32_t Arr[] = {Weights->TrueWeight , Weights->FalseWeight };
115+ setBranchWeights (Br, Arr, false );
116+ }
117+
118+ CondBranchWeights invert () const {
119+ return CondBranchWeights{FalseWeight, TrueWeight};
120+ }
121+ };
122+
123+ using ValueWeightPair = std::pair<Value *, MaybeCondBranchWeights>;
124+
125+ using BBPredicates = DenseMap<BasicBlock *, ValueWeightPair>;
89126using PredMap = DenseMap<BasicBlock *, BBPredicates>;
90127using BB2BBMap = DenseMap<BasicBlock *, BasicBlock *>;
91128
@@ -271,7 +308,7 @@ class StructurizeCFG {
271308
272309 void analyzeLoops (RegionNode *N);
273310
274- Value * buildCondition (BranchInst *Term, unsigned Idx, bool Invert);
311+ ValueWeightPair buildCondition (BranchInst *Term, unsigned Idx, bool Invert);
275312
276313 void gatherPredicates (RegionNode *N);
277314
@@ -449,16 +486,22 @@ void StructurizeCFG::analyzeLoops(RegionNode *N) {
449486}
450487
451488// / Build the condition for one edge
452- Value * StructurizeCFG::buildCondition (BranchInst *Term, unsigned Idx,
453- bool Invert) {
489+ ValueWeightPair StructurizeCFG::buildCondition (BranchInst *Term, unsigned Idx,
490+ bool Invert) {
454491 Value *Cond = Invert ? BoolFalse : BoolTrue;
492+ MaybeCondBranchWeights Weights;
493+
455494 if (Term->isConditional ()) {
456495 Cond = Term->getCondition ();
496+ Weights = CondBranchWeights::tryParse (*Term);
457497
458- if (Idx != (unsigned )Invert)
498+ if (Idx != (unsigned )Invert) {
459499 Cond = invertCondition (Cond);
500+ if (Weights)
501+ Weights = Weights->invert ();
502+ }
460503 }
461- return Cond;
504+ return { Cond, Weights} ;
462505}
463506
464507// / Analyze the predecessors of each block and build up predicates
@@ -490,8 +533,8 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
490533 if (Visited.count (Other) && !Loops.count (Other) &&
491534 !Pred.count (Other) && !Pred.count (P)) {
492535
493- Pred[Other] = BoolFalse;
494- Pred[P] = BoolTrue;
536+ Pred[Other] = { BoolFalse, std:: nullopt } ;
537+ Pred[P] = { BoolTrue, std:: nullopt } ;
495538 continue ;
496539 }
497540 }
@@ -512,9 +555,9 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
512555
513556 BasicBlock *Entry = R->getEntry ();
514557 if (Visited.count (Entry))
515- Pred[Entry] = BoolTrue;
558+ Pred[Entry] = { BoolTrue, std:: nullopt } ;
516559 else
517- LPred[Entry] = BoolFalse;
560+ LPred[Entry] = { BoolFalse, std:: nullopt } ;
518561 }
519562 }
520563}
@@ -578,12 +621,14 @@ void StructurizeCFG::insertConditions(bool Loops) {
578621 Dominator.addBlock (Parent);
579622
580623 Value *ParentValue = nullptr ;
581- for (std::pair<BasicBlock *, Value *> BBAndPred : Preds) {
624+ MaybeCondBranchWeights ParentWeights = std::nullopt ;
625+ for (std::pair<BasicBlock *, ValueWeightPair> BBAndPred : Preds) {
582626 BasicBlock *BB = BBAndPred.first ;
583- Value * Pred = BBAndPred.second ;
627+ auto [ Pred, Weight] = BBAndPred.second ;
584628
585629 if (BB == Parent) {
586630 ParentValue = Pred;
631+ ParentWeights = Weight;
587632 break ;
588633 }
589634 PhiInserter.AddAvailableValue (BB, Pred);
@@ -592,6 +637,7 @@ void StructurizeCFG::insertConditions(bool Loops) {
592637
593638 if (ParentValue) {
594639 Term->setCondition (ParentValue);
640+ CondBranchWeights::setMetadata (*Term, ParentWeights);
595641 } else {
596642 if (!Dominator.resultIsRememberedBlock ())
597643 PhiInserter.AddAvailableValue (Dominator.result (), Default);
@@ -607,7 +653,7 @@ void StructurizeCFG::simplifyConditions() {
607653 for (auto &I : concat<PredMap::value_type>(Predicates, LoopPreds)) {
608654 auto &Preds = I.second ;
609655 for (auto &J : Preds) {
610- auto & Cond = J.second ;
656+ Value * Cond = J.second . first ;
611657 Instruction *Inverted;
612658 if (match (Cond, m_Not (m_OneUse (m_Instruction (Inverted)))) &&
613659 !Cond->use_empty ()) {
@@ -904,9 +950,10 @@ void StructurizeCFG::setPrevNode(BasicBlock *BB) {
904950// / Does BB dominate all the predicates of Node?
905951bool StructurizeCFG::dominatesPredicates (BasicBlock *BB, RegionNode *Node) {
906952 BBPredicates &Preds = Predicates[Node->getEntry ()];
907- return llvm::all_of (Preds, [&](std::pair<BasicBlock *, Value *> Pred) {
908- return DT->dominates (BB, Pred.first );
909- });
953+ return llvm::all_of (Preds,
954+ [&](std::pair<BasicBlock *, ValueWeightPair> Pred) {
955+ return DT->dominates (BB, Pred.first );
956+ });
910957}
911958
912959// / Can we predict that this node will always be called?
@@ -918,9 +965,9 @@ bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
918965 if (!PrevNode)
919966 return true ;
920967
921- for (std::pair<BasicBlock*, Value* > Pred : Preds) {
968+ for (std::pair<BasicBlock *, ValueWeightPair > Pred : Preds) {
922969 BasicBlock *BB = Pred.first ;
923- Value *V = Pred.second ;
970+ Value *V = Pred.second . first ;
924971
925972 if (V != BoolTrue)
926973 return false ;
0 commit comments