1 //===- CodeMoverUtils.cpp - CodeMover Utilities ----------------------------==// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This family of functions perform movements on basic blocks, and instructions 10 // contained within a function. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Utils/CodeMoverUtils.h" 15 #include "llvm/ADT/Optional.h" 16 #include "llvm/ADT/Statistic.h" 17 #include "llvm/Analysis/DependenceAnalysis.h" 18 #include "llvm/Analysis/OrderedInstructions.h" 19 #include "llvm/Analysis/PostDominators.h" 20 #include "llvm/Analysis/ValueTracking.h" 21 #include "llvm/IR/Dominators.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "codemover-utils" 26 27 STATISTIC(HasDependences, 28 "Cannot move across instructions that has memory dependences"); 29 STATISTIC(MayThrowException, "Cannot move across instructions that may throw"); 30 STATISTIC(NotControlFlowEquivalent, 31 "Instructions are not control flow equivalent"); 32 STATISTIC(NotMovedPHINode, "Movement of PHINodes are not supported"); 33 STATISTIC(NotMovedTerminator, "Movement of Terminator are not supported"); 34 35 namespace { 36 /// Represent a control condition. A control condition is a condition of a 37 /// terminator to decide which successors to execute. The pointer field 38 /// represents the address of the condition of the terminator. The integer field 39 /// is a bool, it is true when the basic block is executed when V is true. For 40 /// example, `br %cond, bb0, bb1` %cond is a control condition of bb0 with the 41 /// integer field equals to true, while %cond is a control condition of bb1 with 42 /// the integer field equals to false. 43 using ControlCondition = PointerIntPair<Value *, 1, bool>; 44 #ifndef NDEBUG 45 raw_ostream &operator<<(raw_ostream &OS, const ControlCondition &C) { 46 OS << "[" << *C.getPointer() << ", " << (C.getInt() ? "true" : "false") 47 << "]"; 48 return OS; 49 } 50 #endif 51 52 /// Represent a set of control conditions required to execute ToBB from FromBB. 53 class ControlConditions { 54 using ConditionVectorTy = SmallVector<ControlCondition, 6>; 55 56 /// A SmallVector of control conditions. 57 ConditionVectorTy Conditions; 58 59 public: 60 /// Return a ControlConditions which stores all conditions required to execute 61 /// \p BB from \p Dominator. If \p MaxLookup is non-zero, it limits the 62 /// number of conditions to collect. Return None if not all conditions are 63 /// collected successfully, or we hit the limit. 64 static const Optional<ControlConditions> 65 collectControlConditions(const BasicBlock &BB, const BasicBlock &Dominator, 66 const DominatorTree &DT, 67 const PostDominatorTree &PDT, 68 unsigned MaxLookup = 6); 69 70 /// Return true if there exists no control conditions required to execute ToBB 71 /// from FromBB. 72 bool isUnconditional() const { return Conditions.empty(); } 73 74 /// Return a constant reference of Conditions. 75 const ConditionVectorTy &getControlConditions() const { return Conditions; } 76 77 /// Add \p V as one of the ControlCondition in Condition with IsTrueCondition 78 /// equals to \p True. Return true if inserted successfully. 79 bool addControlCondition(ControlCondition C); 80 81 /// Return true if for all control conditions in Conditions, there exists an 82 /// equivalent control condition in \p Other.Conditions. 83 bool isEquivalent(const ControlConditions &Other) const; 84 85 /// Return true if \p C1 and \p C2 are equivalent. 86 static bool isEquivalent(const ControlCondition &C1, 87 const ControlCondition &C2); 88 89 private: 90 ControlConditions() = default; 91 92 static bool isEquivalent(const Value &V1, const Value &V2); 93 static bool isInverse(const Value &V1, const Value &V2); 94 }; 95 } // namespace 96 97 const Optional<ControlConditions> ControlConditions::collectControlConditions( 98 const BasicBlock &BB, const BasicBlock &Dominator, const DominatorTree &DT, 99 const PostDominatorTree &PDT, unsigned MaxLookup) { 100 assert(DT.dominates(&Dominator, &BB) && "Expecting Dominator to dominate BB"); 101 102 ControlConditions Conditions; 103 unsigned NumConditions = 0; 104 105 // BB is executed unconditional from itself. 106 if (&Dominator == &BB) 107 return Conditions; 108 109 const BasicBlock *CurBlock = &BB; 110 // Walk up the dominator tree from the associated DT node for BB to the 111 // associated DT node for Dominator. 112 do { 113 assert(DT.getNode(CurBlock) && "Expecting a valid DT node for CurBlock"); 114 BasicBlock *IDom = DT.getNode(CurBlock)->getIDom()->getBlock(); 115 assert(DT.dominates(&Dominator, IDom) && 116 "Expecting Dominator to dominate IDom"); 117 118 // Limitation: can only handle branch instruction currently. 119 const BranchInst *BI = dyn_cast<BranchInst>(IDom->getTerminator()); 120 if (!BI) 121 return None; 122 123 bool Inserted = false; 124 if (PDT.dominates(CurBlock, IDom)) { 125 LLVM_DEBUG(dbgs() << CurBlock->getName() 126 << " is executed unconditionally from " 127 << IDom->getName() << "\n"); 128 } else if (PDT.dominates(CurBlock, BI->getSuccessor(0))) { 129 LLVM_DEBUG(dbgs() << CurBlock->getName() << " is executed when \"" 130 << *BI->getCondition() << "\" is true from " 131 << IDom->getName() << "\n"); 132 Inserted = Conditions.addControlCondition( 133 ControlCondition(BI->getCondition(), true)); 134 } else if (PDT.dominates(CurBlock, BI->getSuccessor(1))) { 135 LLVM_DEBUG(dbgs() << CurBlock->getName() << " is executed when \"" 136 << *BI->getCondition() << "\" is false from " 137 << IDom->getName() << "\n"); 138 Inserted = Conditions.addControlCondition( 139 ControlCondition(BI->getCondition(), false)); 140 } else 141 return None; 142 143 if (Inserted) 144 ++NumConditions; 145 146 if (MaxLookup != 0 && NumConditions > MaxLookup) 147 return None; 148 149 CurBlock = IDom; 150 } while (CurBlock != &Dominator); 151 152 return Conditions; 153 } 154 155 bool ControlConditions::addControlCondition(ControlCondition C) { 156 bool Inserted = false; 157 if (none_of(Conditions, [&C](ControlCondition &Exists) { 158 return ControlConditions::isEquivalent(C, Exists); 159 })) { 160 Conditions.push_back(C); 161 Inserted = true; 162 } 163 164 LLVM_DEBUG(dbgs() << (Inserted ? "Inserted " : "Not inserted ") << C << "\n"); 165 return Inserted; 166 } 167 168 bool ControlConditions::isEquivalent(const ControlConditions &Other) const { 169 if (Conditions.empty() && Other.Conditions.empty()) 170 return true; 171 172 if (Conditions.size() != Other.Conditions.size()) 173 return false; 174 175 return all_of(Conditions, [&Other](const ControlCondition &C) { 176 return any_of(Other.Conditions, [&C](const ControlCondition &OtherC) { 177 return ControlConditions::isEquivalent(C, OtherC); 178 }); 179 }); 180 } 181 182 bool ControlConditions::isEquivalent(const ControlCondition &C1, 183 const ControlCondition &C2) { 184 if (C1.getInt() == C2.getInt()) { 185 if (isEquivalent(*C1.getPointer(), *C2.getPointer())) 186 return true; 187 } else if (isInverse(*C1.getPointer(), *C2.getPointer())) 188 return true; 189 190 return false; 191 } 192 193 // FIXME: Use SCEV and reuse GVN/CSE logic to check for equivalence between 194 // Values. 195 // Currently, isEquivalent rely on other passes to ensure equivalent conditions 196 // have the same value, e.g. GVN. 197 bool ControlConditions::isEquivalent(const Value &V1, const Value &V2) { 198 return &V1 == &V2; 199 } 200 201 bool ControlConditions::isInverse(const Value &V1, const Value &V2) { 202 if (const CmpInst *Cmp1 = dyn_cast<CmpInst>(&V1)) 203 if (const CmpInst *Cmp2 = dyn_cast<CmpInst>(&V2)) { 204 if (Cmp1->getPredicate() == Cmp2->getInversePredicate() && 205 Cmp1->getOperand(0) == Cmp2->getOperand(0) && 206 Cmp1->getOperand(1) == Cmp2->getOperand(1)) 207 return true; 208 209 if (Cmp1->getPredicate() == 210 CmpInst::getSwappedPredicate(Cmp2->getInversePredicate()) && 211 Cmp1->getOperand(0) == Cmp2->getOperand(1) && 212 Cmp1->getOperand(1) == Cmp2->getOperand(0)) 213 return true; 214 } 215 return false; 216 } 217 218 bool llvm::isControlFlowEquivalent(const Instruction &I0, const Instruction &I1, 219 const DominatorTree &DT, 220 const PostDominatorTree &PDT) { 221 return isControlFlowEquivalent(*I0.getParent(), *I1.getParent(), DT, PDT); 222 } 223 224 bool llvm::isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1, 225 const DominatorTree &DT, 226 const PostDominatorTree &PDT) { 227 if (&BB0 == &BB1) 228 return true; 229 230 if ((DT.dominates(&BB0, &BB1) && PDT.dominates(&BB1, &BB0)) || 231 (PDT.dominates(&BB0, &BB1) && DT.dominates(&BB1, &BB0))) 232 return true; 233 234 // If the set of conditions required to execute BB0 and BB1 from their common 235 // dominator are the same, then BB0 and BB1 are control flow equivalent. 236 const BasicBlock *CommonDominator = DT.findNearestCommonDominator(&BB0, &BB1); 237 LLVM_DEBUG(dbgs() << "The nearest common dominator of " << BB0.getName() 238 << " and " << BB1.getName() << " is " 239 << CommonDominator->getName() << "\n"); 240 241 const Optional<ControlConditions> BB0Conditions = 242 ControlConditions::collectControlConditions(BB0, *CommonDominator, DT, 243 PDT); 244 if (BB0Conditions == None) 245 return false; 246 247 const Optional<ControlConditions> BB1Conditions = 248 ControlConditions::collectControlConditions(BB1, *CommonDominator, DT, 249 PDT); 250 if (BB1Conditions == None) 251 return false; 252 253 return BB0Conditions->isEquivalent(*BB1Conditions); 254 } 255 256 static bool reportInvalidCandidate(const Instruction &I, 257 llvm::Statistic &Stat) { 258 ++Stat; 259 LLVM_DEBUG(dbgs() << "Unable to move instruction: " << I << ". " 260 << Stat.getDesc()); 261 return false; 262 } 263 264 /// Collect all instructions in between \p StartInst and \p EndInst, and store 265 /// them in \p InBetweenInsts. 266 static void 267 collectInstructionsInBetween(Instruction &StartInst, const Instruction &EndInst, 268 SmallPtrSetImpl<Instruction *> &InBetweenInsts) { 269 assert(InBetweenInsts.empty() && "Expecting InBetweenInsts to be empty"); 270 271 /// Get the next instructions of \p I, and push them to \p WorkList. 272 auto getNextInsts = [](Instruction &I, 273 SmallPtrSetImpl<Instruction *> &WorkList) { 274 if (Instruction *NextInst = I.getNextNode()) 275 WorkList.insert(NextInst); 276 else { 277 assert(I.isTerminator() && "Expecting a terminator instruction"); 278 for (BasicBlock *Succ : successors(&I)) 279 WorkList.insert(&Succ->front()); 280 } 281 }; 282 283 SmallPtrSet<Instruction *, 10> WorkList; 284 getNextInsts(StartInst, WorkList); 285 while (!WorkList.empty()) { 286 Instruction *CurInst = *WorkList.begin(); 287 WorkList.erase(CurInst); 288 289 if (CurInst == &EndInst) 290 continue; 291 292 if (!InBetweenInsts.insert(CurInst).second) 293 continue; 294 295 getNextInsts(*CurInst, WorkList); 296 } 297 } 298 299 bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint, 300 DominatorTree &DT, const PostDominatorTree &PDT, 301 DependenceInfo &DI) { 302 // Cannot move itself before itself. 303 if (&I == &InsertPoint) 304 return false; 305 306 // Not moved. 307 if (I.getNextNode() == &InsertPoint) 308 return true; 309 310 if (isa<PHINode>(I) || isa<PHINode>(InsertPoint)) 311 return reportInvalidCandidate(I, NotMovedPHINode); 312 313 if (I.isTerminator()) 314 return reportInvalidCandidate(I, NotMovedTerminator); 315 316 // TODO remove this limitation. 317 if (!isControlFlowEquivalent(I, InsertPoint, DT, PDT)) 318 return reportInvalidCandidate(I, NotControlFlowEquivalent); 319 320 OrderedInstructions OI(&DT); 321 DT.updateDFSNumbers(); 322 const bool MoveForward = OI.dfsBefore(&I, &InsertPoint); 323 if (MoveForward) { 324 // When I is being moved forward, we need to make sure the InsertPoint 325 // dominates every users. Or else, a user may be using an undefined I. 326 for (const Use &U : I.uses()) 327 if (auto *UserInst = dyn_cast<Instruction>(U.getUser())) 328 if (UserInst != &InsertPoint && !DT.dominates(&InsertPoint, U)) 329 return false; 330 } else { 331 // When I is being moved backward, we need to make sure all its opernads 332 // dominates the InsertPoint. Or else, an operand may be undefined for I. 333 for (const Value *Op : I.operands()) 334 if (auto *OpInst = dyn_cast<Instruction>(Op)) 335 if (&InsertPoint == OpInst || !OI.dominates(OpInst, &InsertPoint)) 336 return false; 337 } 338 339 Instruction &StartInst = (MoveForward ? I : InsertPoint); 340 Instruction &EndInst = (MoveForward ? InsertPoint : I); 341 SmallPtrSet<Instruction *, 10> InstsToCheck; 342 collectInstructionsInBetween(StartInst, EndInst, InstsToCheck); 343 if (!MoveForward) 344 InstsToCheck.insert(&InsertPoint); 345 346 // Check if there exists instructions which may throw, may synchonize, or may 347 // never return, from I to InsertPoint. 348 if (!isSafeToSpeculativelyExecute(&I)) 349 if (std::any_of(InstsToCheck.begin(), InstsToCheck.end(), 350 [](Instruction *I) { 351 if (I->mayThrow()) 352 return true; 353 354 const CallBase *CB = dyn_cast<CallBase>(I); 355 if (!CB) 356 return false; 357 if (!CB->hasFnAttr(Attribute::WillReturn)) 358 return true; 359 if (!CB->hasFnAttr(Attribute::NoSync)) 360 return true; 361 362 return false; 363 })) { 364 return reportInvalidCandidate(I, MayThrowException); 365 } 366 367 // Check if I has any output/flow/anti dependences with instructions from \p 368 // StartInst to \p EndInst. 369 if (std::any_of(InstsToCheck.begin(), InstsToCheck.end(), 370 [&DI, &I](Instruction *CurInst) { 371 auto DepResult = DI.depends(&I, CurInst, true); 372 if (DepResult && 373 (DepResult->isOutput() || DepResult->isFlow() || 374 DepResult->isAnti())) 375 return true; 376 return false; 377 })) 378 return reportInvalidCandidate(I, HasDependences); 379 380 return true; 381 } 382 383 void llvm::moveInstructionsToTheBeginning(BasicBlock &FromBB, BasicBlock &ToBB, 384 DominatorTree &DT, 385 const PostDominatorTree &PDT, 386 DependenceInfo &DI) { 387 for (auto It = ++FromBB.rbegin(); It != FromBB.rend();) { 388 Instruction *MovePos = ToBB.getFirstNonPHIOrDbg(); 389 Instruction &I = *It; 390 // Increment the iterator before modifying FromBB. 391 ++It; 392 393 if (isSafeToMoveBefore(I, *MovePos, DT, PDT, DI)) 394 I.moveBefore(MovePos); 395 } 396 } 397