57#define DEBUG_TYPE "structurizecfg"
65 "structurizecfg-skip-uniform-regions",
67 cl::desc(
"Force whether the StructurizeCFG pass skips uniform regions"),
71 RelaxedUniformRegions(
"structurizecfg-relaxed-uniform-regions",
cl::Hidden,
72 cl::desc(
"Allow relaxed uniform region checks"),
77using BBValuePair = std::pair<BasicBlock *, Value *>;
91using MaybeCondBranchWeights = std::optional<class CondBranchWeights>;
93class CondBranchWeights {
100 static MaybeCondBranchWeights tryParse(
const CondBrInst &Br) {
105 return CondBranchWeights(
T,
F);
109 const MaybeCondBranchWeights &Weights) {
112 uint32_t Arr[] = {Weights->TrueWeight, Weights->FalseWeight};
116 CondBranchWeights invert()
const {
117 return CondBranchWeights{FalseWeight, TrueWeight};
123 MaybeCondBranchWeights Weights;
134struct SubGraphTraits {
135 using NodeRef = std::pair<RegionNode *, SmallDenseSet<RegionNode *> *>;
140 class WrappedSuccIterator
142 WrappedSuccIterator, BaseSuccIterator,
143 std::iterator_traits<BaseSuccIterator>::iterator_category, NodeRef,
144 std::ptrdiff_t, NodeRef *, NodeRef> {
151 NodeRef
operator*()
const {
return {*
I, Nodes}; }
154 static bool filterAll(
const NodeRef &
N) {
return true; }
155 static bool filterSet(
const NodeRef &
N) {
return N.second->count(
N.first); }
160 static NodeRef getEntryNode(
Region *R) {
164 static NodeRef getEntryNode(NodeRef
N) {
return N; }
167 auto *filter =
N.second ? &filterSet : &filterAll;
189class NearestCommonDominator {
192 bool ResultIsRemembered =
false;
195 void addBlock(
BasicBlock *BB,
bool Remember) {
198 ResultIsRemembered = Remember;
203 if (NewResult != Result)
204 ResultIsRemembered =
false;
206 ResultIsRemembered |= Remember;
211 explicit NearestCommonDominator(
DominatorTree *DomTree) : DT(DomTree) {}
227 bool resultIsRememberedBlock() {
return ResultIsRemembered; }
276class StructurizeCFG {
293 BBPhiMap DeletedPhis;
294 BB2BBVecMap AddedPhis;
297 BranchVector Conditions;
301 BranchVector LoopConds;
303 Val2BBMap HoistedValues;
316 PredInfo buildCondition(
CondBrInst *Term,
unsigned Idx,
bool Invert);
324 void simplifyConditions();
339 void simplifyAffectedPhis();
341 void simplifyHoistedPhis();
346 bool IncludeDominator);
350 std::pair<BasicBlock *, DebugLoc> needPrefix(
bool NeedEmpty);
360 void wireFlow(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
362 void handleLoops(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
374class StructurizeCFGLegacyPass :
public RegionPass {
375 bool SkipUniformRegions;
380 explicit StructurizeCFGLegacyPass(
bool SkipUniformRegions_ =
false)
381 :
RegionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
383 SkipUniformRegions = ForceSkipUniformRegions.
getValue();
390 if (SkipUniformRegions) {
392 getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
393 if (SCFG.makeUniformRegion(R, UA))
396 Function *
F = R->getEntry()->getParent();
398 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*
F);
399 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
400 return SCFG.run(R, DT,
TTI);
403 StringRef getPassName()
const override {
return "Structurize control flow"; }
406 if (SkipUniformRegions)
419char StructurizeCFGLegacyPass::ID = 0;
422 "Structurize the CFG",
false,
false)
447 for (
auto &
Op :
I->operands()) {
448 if (auto *OpI = dyn_cast<Instruction>(Op)) {
450 if (!DT->dominates(OpI->getParent(), HoistTo))
471void StructurizeCFG::hoistZeroCostElseBlockPhiValues(
BasicBlock *ElseBB,
477 if (!ElseSucc || !CommonDominator)
487 for (PHINode &Phi : ElseSucc->
phis()) {
488 Value *ElseVal =
Phi.getIncomingValueForBlock(ElseBB);
490 if (!Inst || !isHoistableInstruction(Inst, ElseBB, CommonDominator))
492 Inst->removeFromParent();
493 Inst->insertInto(CommonDominator,
Term->getIterator());
494 HoistedValues[Inst] = CommonDominator;
501void StructurizeCFG::orderNodes() {
502 Order.resize(std::distance(GraphTraits<Region *>::nodes_begin(ParentRegion),
503 GraphTraits<Region *>::nodes_end(ParentRegion)));
507 SmallDenseSet<RegionNode *> Nodes;
508 auto EntryNode = SubGraphTraits::getEntryNode(ParentRegion);
512 unsigned I = 0,
E = Order.size();
529 for (
const auto &
N : SCC) {
530 assert(
I <
E &&
"SCC size mismatch!");
531 Order[
I++] =
N.first;
534 assert(
I ==
E &&
"SCC size mismatch!");
537 if (WorkList.
empty())
546 Nodes.
insert(Order.begin() +
I, Order.begin() +
E - 1);
549 EntryNode.first = Order[
E - 1];
550 EntryNode.second = &Nodes;
555void StructurizeCFG::analyzeLoops(RegionNode *
N) {
556 if (
N->isSubRegion()) {
559 if (Visited.count(Exit))
568 if (Visited.count(Succ))
574PredInfo StructurizeCFG::buildCondition(CondBrInst *Term,
unsigned Idx,
577 auto Weights = CondBranchWeights::tryParse(*Term);
578 if (Idx != (
unsigned)Invert) {
581 Weights = Weights->invert();
583 return {
Cond, Weights};
587void StructurizeCFG::gatherPredicates(RegionNode *
N) {
599 if (R == ParentRegion) {
601 if (Visited.count(
P))
602 Pred[
P] = {BoolTrue, std::nullopt};
604 LPred[
P] = {BoolFalse, std::nullopt};
606 bool Idx = CondBr->getSuccessor(0) == BB ? 0 : 1;
607 if (Visited.count(
P)) {
613 hoistZeroCostElseBlockPhiValues(BB,
Other);
614 Pred[
Other] = {BoolFalse, std::nullopt};
615 Pred[
P] = {BoolTrue, std::nullopt};
617 Pred[
P] = buildCondition(CondBr, Idx,
false);
620 LPred[
P] = buildCondition(CondBr, Idx,
true);
625 while (
R->getParent() != ParentRegion)
633 if (Visited.count(Entry))
634 Pred[
Entry] = {BoolTrue, std::nullopt};
636 LPred[
Entry] = {BoolFalse, std::nullopt};
642void StructurizeCFG::collectInfos() {
653 for (RegionNode *RN :
reverse(Order)) {
655 << (
RN->isSubRegion() ?
"SubRegion with entry: " :
"")
656 <<
RN->getEntry()->getName() <<
"\n");
659 gatherPredicates(RN);
662 Visited.insert(
RN->getEntry());
670void StructurizeCFG::insertConditions(
bool Loops, SSAUpdaterBulk &PhiInserter) {
671 BranchVector &Conds =
Loops ? LoopConds : Conditions;
674 for (CondBrInst *Term : Conds) {
685 NearestCommonDominator Dominator(DT);
686 Dominator.addBlock(Parent);
688 PredInfo ParentInfo{
nullptr, std::nullopt};
689 for (
auto [BB, PI] : Preds) {
695 Dominator.addAndRememberBlock(BB);
698 if (ParentInfo.Pred) {
699 Term->setCondition(ParentInfo.Pred);
700 CondBranchWeights::setMetadata(*Term, ParentInfo.Weights);
702 if (!Dominator.resultIsRememberedBlock())
705 PhiInserter.
AddUse(Variable, &
Term->getOperandUse(0));
711void StructurizeCFG::simplifyConditions() {
712 SmallVector<Instruction *> InstToErase;
714 auto &Preds =
I.second;
715 for (
auto [BB, PI] : Preds) {
718 !PI.Pred->use_empty()) {
720 InvertedCmp->setPredicate(InvertedCmp->getInversePredicate());
721 PI.Pred->replaceAllUsesWith(InvertedCmp);
727 for (
auto *
I : InstToErase)
728 I->eraseFromParent();
733void StructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
735 for (PHINode &Phi : To->
phis()) {
736 bool Recorded =
false;
737 while (
Phi.getBasicBlockIndex(From) != -1) {
741 AffectedPhis.push_back(&Phi);
749void StructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
750 for (PHINode &Phi : To->
phis()) {
754 AddedPhis[To].push_back(From);
761void StructurizeCFG::findUndefBlocks(
762 BasicBlock *PHIBlock,
const SmallPtrSet<BasicBlock *, 8> &Incomings,
788 SmallPtrSet<BasicBlock *, 8> VisitedBlock;
789 SmallVector<BasicBlock *, 8>
Stack;
790 if (PHIBlock == ParentRegion->
getExit()) {
803 while (!
Stack.empty()) {
805 if (!VisitedBlock.
insert(Current).second)
808 if (FlowSet.contains(Current))
810 else if (!Incomings.
contains(Current))
821void StructurizeCFG::mergeIfCompatible(
822 EquivalenceClasses<PHINode *> &PhiClasses, PHINode *
A, PHINode *
B) {
829 PHINode *LeaderA = *ItA;
830 PHINode *LeaderB = *ItB;
831 BBValueVector &IncomingA = DeletedPhis[LeaderA->
getParent()][LeaderA];
832 BBValueVector &IncomingB = DeletedPhis[LeaderB->
getParent()][LeaderB];
834 DenseMap<BasicBlock *, Value *> Mergeable(IncomingA.begin(), IncomingA.end());
835 for (
auto [BB, V] : IncomingB) {
836 auto BBIt = Mergeable.find(BB);
837 if (BBIt != Mergeable.end() && BBIt->second != V)
841 Mergeable.insert({BB,
V});
845 IncomingA.assign(Mergeable.begin(), Mergeable.end());
850void StructurizeCFG::setPhiValues() {
852 SSAUpdater Updater(&InsertedPhis);
853 DenseMap<BasicBlock *, SmallVector<BasicBlock *>> UndefBlksMap;
876 EquivalenceClasses<PHINode *> PhiClasses;
877 for (
const auto &[To, From] : AddedPhis) {
878 auto OldPhiIt = DeletedPhis.find(To);
879 if (OldPhiIt == DeletedPhis.end())
882 PhiMap &BlkPhis = OldPhiIt->second;
884 SmallPtrSet<BasicBlock *, 8> Incomings;
887 if (!BlkPhis.
empty()) {
889 findUndefBlocks(To, Incomings, UndefBlks);
892 for (
const auto &[Phi, Incomings] : OldPhiIt->second) {
894 for (
const auto &[BB, V] : Incomings) {
901 for (
auto *OtherPhi : IncomingPHIs) {
903 if (!DeletedPhis.contains(OtherPhi->getParent()))
905 mergeIfCompatible(PhiClasses, Phi, OtherPhi);
910 for (
const auto &AddedPhi : AddedPhis) {
912 const BBVector &From = AddedPhi.second;
914 auto It = DeletedPhis.find(To);
915 if (It == DeletedPhis.end())
920 for (
const auto &[Phi, Incoming] : Map) {
922 Updater.Initialize(
Phi->getType(),
"");
924 Updater.AddAvailableValue(To,
Poison);
928 bool UseIncomingOfLeader =
930 const auto &IncomingMap =
931 UseIncomingOfLeader ? DeletedPhis[(*LeaderIt)->getParent()][*LeaderIt]
935 for (
const auto &[BB, V] : IncomingMap) {
936 Updater.AddAvailableValue(BB, V);
941 for (
auto UB : UndefBlks) {
947 [&](BasicBlock *CP) {
return DT->
dominates(CP, UB); }))
950 if (Updater.HasValueForBlock(UB))
953 Updater.AddAvailableValue(UB,
Poison);
956 for (BasicBlock *FI : From)
957 Phi->setIncomingValueForBlock(FI, Updater.GetValueAtEndOfBlock(FI));
958 AffectedPhis.push_back(Phi);
962 AffectedPhis.append(InsertedPhis.
begin(), InsertedPhis.
end());
967void StructurizeCFG::simplifyHoistedPhis() {
968 for (WeakVH VH : AffectedPhis) {
970 if (!Phi ||
Phi->getNumIncomingValues() != 2)
973 for (
int i = 0; i < 2; i++) {
975 auto BBIt = HoistedValues.find(V);
977 if (BBIt == HoistedValues.end())
980 Value *OtherV =
Phi->getIncomingValue(!i);
985 int PoisonValBBIdx = -1;
992 if (PoisonValBBIdx == -1 ||
999 Phi->setIncomingValue(i, OtherV);
1004void StructurizeCFG::simplifyAffectedPhis() {
1012 Q.CanUseUndef =
false;
1013 for (WeakVH VH : AffectedPhis) {
1016 Phi->replaceAllUsesWith(NewValue);
1017 Phi->eraseFromParent();
1026DebugLoc StructurizeCFG::killTerminator(BasicBlock *BB) {
1032 delPhiValues(BB, Succ);
1035 Term->eraseFromParent();
1040void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
1041 bool IncludeDominator) {
1042 if (
Node->isSubRegion()) {
1054 delPhiValues(BB, OldExit);
1056 addPhiValues(BB, NewExit);
1059 if (IncludeDominator) {
1078 addPhiValues(BB, NewExit);
1079 if (IncludeDominator)
1085BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
1088 Order.back()->getEntry();
1091 FlowSet.insert(
Flow);
1099std::pair<BasicBlock *, DebugLoc> StructurizeCFG::needPrefix(
bool NeedEmpty) {
1104 if (!NeedEmpty ||
Entry->getFirstInsertionPt() ==
Entry->end())
1112 changeExit(PrevNode,
Flow,
true);
1119 bool ExitUseAllowed) {
1120 if (!Order.empty() || !ExitUseAllowed)
1121 return getNextFlow(
Flow);
1125 addPhiValues(
Flow, Exit);
1130void StructurizeCFG::setPrevNode(BasicBlock *BB) {
1136bool StructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
1139 Preds, [&](
const auto &Pred) {
return DT->
dominates(BB, Pred.first); });
1143bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
1145 bool Dominated =
false;
1151 for (
auto [BB, PI] : Preds) {
1152 if (PI.Pred != BoolTrue)
1164void StructurizeCFG::wireFlow(
bool ExitUseAllowed,
1165 BasicBlock *LoopEnd) {
1166 RegionNode *
Node = Order.pop_back_val();
1167 Visited.insert(
Node->getEntry());
1169 if (isPredictableTrue(Node)) {
1172 changeExit(PrevNode,
Node->getEntry(),
true);
1177 auto [
Flow,
DL] = needPrefix(
false);
1186 Conditions.push_back(Br);
1187 addPhiValues(
Flow, Entry);
1191 while (!Order.empty() && !Visited.count(LoopEnd) &&
1192 dominatesPredicates(Entry, Order.back())) {
1193 handleLoops(
false, LoopEnd);
1196 changeExit(PrevNode,
Next,
false);
1201void StructurizeCFG::handleLoops(
bool ExitUseAllowed,
1202 BasicBlock *LoopEnd) {
1203 RegionNode *
Node = Order.back();
1206 if (!
Loops.count(LoopStart)) {
1207 wireFlow(ExitUseAllowed, LoopEnd);
1211 if (!isPredictableTrue(Node))
1212 LoopStart = needPrefix(
true).first;
1215 wireFlow(
false, LoopEnd);
1216 while (!Visited.count(LoopEnd)) {
1217 handleLoops(
false, LoopEnd);
1224 std::tie(LoopEnd,
DL) = needPrefix(
false);
1228 LoopConds.push_back(Br);
1229 addPhiValues(LoopEnd, LoopStart);
1235void StructurizeCFG::createFlow() {
1239 AffectedPhis.clear();
1240 DeletedPhis.clear();
1248 while (!Order.empty()) {
1249 handleLoops(EntryDominatesExit,
nullptr);
1253 changeExit(PrevNode, Exit, EntryDominatesExit);
1255 assert(EntryDominatesExit);
1260void StructurizeCFG::rebuildSSA() {
1262 for (BasicBlock *BB : ParentRegion->
blocks())
1263 for (Instruction &
I : *BB) {
1264 bool Initialized =
false;
1269 if (
User->getParent() == BB) {
1272 if (UserPN->getIncomingBlock(U) == BB)
1294 bool SubRegionsAreUniform =
true;
1296 unsigned ConditionalDirectChildren = 0;
1298 for (
auto *
E : R->elements()) {
1299 if (!
E->isSubRegion()) {
1308 ConditionalDirectChildren++;
1311 <<
" has uniform terminator\n");
1329 if (!RelaxedUniformRegions)
1332 SubRegionsAreUniform =
false;
1345 return SubRegionsAreUniform || (ConditionalDirectChildren <= 1);
1348void StructurizeCFG::init(Region *R) {
1349 LLVMContext &
Context =
R->getEntry()->getContext();
1359bool StructurizeCFG::makeUniformRegion(Region *R,
UniformityInfo &UA) {
1360 if (
R->isTopLevelRegion())
1369 unsigned UniformMDKindID =
1370 R->getEntry()->getContext().getMDKindID(
"structurizecfg.uniform");
1373 LLVM_DEBUG(
dbgs() <<
"Skipping region with uniform control flow: " << *R
1380 MDNode *MD =
MDNode::get(
R->getEntry()->getParent()->getContext(), {});
1381 for (RegionNode *
E :
R->elements()) {
1382 if (
E->isSubRegion())
1385 if (Instruction *Term =
E->getEntry()->getTerminator())
1386 Term->setMetadata(UniformMDKindID, MD);
1395bool StructurizeCFG::run(Region *R, DominatorTree *DT,
1396 const TargetTransformInfo *
TTI) {
1407 Func =
R->getEntry()->getParent();
1415 SSAUpdaterBulk PhiInserter;
1416 insertConditions(
false, PhiInserter);
1417 insertConditions(
true, PhiInserter);
1421 simplifyHoistedPhis();
1422 simplifyConditions();
1423 simplifyAffectedPhis();
1429 DeletedPhis.clear();
1442 return new StructurizeCFGLegacyPass(SkipUniformRegions);
1446 Regions.push_back(&R);
1447 for (
const auto &
E : R)
1452 : SkipUniformRegions(SkipUniformRegions_) {
1453 if (ForceSkipUniformRegions.getNumOccurrences())
1454 SkipUniformRegions = ForceSkipUniformRegions.getValue();
1459 static_cast<PassInfoMixin<StructurizeCFGPass> *
>(
this)->
printPipeline(
1460 OS, MapClassName2PassName);
1461 if (SkipUniformRegions)
1462 OS <<
"<skip-uniform-regions>";
1473 if (SkipUniformRegions)
1476 std::vector<Region *> Regions;
1478 while (!Regions.empty()) {
1479 Region *R = Regions.back();
1482 StructurizeCFG SCFG;
1485 if (SkipUniformRegions && SCFG.makeUniformRegion(R, *UI)) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DenseMap< BasicBlock *, Instruction * > BBPredicates
This file defines the DenseMap class.
Generic implementation of equivalence classes through the use Tarjan's efficient union-find algorithm...
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
This file implements a map that provides insertion order iteration.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
static void addRegionIntoQueue(Region &R, std::deque< Region * > &RQ)
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
SmallDenseMap< const PHINode *, PhiInfo, 16 > PhiMap
const char FlowBlockName[]
static bool hasOnlyUniformBranches(Region *R, unsigned UniformMDKindID, const UniformityInfo &UA)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI bool hasNPredecessors(unsigned N) const
Return true if this block has exactly N predecessors.
const Instruction * getTerminatorOrNull() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Analysis pass which computes a DominatorTree.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This represents a collection of equivalence classes and supports three efficient operations: insert a...
const ECValue & insert(const ElemTy &Data)
Insert a new value into the union/find set, ignoring the request if the value already exists.
member_iterator member_end() const
member_iterator findLeader(const ElemTy &V) const
Given a value in the set, return a member iterator for the equivalence class it is in.
member_iterator unionSets(const ElemTy &V1, const ElemTy &V2)
Merge the two equivalence sets for the specified values, inserting them if they do not already exist ...
const BasicBlock & getEntryBlock() const
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class implements a map that also provides access to all stored values in a deterministic order.
void setIncomingValue(unsigned i, Value *V)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
The pass manager to schedule RegionPasses.
void replaceExit(BlockT *BB)
Replace the exit basic block of the region with the new basic block.
block_range blocks()
Returns a range view of the basic blocks in the region.
BlockT * getExit() const
Get the exit BasicBlock of the Region.
RegionNodeT * getBBNode(BlockT *BB) const
Get the BasicBlock RegionNode for a BasicBlock.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
RegionInfoT * getRegionInfo() const
Return the RegionInfo object, that belongs to this Region.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Analysis pass that exposes the RegionInfo for a function.
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
bool isSubRegion() const
Is this RegionNode a subregion?
BlockT * getEntry() const
Get the entry BasicBlock of this RegionNode.
A pass that runs on each Region in a function.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI unsigned AddVariable(StringRef Name, Type *Ty)
Add a new variable to the SSA rewriter.
LLVM_ABI void AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
LLVM_ABI void AddUse(unsigned Var, Use *U)
Record a use of the symbolic value.
LLVM_ABI void RewriteAndOptimizeAllUses(DominatorTree &DT)
Rewrite all uses and simplify the inserted PHI nodes.
LLVM_ABI void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
Implements a dense probed hash-table based set with some number of buckets stored inline.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Analysis pass providing the TargetTransformInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM Value Representation.
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
CRTP base class for adapting an iterator to a different type.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
static scc_iterator begin(const GraphT &G)
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< SSAContext > UniformityInfo
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
auto successors(const MachineBasicBlock *BB)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI Pass * createStructurizeCFGPass(bool SkipUniformRegions=false)
When SkipUniformRegions is true the structizer will not structurize regions that only contain uniform...
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Value * invertCondition(Value *Condition)
Invert the given true/false value, possibly reusing an existing copy.
filter_iterator_impl< WrappedIteratorT, PredicateT, detail::fwd_or_bidi_tag< WrappedIteratorT > > filter_iterator
Defines filter_iterator to a suitable specialization of filter_iterator_impl, based on the underlying...
LLVM_ABI void initializeStructurizeCFGLegacyPassPass(PassRegistry &)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI StructurizeCFGPass(bool SkipUniformRegions=false)