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