1 //===-- ConstraintElimination.cpp - Eliminate conds using constraints. ----===// 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 // Eliminate conditions based on constraints collected from dominating 10 // conditions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Scalar/ConstraintElimination.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/ScopeExit.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/Analysis/ConstraintSystem.h" 20 #include "llvm/Analysis/GlobalsModRef.h" 21 #include "llvm/Analysis/ValueTracking.h" 22 #include "llvm/IR/Dominators.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/IRBuilder.h" 25 #include "llvm/IR/Instructions.h" 26 #include "llvm/IR/PatternMatch.h" 27 #include "llvm/InitializePasses.h" 28 #include "llvm/Pass.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/DebugCounter.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Transforms/Scalar.h" 33 34 #include <string> 35 36 using namespace llvm; 37 using namespace PatternMatch; 38 39 #define DEBUG_TYPE "constraint-elimination" 40 41 STATISTIC(NumCondsRemoved, "Number of instructions removed"); 42 DEBUG_COUNTER(EliminatedCounter, "conds-eliminated", 43 "Controls which conditions are eliminated"); 44 45 static int64_t MaxConstraintValue = std::numeric_limits<int64_t>::max(); 46 static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t>::min(); 47 48 namespace { 49 50 class ConstraintInfo; 51 52 /// Struct to express a pre-condition of the form %Op0 Pred %Op1. 53 struct PreconditionTy { 54 CmpInst::Predicate Pred; 55 Value *Op0; 56 Value *Op1; 57 58 PreconditionTy(CmpInst::Predicate Pred, Value *Op0, Value *Op1) 59 : Pred(Pred), Op0(Op0), Op1(Op1) {} 60 }; 61 62 struct ConstraintTy { 63 SmallVector<int64_t, 8> Coefficients; 64 SmallVector<PreconditionTy, 2> Preconditions; 65 66 bool IsSigned = false; 67 bool IsEq = false; 68 69 ConstraintTy() = default; 70 71 ConstraintTy(SmallVector<int64_t, 8> Coefficients, bool IsSigned) 72 : Coefficients(Coefficients), IsSigned(IsSigned) {} 73 74 unsigned size() const { return Coefficients.size(); } 75 76 unsigned empty() const { return Coefficients.empty(); } 77 78 /// Returns true if any constraint has a non-zero coefficient for any of the 79 /// newly added indices. Zero coefficients for new indices are removed. If it 80 /// returns true, no new variable need to be added to the system. 81 bool needsNewIndices(const DenseMap<Value *, unsigned> &NewIndices) { 82 for (unsigned I = 0; I < NewIndices.size(); ++I) { 83 int64_t Last = Coefficients.pop_back_val(); 84 if (Last != 0) 85 return true; 86 } 87 return false; 88 } 89 90 /// Returns true if all preconditions for this list of constraints are 91 /// satisfied given \p CS and the corresponding \p Value2Index mapping. 92 bool isValid(const ConstraintInfo &Info) const; 93 }; 94 95 /// Wrapper encapsulating separate constraint systems and corresponding value 96 /// mappings for both unsigned and signed information. Facts are added to and 97 /// conditions are checked against the corresponding system depending on the 98 /// signed-ness of their predicates. While the information is kept separate 99 /// based on signed-ness, certain conditions can be transferred between the two 100 /// systems. 101 class ConstraintInfo { 102 DenseMap<Value *, unsigned> UnsignedValue2Index; 103 DenseMap<Value *, unsigned> SignedValue2Index; 104 105 ConstraintSystem UnsignedCS; 106 ConstraintSystem SignedCS; 107 108 public: 109 DenseMap<Value *, unsigned> &getValue2Index(bool Signed) { 110 return Signed ? SignedValue2Index : UnsignedValue2Index; 111 } 112 const DenseMap<Value *, unsigned> &getValue2Index(bool Signed) const { 113 return Signed ? SignedValue2Index : UnsignedValue2Index; 114 } 115 116 ConstraintSystem &getCS(bool Signed) { 117 return Signed ? SignedCS : UnsignedCS; 118 } 119 const ConstraintSystem &getCS(bool Signed) const { 120 return Signed ? SignedCS : UnsignedCS; 121 } 122 123 void popLastConstraint(bool Signed) { getCS(Signed).popLastConstraint(); } 124 void popLastNVariables(bool Signed, unsigned N) { 125 getCS(Signed).popLastNVariables(N); 126 } 127 }; 128 129 } // namespace 130 131 // Decomposes \p V into a vector of pairs of the form { c, X } where c * X. The 132 // sum of the pairs equals \p V. The first pair is the constant-factor and X 133 // must be nullptr. If the expression cannot be decomposed, returns an empty 134 // vector. 135 static SmallVector<std::pair<int64_t, Value *>, 4> 136 decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions, 137 bool IsSigned) { 138 139 auto CanUseSExt = [](ConstantInt *CI) { 140 const APInt &Val = CI->getValue(); 141 return Val.sgt(MinSignedConstraintValue) && Val.slt(MaxConstraintValue); 142 }; 143 // Decompose \p V used with a signed predicate. 144 if (IsSigned) { 145 if (auto *CI = dyn_cast<ConstantInt>(V)) { 146 if (CanUseSExt(CI)) 147 return {{CI->getSExtValue(), nullptr}}; 148 } 149 150 return {{0, nullptr}, {1, V}}; 151 } 152 153 if (auto *CI = dyn_cast<ConstantInt>(V)) { 154 if (CI->uge(MaxConstraintValue)) 155 return {}; 156 return {{CI->getZExtValue(), nullptr}}; 157 } 158 auto *GEP = dyn_cast<GetElementPtrInst>(V); 159 if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) { 160 Value *Op0, *Op1; 161 ConstantInt *CI; 162 163 // If the index is zero-extended, it is guaranteed to be positive. 164 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 165 m_ZExt(m_Value(Op0)))) { 166 if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && 167 CanUseSExt(CI)) 168 return {{0, nullptr}, 169 {1, GEP->getPointerOperand()}, 170 {std::pow(int64_t(2), CI->getSExtValue()), Op1}}; 171 if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) && 172 CanUseSExt(CI)) 173 return {{CI->getSExtValue(), nullptr}, 174 {1, GEP->getPointerOperand()}, 175 {1, Op1}}; 176 return {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}}; 177 } 178 179 if (match(GEP->getOperand(GEP->getNumOperands() - 1), m_ConstantInt(CI)) && 180 !CI->isNegative() && CanUseSExt(CI)) 181 return {{CI->getSExtValue(), nullptr}, {1, GEP->getPointerOperand()}}; 182 183 SmallVector<std::pair<int64_t, Value *>, 4> Result; 184 if (match(GEP->getOperand(GEP->getNumOperands() - 1), 185 m_NUWShl(m_Value(Op0), m_ConstantInt(CI))) && 186 CanUseSExt(CI)) 187 Result = {{0, nullptr}, 188 {1, GEP->getPointerOperand()}, 189 {std::pow(int64_t(2), CI->getSExtValue()), Op0}}; 190 else if (match(GEP->getOperand(GEP->getNumOperands() - 1), 191 m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) && 192 CanUseSExt(CI)) 193 Result = {{CI->getSExtValue(), nullptr}, 194 {1, GEP->getPointerOperand()}, 195 {1, Op0}}; 196 else { 197 Op0 = GEP->getOperand(GEP->getNumOperands() - 1); 198 Result = {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}}; 199 } 200 // If Op0 is signed non-negative, the GEP is increasing monotonically and 201 // can be de-composed. 202 Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0, 203 ConstantInt::get(Op0->getType(), 0)); 204 return Result; 205 } 206 207 Value *Op0; 208 if (match(V, m_ZExt(m_Value(Op0)))) 209 V = Op0; 210 211 Value *Op1; 212 ConstantInt *CI; 213 if (match(V, m_NUWAdd(m_Value(Op0), m_ConstantInt(CI))) && 214 !CI->uge(MaxConstraintValue)) 215 return {{CI->getZExtValue(), nullptr}, {1, Op0}}; 216 if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative() && 217 CanUseSExt(CI)) { 218 Preconditions.emplace_back( 219 CmpInst::ICMP_UGE, Op0, 220 ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1)); 221 return {{CI->getSExtValue(), nullptr}, {1, Op0}}; 222 } 223 if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) 224 return {{0, nullptr}, {1, Op0}, {1, Op1}}; 225 226 if (match(V, m_NUWSub(m_Value(Op0), m_ConstantInt(CI))) && CanUseSExt(CI)) 227 return {{-1 * CI->getSExtValue(), nullptr}, {1, Op0}}; 228 if (match(V, m_NUWSub(m_Value(Op0), m_Value(Op1)))) 229 return {{0, nullptr}, {1, Op0}, {-1, Op1}}; 230 231 return {{0, nullptr}, {1, V}}; 232 } 233 234 /// Turn a condition \p CmpI into a vector of constraints, using indices from \p 235 /// Value2Index. Additional indices for newly discovered values are added to \p 236 /// NewIndices. 237 static ConstraintTy 238 getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1, 239 const DenseMap<Value *, unsigned> &Value2Index, 240 DenseMap<Value *, unsigned> &NewIndices) { 241 bool IsEq = false; 242 // Try to convert Pred to one of ULE/SLT/SLE/SLT. 243 switch (Pred) { 244 case CmpInst::ICMP_UGT: 245 case CmpInst::ICMP_UGE: 246 case CmpInst::ICMP_SGT: 247 case CmpInst::ICMP_SGE: { 248 Pred = CmpInst::getSwappedPredicate(Pred); 249 std::swap(Op0, Op1); 250 break; 251 } 252 case CmpInst::ICMP_EQ: 253 if (match(Op1, m_Zero())) { 254 Pred = CmpInst::ICMP_ULE; 255 } else { 256 IsEq = true; 257 Pred = CmpInst::ICMP_ULE; 258 } 259 break; 260 case CmpInst::ICMP_NE: 261 if (!match(Op1, m_Zero())) 262 return {}; 263 Pred = CmpInst::getSwappedPredicate(CmpInst::ICMP_UGT); 264 std::swap(Op0, Op1); 265 break; 266 default: 267 break; 268 } 269 270 // Only ULE and ULT predicates are supported at the moment. 271 if (Pred != CmpInst::ICMP_ULE && Pred != CmpInst::ICMP_ULT && 272 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT) 273 return {}; 274 275 SmallVector<PreconditionTy, 4> Preconditions; 276 bool IsSigned = CmpInst::isSigned(Pred); 277 auto ADec = decompose(Op0->stripPointerCastsSameRepresentation(), 278 Preconditions, IsSigned); 279 auto BDec = decompose(Op1->stripPointerCastsSameRepresentation(), 280 Preconditions, IsSigned); 281 // Skip if decomposing either of the values failed. 282 if (ADec.empty() || BDec.empty()) 283 return {}; 284 285 int64_t Offset1 = ADec[0].first; 286 int64_t Offset2 = BDec[0].first; 287 Offset1 *= -1; 288 289 // Create iterator ranges that skip the constant-factor. 290 auto VariablesA = llvm::drop_begin(ADec); 291 auto VariablesB = llvm::drop_begin(BDec); 292 293 // First try to look up \p V in Value2Index and NewIndices. Otherwise add a 294 // new entry to NewIndices. 295 auto GetOrAddIndex = [&Value2Index, &NewIndices](Value *V) -> unsigned { 296 auto V2I = Value2Index.find(V); 297 if (V2I != Value2Index.end()) 298 return V2I->second; 299 auto Insert = 300 NewIndices.insert({V, Value2Index.size() + NewIndices.size() + 1}); 301 return Insert.first->second; 302 }; 303 304 // Make sure all variables have entries in Value2Index or NewIndices. 305 for (const auto &KV : 306 concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB)) 307 GetOrAddIndex(KV.second); 308 309 // Build result constraint, by first adding all coefficients from A and then 310 // subtracting all coefficients from B. 311 ConstraintTy Res( 312 SmallVector<int64_t, 8>(Value2Index.size() + NewIndices.size() + 1, 0), 313 IsSigned); 314 Res.IsEq = IsEq; 315 auto &R = Res.Coefficients; 316 for (const auto &KV : VariablesA) 317 R[GetOrAddIndex(KV.second)] += KV.first; 318 319 for (const auto &KV : VariablesB) 320 R[GetOrAddIndex(KV.second)] -= KV.first; 321 322 int64_t OffsetSum; 323 if (AddOverflow(Offset1, Offset2, OffsetSum)) 324 return {}; 325 if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT)) 326 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum)) 327 return {}; 328 R[0] = OffsetSum; 329 Res.Preconditions = std::move(Preconditions); 330 return Res; 331 } 332 333 static ConstraintTy getConstraint(CmpInst *Cmp, ConstraintInfo &Info, 334 DenseMap<Value *, unsigned> &NewIndices) { 335 return getConstraint( 336 Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), 337 Info.getValue2Index(CmpInst::isSigned(Cmp->getPredicate())), NewIndices); 338 } 339 340 bool ConstraintTy::isValid(const ConstraintInfo &Info) const { 341 return Coefficients.size() > 0 && 342 all_of(Preconditions, [&Info](const PreconditionTy &C) { 343 DenseMap<Value *, unsigned> NewIndices; 344 auto R = getConstraint( 345 C.Pred, C.Op0, C.Op1, 346 Info.getValue2Index(CmpInst::isSigned(C.Pred)), NewIndices); 347 // TODO: properly check NewIndices. 348 return NewIndices.empty() && R.Preconditions.empty() && !R.IsEq && 349 R.size() >= 1 && 350 Info.getCS(CmpInst::isSigned(C.Pred)) 351 .isConditionImplied(R.Coefficients); 352 }); 353 } 354 355 namespace { 356 /// Represents either a condition that holds on entry to a block or a basic 357 /// block, with their respective Dominator DFS in and out numbers. 358 struct ConstraintOrBlock { 359 unsigned NumIn; 360 unsigned NumOut; 361 bool IsBlock; 362 bool Not; 363 union { 364 BasicBlock *BB; 365 CmpInst *Condition; 366 }; 367 368 ConstraintOrBlock(DomTreeNode *DTN) 369 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true), 370 BB(DTN->getBlock()) {} 371 ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not) 372 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false), 373 Not(Not), Condition(Condition) {} 374 }; 375 376 struct StackEntry { 377 unsigned NumIn; 378 unsigned NumOut; 379 Instruction *Condition; 380 bool IsNot; 381 bool IsSigned = false; 382 /// Variables that can be removed from the system once the stack entry gets 383 /// removed. 384 SmallVector<Value *, 2> ValuesToRelease; 385 386 StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot, 387 bool IsSigned, SmallVector<Value *, 2> ValuesToRelease) 388 : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot), 389 IsSigned(IsSigned), ValuesToRelease(ValuesToRelease) {} 390 }; 391 392 /// Keep state required to build worklist. 393 struct State { 394 DominatorTree &DT; 395 SmallVector<ConstraintOrBlock, 64> WorkList; 396 397 State(DominatorTree &DT) : DT(DT) {} 398 399 /// Process block \p BB and add known facts to work-list. 400 void addInfoFor(BasicBlock &BB); 401 402 /// Returns true if we can add a known condition from BB to its successor 403 /// block Succ. Each predecessor of Succ can either be BB or be dominated 404 /// by Succ (e.g. the case when adding a condition from a pre-header to a 405 /// loop header). 406 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const { 407 if (BB.getSingleSuccessor()) { 408 assert(BB.getSingleSuccessor() == Succ); 409 return DT.properlyDominates(&BB, Succ); 410 } 411 return any_of(successors(&BB), 412 [Succ](const BasicBlock *S) { return S != Succ; }) && 413 all_of(predecessors(Succ), [&BB, Succ, this](BasicBlock *Pred) { 414 return Pred == &BB || DT.dominates(Succ, Pred); 415 }); 416 } 417 }; 418 419 } // namespace 420 421 #ifndef NDEBUG 422 static void dumpWithNames(ConstraintTy &C, 423 DenseMap<Value *, unsigned> &Value2Index) { 424 SmallVector<std::string> Names(Value2Index.size(), ""); 425 for (auto &KV : Value2Index) { 426 Names[KV.second - 1] = std::string("%") + KV.first->getName().str(); 427 } 428 ConstraintSystem CS; 429 CS.addVariableRowFill(C.Coefficients); 430 CS.dump(Names); 431 } 432 #endif 433 434 void State::addInfoFor(BasicBlock &BB) { 435 WorkList.emplace_back(DT.getNode(&BB)); 436 437 // True as long as long as the current instruction is guaranteed to execute. 438 bool GuaranteedToExecute = true; 439 // Scan BB for assume calls. 440 // TODO: also use this scan to queue conditions to simplify, so we can 441 // interleave facts from assumes and conditions to simplify in a single 442 // basic block. And to skip another traversal of each basic block when 443 // simplifying. 444 for (Instruction &I : BB) { 445 Value *Cond; 446 // For now, just handle assumes with a single compare as condition. 447 if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) && 448 isa<ICmpInst>(Cond)) { 449 if (GuaranteedToExecute) { 450 // The assume is guaranteed to execute when BB is entered, hence Cond 451 // holds on entry to BB. 452 WorkList.emplace_back(DT.getNode(&BB), cast<ICmpInst>(Cond), false); 453 } else { 454 // Otherwise the condition only holds in the successors. 455 for (BasicBlock *Succ : successors(&BB)) { 456 if (!canAddSuccessor(BB, Succ)) 457 continue; 458 WorkList.emplace_back(DT.getNode(Succ), cast<ICmpInst>(Cond), false); 459 } 460 } 461 } 462 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I); 463 } 464 465 auto *Br = dyn_cast<BranchInst>(BB.getTerminator()); 466 if (!Br || !Br->isConditional()) 467 return; 468 469 // If the condition is an OR of 2 compares and the false successor only has 470 // the current block as predecessor, queue both negated conditions for the 471 // false successor. 472 Value *Op0, *Op1; 473 if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) && 474 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 475 BasicBlock *FalseSuccessor = Br->getSuccessor(1); 476 if (canAddSuccessor(BB, FalseSuccessor)) { 477 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op0), 478 true); 479 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op1), 480 true); 481 } 482 return; 483 } 484 485 // If the condition is an AND of 2 compares and the true successor only has 486 // the current block as predecessor, queue both conditions for the true 487 // successor. 488 if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) && 489 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 490 BasicBlock *TrueSuccessor = Br->getSuccessor(0); 491 if (canAddSuccessor(BB, TrueSuccessor)) { 492 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op0), 493 false); 494 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op1), 495 false); 496 } 497 return; 498 } 499 500 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition()); 501 if (!CmpI) 502 return; 503 if (canAddSuccessor(BB, Br->getSuccessor(0))) 504 WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false); 505 if (canAddSuccessor(BB, Br->getSuccessor(1))) 506 WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true); 507 } 508 509 static void 510 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, 511 SmallVectorImpl<Instruction *> &ToRemove) { 512 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B, 513 ConstraintInfo &Info) { 514 DenseMap<Value *, unsigned> NewIndices; 515 auto R = getConstraint( 516 Pred, A, B, Info.getValue2Index(CmpInst::isSigned(Pred)), NewIndices); 517 if (R.size() < 2 || R.needsNewIndices(NewIndices) || !R.isValid(Info)) 518 return false; 519 520 auto &CSToUse = Info.getCS(CmpInst::isSigned(Pred)); 521 return CSToUse.isConditionImplied(R.Coefficients); 522 }; 523 524 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) { 525 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and 526 // can be simplified to a regular sub. 527 Value *A = II->getArgOperand(0); 528 Value *B = II->getArgOperand(1); 529 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) || 530 !DoesConditionHold(CmpInst::ICMP_SGE, B, 531 ConstantInt::get(A->getType(), 0), Info)) 532 return; 533 534 IRBuilder<> Builder(II->getParent(), II->getIterator()); 535 Value *Sub = nullptr; 536 for (User *U : make_early_inc_range(II->users())) { 537 if (match(U, m_ExtractValue<0>(m_Value()))) { 538 if (!Sub) 539 Sub = Builder.CreateSub(A, B); 540 U->replaceAllUsesWith(Sub); 541 } else if (match(U, m_ExtractValue<1>(m_Value()))) 542 U->replaceAllUsesWith(Builder.getFalse()); 543 else 544 continue; 545 546 if (U->use_empty()) { 547 auto *I = cast<Instruction>(U); 548 ToRemove.push_back(I); 549 I->setOperand(0, PoisonValue::get(II->getType())); 550 } 551 } 552 553 if (II->use_empty()) 554 II->eraseFromParent(); 555 } 556 } 557 558 static bool eliminateConstraints(Function &F, DominatorTree &DT) { 559 bool Changed = false; 560 DT.updateDFSNumbers(); 561 562 ConstraintInfo Info; 563 State S(DT); 564 565 // First, collect conditions implied by branches and blocks with their 566 // Dominator DFS in and out numbers. 567 for (BasicBlock &BB : F) { 568 if (!DT.getNode(&BB)) 569 continue; 570 S.addInfoFor(BB); 571 } 572 573 // Next, sort worklist by dominance, so that dominating blocks and conditions 574 // come before blocks and conditions dominated by them. If a block and a 575 // condition have the same numbers, the condition comes before the block, as 576 // it holds on entry to the block. 577 sort(S.WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) { 578 return std::tie(A.NumIn, A.IsBlock) < std::tie(B.NumIn, B.IsBlock); 579 }); 580 581 SmallVector<Instruction *> ToRemove; 582 583 // Finally, process ordered worklist and eliminate implied conditions. 584 SmallVector<StackEntry, 16> DFSInStack; 585 for (ConstraintOrBlock &CB : S.WorkList) { 586 // First, pop entries from the stack that are out-of-scope for CB. Remove 587 // the corresponding entry from the constraint system. 588 while (!DFSInStack.empty()) { 589 auto &E = DFSInStack.back(); 590 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut 591 << "\n"); 592 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n"); 593 assert(E.NumIn <= CB.NumIn); 594 if (CB.NumOut <= E.NumOut) 595 break; 596 LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot 597 << "\n"); 598 Info.popLastConstraint(E.IsSigned); 599 // Remove variables in the system that went out of scope. 600 auto &Mapping = Info.getValue2Index(E.IsSigned); 601 for (Value *V : E.ValuesToRelease) 602 Mapping.erase(V); 603 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size()); 604 DFSInStack.pop_back(); 605 } 606 607 LLVM_DEBUG({ 608 dbgs() << "Processing "; 609 if (CB.IsBlock) 610 dbgs() << *CB.BB; 611 else 612 dbgs() << *CB.Condition; 613 dbgs() << "\n"; 614 }); 615 616 // For a block, check if any CmpInsts become known based on the current set 617 // of constraints. 618 if (CB.IsBlock) { 619 for (Instruction &I : make_early_inc_range(*CB.BB)) { 620 if (auto *II = dyn_cast<WithOverflowInst>(&I)) { 621 tryToSimplifyOverflowMath(II, Info, ToRemove); 622 continue; 623 } 624 auto *Cmp = dyn_cast<ICmpInst>(&I); 625 if (!Cmp) 626 continue; 627 628 DenseMap<Value *, unsigned> NewIndices; 629 auto R = getConstraint(Cmp, Info, NewIndices); 630 if (R.IsEq || R.empty() || R.needsNewIndices(NewIndices) || 631 !R.isValid(Info)) 632 continue; 633 634 auto &CSToUse = Info.getCS(R.IsSigned); 635 if (CSToUse.isConditionImplied(R.Coefficients)) { 636 if (!DebugCounter::shouldExecute(EliminatedCounter)) 637 continue; 638 639 LLVM_DEBUG(dbgs() << "Condition " << *Cmp 640 << " implied by dominating constraints\n"); 641 LLVM_DEBUG({ 642 for (auto &E : reverse(DFSInStack)) 643 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 644 }); 645 Cmp->replaceUsesWithIf( 646 ConstantInt::getTrue(F.getParent()->getContext()), [](Use &U) { 647 // Conditions in an assume trivially simplify to true. Skip uses 648 // in assume calls to not destroy the available information. 649 auto *II = dyn_cast<IntrinsicInst>(U.getUser()); 650 return !II || II->getIntrinsicID() != Intrinsic::assume; 651 }); 652 NumCondsRemoved++; 653 Changed = true; 654 } 655 if (CSToUse.isConditionImplied( 656 ConstraintSystem::negate(R.Coefficients))) { 657 if (!DebugCounter::shouldExecute(EliminatedCounter)) 658 continue; 659 660 LLVM_DEBUG(dbgs() << "Condition !" << *Cmp 661 << " implied by dominating constraints\n"); 662 LLVM_DEBUG({ 663 for (auto &E : reverse(DFSInStack)) 664 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 665 }); 666 Cmp->replaceAllUsesWith( 667 ConstantInt::getFalse(F.getParent()->getContext())); 668 NumCondsRemoved++; 669 Changed = true; 670 } 671 } 672 continue; 673 } 674 675 // Set up a function to restore the predicate at the end of the scope if it 676 // has been negated. Negate the predicate in-place, if required. 677 auto *CI = dyn_cast<ICmpInst>(CB.Condition); 678 auto PredicateRestorer = make_scope_exit([CI, &CB]() { 679 if (CB.Not && CI) 680 CI->setPredicate(CI->getInversePredicate()); 681 }); 682 if (CB.Not) { 683 if (CI) { 684 CI->setPredicate(CI->getInversePredicate()); 685 } else { 686 LLVM_DEBUG(dbgs() << "Can only negate compares so far.\n"); 687 continue; 688 } 689 } 690 691 // Otherwise, add the condition to the system and stack, if we can transform 692 // it into a constraint. 693 DenseMap<Value *, unsigned> NewIndices; 694 auto R = getConstraint(CB.Condition, Info, NewIndices); 695 if (!R.isValid(Info)) 696 continue; 697 698 LLVM_DEBUG(dbgs() << "Adding " << *CB.Condition << " " << CB.Not << "\n"); 699 bool Added = false; 700 assert(CmpInst::isSigned(CB.Condition->getPredicate()) == R.IsSigned && 701 "condition and constraint signs must match"); 702 auto &CSToUse = Info.getCS(R.IsSigned); 703 if (R.Coefficients.empty()) 704 continue; 705 706 Added |= CSToUse.addVariableRowFill(R.Coefficients); 707 708 // If R has been added to the system, queue it for removal once it goes 709 // out-of-scope. 710 if (Added) { 711 SmallVector<Value *, 2> ValuesToRelease; 712 for (auto &KV : NewIndices) { 713 Info.getValue2Index(R.IsSigned).insert(KV); 714 ValuesToRelease.push_back(KV.first); 715 } 716 717 LLVM_DEBUG({ 718 dbgs() << " constraint: "; 719 dumpWithNames(R, Info.getValue2Index(R.IsSigned)); 720 }); 721 722 DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not, 723 R.IsSigned, ValuesToRelease); 724 725 if (R.IsEq) { 726 // Also add the inverted constraint for equality constraints. 727 for (auto &Coeff : R.Coefficients) 728 Coeff *= -1; 729 CSToUse.addVariableRowFill(R.Coefficients); 730 731 DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not, 732 R.IsSigned, SmallVector<Value *, 2>()); 733 } 734 } 735 } 736 737 #ifndef NDEBUG 738 unsigned SignedEntries = 739 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); 740 assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries && 741 "updates to CS and DFSInStack are out of sync"); 742 assert(Info.getCS(true).size() == SignedEntries && 743 "updates to CS and DFSInStack are out of sync"); 744 #endif 745 746 for (Instruction *I : ToRemove) 747 I->eraseFromParent(); 748 return Changed; 749 } 750 751 PreservedAnalyses ConstraintEliminationPass::run(Function &F, 752 FunctionAnalysisManager &AM) { 753 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 754 if (!eliminateConstraints(F, DT)) 755 return PreservedAnalyses::all(); 756 757 PreservedAnalyses PA; 758 PA.preserve<DominatorTreeAnalysis>(); 759 PA.preserveSet<CFGAnalyses>(); 760 return PA; 761 } 762 763 namespace { 764 765 class ConstraintElimination : public FunctionPass { 766 public: 767 static char ID; 768 769 ConstraintElimination() : FunctionPass(ID) { 770 initializeConstraintEliminationPass(*PassRegistry::getPassRegistry()); 771 } 772 773 bool runOnFunction(Function &F) override { 774 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 775 return eliminateConstraints(F, DT); 776 } 777 778 void getAnalysisUsage(AnalysisUsage &AU) const override { 779 AU.setPreservesCFG(); 780 AU.addRequired<DominatorTreeWrapperPass>(); 781 AU.addPreserved<GlobalsAAWrapperPass>(); 782 AU.addPreserved<DominatorTreeWrapperPass>(); 783 } 784 }; 785 786 } // end anonymous namespace 787 788 char ConstraintElimination::ID = 0; 789 790 INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination", 791 "Constraint Elimination", false, false) 792 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 793 INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) 794 INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination", 795 "Constraint Elimination", false, false) 796 797 FunctionPass *llvm::createConstraintEliminationPass() { 798 return new ConstraintElimination(); 799 } 800