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 // Skip trivial constraints without any variables. 286 if (ADec.size() == 1 && BDec.size() == 1) 287 return {}; 288 289 int64_t Offset1 = ADec[0].first; 290 int64_t Offset2 = BDec[0].first; 291 Offset1 *= -1; 292 293 // Create iterator ranges that skip the constant-factor. 294 auto VariablesA = llvm::drop_begin(ADec); 295 auto VariablesB = llvm::drop_begin(BDec); 296 297 // First try to look up \p V in Value2Index and NewIndices. Otherwise add a 298 // new entry to NewIndices. 299 auto GetOrAddIndex = [&Value2Index, &NewIndices](Value *V) -> unsigned { 300 auto V2I = Value2Index.find(V); 301 if (V2I != Value2Index.end()) 302 return V2I->second; 303 auto Insert = 304 NewIndices.insert({V, Value2Index.size() + NewIndices.size() + 1}); 305 return Insert.first->second; 306 }; 307 308 // Make sure all variables have entries in Value2Index or NewIndices. 309 for (const auto &KV : 310 concat<std::pair<int64_t, Value *>>(VariablesA, VariablesB)) 311 GetOrAddIndex(KV.second); 312 313 // Build result constraint, by first adding all coefficients from A and then 314 // subtracting all coefficients from B. 315 ConstraintTy Res( 316 SmallVector<int64_t, 8>(Value2Index.size() + NewIndices.size() + 1, 0), 317 IsSigned); 318 Res.IsEq = IsEq; 319 auto &R = Res.Coefficients; 320 for (const auto &KV : VariablesA) 321 R[GetOrAddIndex(KV.second)] += KV.first; 322 323 for (const auto &KV : VariablesB) 324 R[GetOrAddIndex(KV.second)] -= KV.first; 325 326 int64_t OffsetSum; 327 if (AddOverflow(Offset1, Offset2, OffsetSum)) 328 return {}; 329 if (Pred == (IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT)) 330 if (AddOverflow(OffsetSum, int64_t(-1), OffsetSum)) 331 return {}; 332 R[0] = OffsetSum; 333 Res.Preconditions = std::move(Preconditions); 334 return Res; 335 } 336 337 static ConstraintTy getConstraint(CmpInst *Cmp, ConstraintInfo &Info, 338 DenseMap<Value *, unsigned> &NewIndices) { 339 return getConstraint( 340 Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), 341 Info.getValue2Index(CmpInst::isSigned(Cmp->getPredicate())), NewIndices); 342 } 343 344 bool ConstraintTy::isValid(const ConstraintInfo &Info) const { 345 return Coefficients.size() > 0 && 346 all_of(Preconditions, [&Info](const PreconditionTy &C) { 347 DenseMap<Value *, unsigned> NewIndices; 348 auto R = getConstraint( 349 C.Pred, C.Op0, C.Op1, 350 Info.getValue2Index(CmpInst::isSigned(C.Pred)), NewIndices); 351 // TODO: properly check NewIndices. 352 return NewIndices.empty() && R.Preconditions.empty() && !R.IsEq && 353 R.size() >= 2 && 354 Info.getCS(CmpInst::isSigned(C.Pred)) 355 .isConditionImplied(R.Coefficients); 356 }); 357 } 358 359 namespace { 360 /// Represents either a condition that holds on entry to a block or a basic 361 /// block, with their respective Dominator DFS in and out numbers. 362 struct ConstraintOrBlock { 363 unsigned NumIn; 364 unsigned NumOut; 365 bool IsBlock; 366 bool Not; 367 union { 368 BasicBlock *BB; 369 CmpInst *Condition; 370 }; 371 372 ConstraintOrBlock(DomTreeNode *DTN) 373 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(true), 374 BB(DTN->getBlock()) {} 375 ConstraintOrBlock(DomTreeNode *DTN, CmpInst *Condition, bool Not) 376 : NumIn(DTN->getDFSNumIn()), NumOut(DTN->getDFSNumOut()), IsBlock(false), 377 Not(Not), Condition(Condition) {} 378 }; 379 380 struct StackEntry { 381 unsigned NumIn; 382 unsigned NumOut; 383 Instruction *Condition; 384 bool IsNot; 385 bool IsSigned = false; 386 /// Variables that can be removed from the system once the stack entry gets 387 /// removed. 388 SmallVector<Value *, 2> ValuesToRelease; 389 390 StackEntry(unsigned NumIn, unsigned NumOut, CmpInst *Condition, bool IsNot, 391 bool IsSigned, SmallVector<Value *, 2> ValuesToRelease) 392 : NumIn(NumIn), NumOut(NumOut), Condition(Condition), IsNot(IsNot), 393 IsSigned(IsSigned), ValuesToRelease(ValuesToRelease) {} 394 }; 395 396 /// Keep state required to build worklist. 397 struct State { 398 DominatorTree &DT; 399 SmallVector<ConstraintOrBlock, 64> WorkList; 400 401 State(DominatorTree &DT) : DT(DT) {} 402 403 /// Process block \p BB and add known facts to work-list. 404 void addInfoFor(BasicBlock &BB); 405 406 /// Returns true if we can add a known condition from BB to its successor 407 /// block Succ. Each predecessor of Succ can either be BB or be dominated 408 /// by Succ (e.g. the case when adding a condition from a pre-header to a 409 /// loop header). 410 bool canAddSuccessor(BasicBlock &BB, BasicBlock *Succ) const { 411 if (BB.getSingleSuccessor()) { 412 assert(BB.getSingleSuccessor() == Succ); 413 return DT.properlyDominates(&BB, Succ); 414 } 415 return any_of(successors(&BB), 416 [Succ](const BasicBlock *S) { return S != Succ; }) && 417 all_of(predecessors(Succ), [&BB, Succ, this](BasicBlock *Pred) { 418 return Pred == &BB || DT.dominates(Succ, Pred); 419 }); 420 } 421 }; 422 423 } // namespace 424 425 #ifndef NDEBUG 426 static void dumpWithNames(ConstraintTy &C, 427 DenseMap<Value *, unsigned> &Value2Index) { 428 SmallVector<std::string> Names(Value2Index.size(), ""); 429 for (auto &KV : Value2Index) { 430 Names[KV.second - 1] = std::string("%") + KV.first->getName().str(); 431 } 432 ConstraintSystem CS; 433 CS.addVariableRowFill(C.Coefficients); 434 CS.dump(Names); 435 } 436 #endif 437 438 void State::addInfoFor(BasicBlock &BB) { 439 WorkList.emplace_back(DT.getNode(&BB)); 440 441 // True as long as long as the current instruction is guaranteed to execute. 442 bool GuaranteedToExecute = true; 443 // Scan BB for assume calls. 444 // TODO: also use this scan to queue conditions to simplify, so we can 445 // interleave facts from assumes and conditions to simplify in a single 446 // basic block. And to skip another traversal of each basic block when 447 // simplifying. 448 for (Instruction &I : BB) { 449 Value *Cond; 450 // For now, just handle assumes with a single compare as condition. 451 if (match(&I, m_Intrinsic<Intrinsic::assume>(m_Value(Cond))) && 452 isa<ICmpInst>(Cond)) { 453 if (GuaranteedToExecute) { 454 // The assume is guaranteed to execute when BB is entered, hence Cond 455 // holds on entry to BB. 456 WorkList.emplace_back(DT.getNode(&BB), cast<ICmpInst>(Cond), false); 457 } else { 458 // Otherwise the condition only holds in the successors. 459 for (BasicBlock *Succ : successors(&BB)) { 460 if (!canAddSuccessor(BB, Succ)) 461 continue; 462 WorkList.emplace_back(DT.getNode(Succ), cast<ICmpInst>(Cond), false); 463 } 464 } 465 } 466 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I); 467 } 468 469 auto *Br = dyn_cast<BranchInst>(BB.getTerminator()); 470 if (!Br || !Br->isConditional()) 471 return; 472 473 // If the condition is an OR of 2 compares and the false successor only has 474 // the current block as predecessor, queue both negated conditions for the 475 // false successor. 476 Value *Op0, *Op1; 477 if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) && 478 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 479 BasicBlock *FalseSuccessor = Br->getSuccessor(1); 480 if (canAddSuccessor(BB, FalseSuccessor)) { 481 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op0), 482 true); 483 WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<ICmpInst>(Op1), 484 true); 485 } 486 return; 487 } 488 489 // If the condition is an AND of 2 compares and the true successor only has 490 // the current block as predecessor, queue both conditions for the true 491 // successor. 492 if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) && 493 isa<ICmpInst>(Op0) && isa<ICmpInst>(Op1)) { 494 BasicBlock *TrueSuccessor = Br->getSuccessor(0); 495 if (canAddSuccessor(BB, TrueSuccessor)) { 496 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op0), 497 false); 498 WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<ICmpInst>(Op1), 499 false); 500 } 501 return; 502 } 503 504 auto *CmpI = dyn_cast<ICmpInst>(Br->getCondition()); 505 if (!CmpI) 506 return; 507 if (canAddSuccessor(BB, Br->getSuccessor(0))) 508 WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false); 509 if (canAddSuccessor(BB, Br->getSuccessor(1))) 510 WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true); 511 } 512 513 static void 514 tryToSimplifyOverflowMath(IntrinsicInst *II, ConstraintInfo &Info, 515 SmallVectorImpl<Instruction *> &ToRemove) { 516 auto DoesConditionHold = [](CmpInst::Predicate Pred, Value *A, Value *B, 517 ConstraintInfo &Info) { 518 DenseMap<Value *, unsigned> NewIndices; 519 auto R = getConstraint( 520 Pred, A, B, Info.getValue2Index(CmpInst::isSigned(Pred)), NewIndices); 521 if (R.size() < 2 || R.needsNewIndices(NewIndices) || !R.isValid(Info)) 522 return false; 523 524 auto &CSToUse = Info.getCS(CmpInst::isSigned(Pred)); 525 return CSToUse.isConditionImplied(R.Coefficients); 526 }; 527 528 if (II->getIntrinsicID() == Intrinsic::ssub_with_overflow) { 529 // If A s>= B && B s>= 0, ssub.with.overflow(a, b) should not overflow and 530 // can be simplified to a regular sub. 531 Value *A = II->getArgOperand(0); 532 Value *B = II->getArgOperand(1); 533 if (!DoesConditionHold(CmpInst::ICMP_SGE, A, B, Info) || 534 !DoesConditionHold(CmpInst::ICMP_SGE, B, 535 ConstantInt::get(A->getType(), 0), Info)) 536 return; 537 538 IRBuilder<> Builder(II->getParent(), II->getIterator()); 539 Value *Sub = nullptr; 540 for (User *U : make_early_inc_range(II->users())) { 541 if (match(U, m_ExtractValue<0>(m_Value()))) { 542 if (!Sub) 543 Sub = Builder.CreateSub(A, B); 544 U->replaceAllUsesWith(Sub); 545 } else if (match(U, m_ExtractValue<1>(m_Value()))) 546 U->replaceAllUsesWith(Builder.getFalse()); 547 else 548 continue; 549 550 if (U->use_empty()) { 551 auto *I = cast<Instruction>(U); 552 ToRemove.push_back(I); 553 I->setOperand(0, PoisonValue::get(II->getType())); 554 } 555 } 556 557 if (II->use_empty()) 558 II->eraseFromParent(); 559 } 560 } 561 562 static bool eliminateConstraints(Function &F, DominatorTree &DT) { 563 bool Changed = false; 564 DT.updateDFSNumbers(); 565 566 ConstraintInfo Info; 567 State S(DT); 568 569 // First, collect conditions implied by branches and blocks with their 570 // Dominator DFS in and out numbers. 571 for (BasicBlock &BB : F) { 572 if (!DT.getNode(&BB)) 573 continue; 574 S.addInfoFor(BB); 575 } 576 577 // Next, sort worklist by dominance, so that dominating blocks and conditions 578 // come before blocks and conditions dominated by them. If a block and a 579 // condition have the same numbers, the condition comes before the block, as 580 // it holds on entry to the block. 581 sort(S.WorkList, [](const ConstraintOrBlock &A, const ConstraintOrBlock &B) { 582 return std::tie(A.NumIn, A.IsBlock) < std::tie(B.NumIn, B.IsBlock); 583 }); 584 585 SmallVector<Instruction *> ToRemove; 586 587 // Finally, process ordered worklist and eliminate implied conditions. 588 SmallVector<StackEntry, 16> DFSInStack; 589 for (ConstraintOrBlock &CB : S.WorkList) { 590 // First, pop entries from the stack that are out-of-scope for CB. Remove 591 // the corresponding entry from the constraint system. 592 while (!DFSInStack.empty()) { 593 auto &E = DFSInStack.back(); 594 LLVM_DEBUG(dbgs() << "Top of stack : " << E.NumIn << " " << E.NumOut 595 << "\n"); 596 LLVM_DEBUG(dbgs() << "CB: " << CB.NumIn << " " << CB.NumOut << "\n"); 597 assert(E.NumIn <= CB.NumIn); 598 if (CB.NumOut <= E.NumOut) 599 break; 600 LLVM_DEBUG(dbgs() << "Removing " << *E.Condition << " " << E.IsNot 601 << "\n"); 602 Info.popLastConstraint(E.IsSigned); 603 // Remove variables in the system that went out of scope. 604 auto &Mapping = Info.getValue2Index(E.IsSigned); 605 for (Value *V : E.ValuesToRelease) 606 Mapping.erase(V); 607 Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size()); 608 DFSInStack.pop_back(); 609 } 610 611 LLVM_DEBUG({ 612 dbgs() << "Processing "; 613 if (CB.IsBlock) 614 dbgs() << *CB.BB; 615 else 616 dbgs() << *CB.Condition; 617 dbgs() << "\n"; 618 }); 619 620 // For a block, check if any CmpInsts become known based on the current set 621 // of constraints. 622 if (CB.IsBlock) { 623 for (Instruction &I : make_early_inc_range(*CB.BB)) { 624 if (auto *II = dyn_cast<WithOverflowInst>(&I)) { 625 tryToSimplifyOverflowMath(II, Info, ToRemove); 626 continue; 627 } 628 auto *Cmp = dyn_cast<ICmpInst>(&I); 629 if (!Cmp) 630 continue; 631 632 DenseMap<Value *, unsigned> NewIndices; 633 auto R = getConstraint(Cmp, Info, NewIndices); 634 if (R.IsEq || R.size() < 2 || R.needsNewIndices(NewIndices) || 635 !R.isValid(Info)) 636 continue; 637 638 auto &CSToUse = Info.getCS(R.IsSigned); 639 if (CSToUse.isConditionImplied(R.Coefficients)) { 640 if (!DebugCounter::shouldExecute(EliminatedCounter)) 641 continue; 642 643 LLVM_DEBUG(dbgs() << "Condition " << *Cmp 644 << " implied by dominating constraints\n"); 645 LLVM_DEBUG({ 646 for (auto &E : reverse(DFSInStack)) 647 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 648 }); 649 Cmp->replaceUsesWithIf( 650 ConstantInt::getTrue(F.getParent()->getContext()), [](Use &U) { 651 // Conditions in an assume trivially simplify to true. Skip uses 652 // in assume calls to not destroy the available information. 653 auto *II = dyn_cast<IntrinsicInst>(U.getUser()); 654 return !II || II->getIntrinsicID() != Intrinsic::assume; 655 }); 656 NumCondsRemoved++; 657 Changed = true; 658 } 659 if (CSToUse.isConditionImplied( 660 ConstraintSystem::negate(R.Coefficients))) { 661 if (!DebugCounter::shouldExecute(EliminatedCounter)) 662 continue; 663 664 LLVM_DEBUG(dbgs() << "Condition !" << *Cmp 665 << " implied by dominating constraints\n"); 666 LLVM_DEBUG({ 667 for (auto &E : reverse(DFSInStack)) 668 dbgs() << " C " << *E.Condition << " " << E.IsNot << "\n"; 669 }); 670 Cmp->replaceAllUsesWith( 671 ConstantInt::getFalse(F.getParent()->getContext())); 672 NumCondsRemoved++; 673 Changed = true; 674 } 675 } 676 continue; 677 } 678 679 // Set up a function to restore the predicate at the end of the scope if it 680 // has been negated. Negate the predicate in-place, if required. 681 auto *CI = dyn_cast<ICmpInst>(CB.Condition); 682 auto PredicateRestorer = make_scope_exit([CI, &CB]() { 683 if (CB.Not && CI) 684 CI->setPredicate(CI->getInversePredicate()); 685 }); 686 if (CB.Not) { 687 if (CI) { 688 CI->setPredicate(CI->getInversePredicate()); 689 } else { 690 LLVM_DEBUG(dbgs() << "Can only negate compares so far.\n"); 691 continue; 692 } 693 } 694 695 // Otherwise, add the condition to the system and stack, if we can transform 696 // it into a constraint. 697 DenseMap<Value *, unsigned> NewIndices; 698 auto R = getConstraint(CB.Condition, Info, NewIndices); 699 if (!R.isValid(Info)) 700 continue; 701 702 LLVM_DEBUG(dbgs() << "Adding " << *CB.Condition << " " << CB.Not << "\n"); 703 bool Added = false; 704 assert(CmpInst::isSigned(CB.Condition->getPredicate()) == R.IsSigned && 705 "condition and constraint signs must match"); 706 auto &CSToUse = Info.getCS(R.IsSigned); 707 if (R.Coefficients.empty()) 708 continue; 709 710 Added |= CSToUse.addVariableRowFill(R.Coefficients); 711 712 // If R has been added to the system, queue it for removal once it goes 713 // out-of-scope. 714 if (Added) { 715 SmallVector<Value *, 2> ValuesToRelease; 716 for (auto &KV : NewIndices) { 717 Info.getValue2Index(R.IsSigned).insert(KV); 718 ValuesToRelease.push_back(KV.first); 719 } 720 721 LLVM_DEBUG({ 722 dbgs() << " constraint: "; 723 dumpWithNames(R, Info.getValue2Index(R.IsSigned)); 724 }); 725 726 DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not, 727 R.IsSigned, ValuesToRelease); 728 729 if (R.IsEq) { 730 // Also add the inverted constraint for equality constraints. 731 for (auto &Coeff : R.Coefficients) 732 Coeff *= -1; 733 CSToUse.addVariableRowFill(R.Coefficients); 734 735 DFSInStack.emplace_back(CB.NumIn, CB.NumOut, CB.Condition, CB.Not, 736 R.IsSigned, SmallVector<Value *, 2>()); 737 } 738 } 739 } 740 741 #ifndef NDEBUG 742 unsigned SignedEntries = 743 count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; }); 744 assert(Info.getCS(false).size() == DFSInStack.size() - SignedEntries && 745 "updates to CS and DFSInStack are out of sync"); 746 assert(Info.getCS(true).size() == SignedEntries && 747 "updates to CS and DFSInStack are out of sync"); 748 #endif 749 750 for (Instruction *I : ToRemove) 751 I->eraseFromParent(); 752 return Changed; 753 } 754 755 PreservedAnalyses ConstraintEliminationPass::run(Function &F, 756 FunctionAnalysisManager &AM) { 757 auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 758 if (!eliminateConstraints(F, DT)) 759 return PreservedAnalyses::all(); 760 761 PreservedAnalyses PA; 762 PA.preserve<DominatorTreeAnalysis>(); 763 PA.preserveSet<CFGAnalyses>(); 764 return PA; 765 } 766 767 namespace { 768 769 class ConstraintElimination : public FunctionPass { 770 public: 771 static char ID; 772 773 ConstraintElimination() : FunctionPass(ID) { 774 initializeConstraintEliminationPass(*PassRegistry::getPassRegistry()); 775 } 776 777 bool runOnFunction(Function &F) override { 778 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 779 return eliminateConstraints(F, DT); 780 } 781 782 void getAnalysisUsage(AnalysisUsage &AU) const override { 783 AU.setPreservesCFG(); 784 AU.addRequired<DominatorTreeWrapperPass>(); 785 AU.addPreserved<GlobalsAAWrapperPass>(); 786 AU.addPreserved<DominatorTreeWrapperPass>(); 787 } 788 }; 789 790 } // end anonymous namespace 791 792 char ConstraintElimination::ID = 0; 793 794 INITIALIZE_PASS_BEGIN(ConstraintElimination, "constraint-elimination", 795 "Constraint Elimination", false, false) 796 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 797 INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) 798 INITIALIZE_PASS_END(ConstraintElimination, "constraint-elimination", 799 "Constraint Elimination", false, false) 800 801 FunctionPass *llvm::createConstraintEliminationPass() { 802 return new ConstraintElimination(); 803 } 804