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