1 //===- CodeMoverUtils.cpp - CodeMover Utilities ----------------------------==//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This family of functions perform movements on basic blocks, and instructions
10 // contained within a function.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/Utils/CodeMoverUtils.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/Analysis/DependenceAnalysis.h"
17 #include "llvm/Analysis/PostDominators.h"
18 #include "llvm/Analysis/ValueTracking.h"
19 #include "llvm/IR/Dominators.h"
23 #define DEBUG_TYPE "codemover-utils"
25 STATISTIC(HasDependences
,
26 "Cannot move across instructions that has memory dependences");
27 STATISTIC(MayThrowException
, "Cannot move across instructions that may throw");
28 STATISTIC(NotControlFlowEquivalent
,
29 "Instructions are not control flow equivalent");
30 STATISTIC(NotMovedPHINode
, "Movement of PHINodes are not supported");
31 STATISTIC(NotMovedTerminator
, "Movement of Terminator are not supported");
34 /// Represent a control condition. A control condition is a condition of a
35 /// terminator to decide which successors to execute. The pointer field
36 /// represents the address of the condition of the terminator. The integer field
37 /// is a bool, it is true when the basic block is executed when V is true. For
38 /// example, `br %cond, bb0, bb1` %cond is a control condition of bb0 with the
39 /// integer field equals to true, while %cond is a control condition of bb1 with
40 /// the integer field equals to false.
41 using ControlCondition
= PointerIntPair
<Value
*, 1, bool>;
43 raw_ostream
&operator<<(raw_ostream
&OS
, const ControlCondition
&C
) {
44 OS
<< "[" << *C
.getPointer() << ", " << (C
.getInt() ? "true" : "false")
50 /// Represent a set of control conditions required to execute ToBB from FromBB.
51 class ControlConditions
{
52 using ConditionVectorTy
= SmallVector
<ControlCondition
, 6>;
54 /// A SmallVector of control conditions.
55 ConditionVectorTy Conditions
;
58 /// Return a ControlConditions which stores all conditions required to execute
59 /// \p BB from \p Dominator. If \p MaxLookup is non-zero, it limits the
60 /// number of conditions to collect. Return std::nullopt if not all conditions
61 /// are collected successfully, or we hit the limit.
62 static const std::optional
<ControlConditions
>
63 collectControlConditions(const BasicBlock
&BB
, const BasicBlock
&Dominator
,
64 const DominatorTree
&DT
,
65 const PostDominatorTree
&PDT
,
66 unsigned MaxLookup
= 6);
68 /// Return true if there exists no control conditions required to execute ToBB
70 bool isUnconditional() const { return Conditions
.empty(); }
72 /// Return a constant reference of Conditions.
73 const ConditionVectorTy
&getControlConditions() const { return Conditions
; }
75 /// Add \p V as one of the ControlCondition in Condition with IsTrueCondition
76 /// equals to \p True. Return true if inserted successfully.
77 bool addControlCondition(ControlCondition C
);
79 /// Return true if for all control conditions in Conditions, there exists an
80 /// equivalent control condition in \p Other.Conditions.
81 bool isEquivalent(const ControlConditions
&Other
) const;
83 /// Return true if \p C1 and \p C2 are equivalent.
84 static bool isEquivalent(const ControlCondition
&C1
,
85 const ControlCondition
&C2
);
88 ControlConditions() = default;
90 static bool isEquivalent(const Value
&V1
, const Value
&V2
);
91 static bool isInverse(const Value
&V1
, const Value
&V2
);
95 static bool domTreeLevelBefore(DominatorTree
*DT
, const Instruction
*InstA
,
96 const Instruction
*InstB
) {
97 // Use ordered basic block in case the 2 instructions are in the same
99 if (InstA
->getParent() == InstB
->getParent())
100 return InstA
->comesBefore(InstB
);
102 DomTreeNode
*DA
= DT
->getNode(InstA
->getParent());
103 DomTreeNode
*DB
= DT
->getNode(InstB
->getParent());
104 return DA
->getLevel() < DB
->getLevel();
107 const std::optional
<ControlConditions
>
108 ControlConditions::collectControlConditions(const BasicBlock
&BB
,
109 const BasicBlock
&Dominator
,
110 const DominatorTree
&DT
,
111 const PostDominatorTree
&PDT
,
112 unsigned MaxLookup
) {
113 assert(DT
.dominates(&Dominator
, &BB
) && "Expecting Dominator to dominate BB");
115 ControlConditions Conditions
;
116 unsigned NumConditions
= 0;
118 // BB is executed unconditional from itself.
119 if (&Dominator
== &BB
)
122 const BasicBlock
*CurBlock
= &BB
;
123 // Walk up the dominator tree from the associated DT node for BB to the
124 // associated DT node for Dominator.
126 assert(DT
.getNode(CurBlock
) && "Expecting a valid DT node for CurBlock");
127 BasicBlock
*IDom
= DT
.getNode(CurBlock
)->getIDom()->getBlock();
128 assert(DT
.dominates(&Dominator
, IDom
) &&
129 "Expecting Dominator to dominate IDom");
131 // Limitation: can only handle branch instruction currently.
132 const BranchInst
*BI
= dyn_cast
<BranchInst
>(IDom
->getTerminator());
136 bool Inserted
= false;
137 if (PDT
.dominates(CurBlock
, IDom
)) {
138 LLVM_DEBUG(dbgs() << CurBlock
->getName()
139 << " is executed unconditionally from "
140 << IDom
->getName() << "\n");
141 } else if (PDT
.dominates(CurBlock
, BI
->getSuccessor(0))) {
142 LLVM_DEBUG(dbgs() << CurBlock
->getName() << " is executed when \""
143 << *BI
->getCondition() << "\" is true from "
144 << IDom
->getName() << "\n");
145 Inserted
= Conditions
.addControlCondition(
146 ControlCondition(BI
->getCondition(), true));
147 } else if (PDT
.dominates(CurBlock
, BI
->getSuccessor(1))) {
148 LLVM_DEBUG(dbgs() << CurBlock
->getName() << " is executed when \""
149 << *BI
->getCondition() << "\" is false from "
150 << IDom
->getName() << "\n");
151 Inserted
= Conditions
.addControlCondition(
152 ControlCondition(BI
->getCondition(), false));
159 if (MaxLookup
!= 0 && NumConditions
> MaxLookup
)
163 } while (CurBlock
!= &Dominator
);
168 bool ControlConditions::addControlCondition(ControlCondition C
) {
169 bool Inserted
= false;
170 if (none_of(Conditions
, [&](ControlCondition
&Exists
) {
171 return ControlConditions::isEquivalent(C
, Exists
);
173 Conditions
.push_back(C
);
177 LLVM_DEBUG(dbgs() << (Inserted
? "Inserted " : "Not inserted ") << C
<< "\n");
181 bool ControlConditions::isEquivalent(const ControlConditions
&Other
) const {
182 if (Conditions
.empty() && Other
.Conditions
.empty())
185 if (Conditions
.size() != Other
.Conditions
.size())
188 return all_of(Conditions
, [&](const ControlCondition
&C
) {
189 return any_of(Other
.Conditions
, [&](const ControlCondition
&OtherC
) {
190 return ControlConditions::isEquivalent(C
, OtherC
);
195 bool ControlConditions::isEquivalent(const ControlCondition
&C1
,
196 const ControlCondition
&C2
) {
197 if (C1
.getInt() == C2
.getInt()) {
198 if (isEquivalent(*C1
.getPointer(), *C2
.getPointer()))
200 } else if (isInverse(*C1
.getPointer(), *C2
.getPointer()))
206 // FIXME: Use SCEV and reuse GVN/CSE logic to check for equivalence between
208 // Currently, isEquivalent rely on other passes to ensure equivalent conditions
209 // have the same value, e.g. GVN.
210 bool ControlConditions::isEquivalent(const Value
&V1
, const Value
&V2
) {
214 bool ControlConditions::isInverse(const Value
&V1
, const Value
&V2
) {
215 if (const CmpInst
*Cmp1
= dyn_cast
<CmpInst
>(&V1
))
216 if (const CmpInst
*Cmp2
= dyn_cast
<CmpInst
>(&V2
)) {
217 if (Cmp1
->getPredicate() == Cmp2
->getInversePredicate() &&
218 Cmp1
->getOperand(0) == Cmp2
->getOperand(0) &&
219 Cmp1
->getOperand(1) == Cmp2
->getOperand(1))
222 if (Cmp1
->getPredicate() ==
223 CmpInst::getSwappedPredicate(Cmp2
->getInversePredicate()) &&
224 Cmp1
->getOperand(0) == Cmp2
->getOperand(1) &&
225 Cmp1
->getOperand(1) == Cmp2
->getOperand(0))
231 bool llvm::isControlFlowEquivalent(const Instruction
&I0
, const Instruction
&I1
,
232 const DominatorTree
&DT
,
233 const PostDominatorTree
&PDT
) {
234 return isControlFlowEquivalent(*I0
.getParent(), *I1
.getParent(), DT
, PDT
);
237 bool llvm::isControlFlowEquivalent(const BasicBlock
&BB0
, const BasicBlock
&BB1
,
238 const DominatorTree
&DT
,
239 const PostDominatorTree
&PDT
) {
243 if ((DT
.dominates(&BB0
, &BB1
) && PDT
.dominates(&BB1
, &BB0
)) ||
244 (PDT
.dominates(&BB0
, &BB1
) && DT
.dominates(&BB1
, &BB0
)))
247 // If the set of conditions required to execute BB0 and BB1 from their common
248 // dominator are the same, then BB0 and BB1 are control flow equivalent.
249 const BasicBlock
*CommonDominator
= DT
.findNearestCommonDominator(&BB0
, &BB1
);
250 LLVM_DEBUG(dbgs() << "The nearest common dominator of " << BB0
.getName()
251 << " and " << BB1
.getName() << " is "
252 << CommonDominator
->getName() << "\n");
254 const std::optional
<ControlConditions
> BB0Conditions
=
255 ControlConditions::collectControlConditions(BB0
, *CommonDominator
, DT
,
257 if (BB0Conditions
== std::nullopt
)
260 const std::optional
<ControlConditions
> BB1Conditions
=
261 ControlConditions::collectControlConditions(BB1
, *CommonDominator
, DT
,
263 if (BB1Conditions
== std::nullopt
)
266 return BB0Conditions
->isEquivalent(*BB1Conditions
);
269 static bool reportInvalidCandidate(const Instruction
&I
,
270 llvm::Statistic
&Stat
) {
272 LLVM_DEBUG(dbgs() << "Unable to move instruction: " << I
<< ". "
277 /// Collect all instructions in between \p StartInst and \p EndInst, and store
278 /// them in \p InBetweenInsts.
280 collectInstructionsInBetween(Instruction
&StartInst
, const Instruction
&EndInst
,
281 SmallPtrSetImpl
<Instruction
*> &InBetweenInsts
) {
282 assert(InBetweenInsts
.empty() && "Expecting InBetweenInsts to be empty");
284 /// Get the next instructions of \p I, and push them to \p WorkList.
285 auto getNextInsts
= [](Instruction
&I
,
286 SmallPtrSetImpl
<Instruction
*> &WorkList
) {
287 if (Instruction
*NextInst
= I
.getNextNode())
288 WorkList
.insert(NextInst
);
290 assert(I
.isTerminator() && "Expecting a terminator instruction");
291 for (BasicBlock
*Succ
: successors(&I
))
292 WorkList
.insert(&Succ
->front());
296 SmallPtrSet
<Instruction
*, 10> WorkList
;
297 getNextInsts(StartInst
, WorkList
);
298 while (!WorkList
.empty()) {
299 Instruction
*CurInst
= *WorkList
.begin();
300 WorkList
.erase(CurInst
);
302 if (CurInst
== &EndInst
)
305 if (!InBetweenInsts
.insert(CurInst
).second
)
308 getNextInsts(*CurInst
, WorkList
);
312 bool llvm::isSafeToMoveBefore(Instruction
&I
, Instruction
&InsertPoint
,
313 DominatorTree
&DT
, const PostDominatorTree
*PDT
,
314 DependenceInfo
*DI
, bool CheckForEntireBlock
) {
315 // Skip tests when we don't have PDT or DI
319 // Cannot move itself before itself.
320 if (&I
== &InsertPoint
)
324 if (I
.getNextNode() == &InsertPoint
)
327 if (isa
<PHINode
>(I
) || isa
<PHINode
>(InsertPoint
))
328 return reportInvalidCandidate(I
, NotMovedPHINode
);
330 if (I
.isTerminator())
331 return reportInvalidCandidate(I
, NotMovedTerminator
);
333 // TODO remove this limitation.
334 if (!isControlFlowEquivalent(I
, InsertPoint
, DT
, *PDT
))
335 return reportInvalidCandidate(I
, NotControlFlowEquivalent
);
337 if (isReachedBefore(&I
, &InsertPoint
, &DT
, PDT
))
338 for (const Use
&U
: I
.uses())
339 if (auto *UserInst
= dyn_cast
<Instruction
>(U
.getUser()))
340 if (UserInst
!= &InsertPoint
&& !DT
.dominates(&InsertPoint
, U
))
342 if (isReachedBefore(&InsertPoint
, &I
, &DT
, PDT
))
343 for (const Value
*Op
: I
.operands())
344 if (auto *OpInst
= dyn_cast
<Instruction
>(Op
)) {
345 if (&InsertPoint
== OpInst
)
347 // If OpInst is an instruction that appears earlier in the same BB as
348 // I, then it is okay to move since OpInst will still be available.
349 if (CheckForEntireBlock
&& I
.getParent() == OpInst
->getParent() &&
350 DT
.dominates(OpInst
, &I
))
352 if (!DT
.dominates(OpInst
, &InsertPoint
))
356 DT
.updateDFSNumbers();
357 const bool MoveForward
= domTreeLevelBefore(&DT
, &I
, &InsertPoint
);
358 Instruction
&StartInst
= (MoveForward
? I
: InsertPoint
);
359 Instruction
&EndInst
= (MoveForward
? InsertPoint
: I
);
360 SmallPtrSet
<Instruction
*, 10> InstsToCheck
;
361 collectInstructionsInBetween(StartInst
, EndInst
, InstsToCheck
);
363 InstsToCheck
.insert(&InsertPoint
);
365 // Check if there exists instructions which may throw, may synchonize, or may
366 // never return, from I to InsertPoint.
367 if (!isSafeToSpeculativelyExecute(&I
))
368 if (llvm::any_of(InstsToCheck
, [](Instruction
*I
) {
372 const CallBase
*CB
= dyn_cast
<CallBase
>(I
);
375 if (!CB
->hasFnAttr(Attribute::WillReturn
))
377 if (!CB
->hasFnAttr(Attribute::NoSync
))
382 return reportInvalidCandidate(I
, MayThrowException
);
385 // Check if I has any output/flow/anti dependences with instructions from \p
386 // StartInst to \p EndInst.
387 if (llvm::any_of(InstsToCheck
, [&DI
, &I
](Instruction
*CurInst
) {
388 auto DepResult
= DI
->depends(&I
, CurInst
, true);
389 if (DepResult
&& (DepResult
->isOutput() || DepResult
->isFlow() ||
390 DepResult
->isAnti()))
394 return reportInvalidCandidate(I
, HasDependences
);
399 bool llvm::isSafeToMoveBefore(BasicBlock
&BB
, Instruction
&InsertPoint
,
400 DominatorTree
&DT
, const PostDominatorTree
*PDT
,
401 DependenceInfo
*DI
) {
402 return llvm::all_of(BB
, [&](Instruction
&I
) {
403 if (BB
.getTerminator() == &I
)
406 return isSafeToMoveBefore(I
, InsertPoint
, DT
, PDT
, DI
,
407 /*CheckForEntireBlock=*/true);
411 void llvm::moveInstructionsToTheBeginning(BasicBlock
&FromBB
, BasicBlock
&ToBB
,
413 const PostDominatorTree
&PDT
,
414 DependenceInfo
&DI
) {
415 for (Instruction
&I
:
416 llvm::make_early_inc_range(llvm::drop_begin(llvm::reverse(FromBB
)))) {
417 Instruction
*MovePos
= ToBB
.getFirstNonPHIOrDbg();
419 if (isSafeToMoveBefore(I
, *MovePos
, DT
, &PDT
, &DI
))
420 I
.moveBeforePreserving(MovePos
);
424 void llvm::moveInstructionsToTheEnd(BasicBlock
&FromBB
, BasicBlock
&ToBB
,
426 const PostDominatorTree
&PDT
,
427 DependenceInfo
&DI
) {
428 Instruction
*MovePos
= ToBB
.getTerminator();
429 while (FromBB
.size() > 1) {
430 Instruction
&I
= FromBB
.front();
431 if (isSafeToMoveBefore(I
, *MovePos
, DT
, &PDT
, &DI
))
432 I
.moveBeforePreserving(MovePos
);
436 bool llvm::nonStrictlyPostDominate(const BasicBlock
*ThisBlock
,
437 const BasicBlock
*OtherBlock
,
438 const DominatorTree
*DT
,
439 const PostDominatorTree
*PDT
) {
440 assert(isControlFlowEquivalent(*ThisBlock
, *OtherBlock
, *DT
, *PDT
) &&
441 "ThisBlock and OtherBlock must be CFG equivalent!");
442 const BasicBlock
*CommonDominator
=
443 DT
->findNearestCommonDominator(ThisBlock
, OtherBlock
);
444 if (CommonDominator
== nullptr)
447 /// Recursively check the predecessors of \p ThisBlock up to
448 /// their common dominator, and see if any of them post-dominates
450 SmallVector
<const BasicBlock
*, 8> WorkList
;
451 SmallPtrSet
<const BasicBlock
*, 8> Visited
;
452 WorkList
.push_back(ThisBlock
);
453 while (!WorkList
.empty()) {
454 const BasicBlock
*CurBlock
= WorkList
.back();
456 Visited
.insert(CurBlock
);
457 if (PDT
->dominates(CurBlock
, OtherBlock
))
460 for (const auto *Pred
: predecessors(CurBlock
)) {
461 if (Pred
== CommonDominator
|| Visited
.count(Pred
))
463 WorkList
.push_back(Pred
);
469 bool llvm::isReachedBefore(const Instruction
*I0
, const Instruction
*I1
,
470 const DominatorTree
*DT
,
471 const PostDominatorTree
*PDT
) {
472 const BasicBlock
*BB0
= I0
->getParent();
473 const BasicBlock
*BB1
= I1
->getParent();
475 return DT
->dominates(I0
, I1
);
477 return nonStrictlyPostDominate(BB1
, BB0
, DT
, PDT
);