LLVM 23.0.0git
NaryReassociate.cpp
Go to the documentation of this file.
1//===- NaryReassociate.cpp - Reassociate n-ary expressions ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass reassociates n-ary add expressions and eliminates the redundancy
10// exposed by the reassociation.
11//
12// A motivating example:
13//
14// void foo(int a, int b) {
15// bar(a + b);
16// bar((a + 2) + b);
17// }
18//
19// An ideal compiler should reassociate (a + 2) + b to (a + b) + 2 and simplify
20// the above code to
21//
22// int t = a + b;
23// bar(t);
24// bar(t + 2);
25//
26// However, the Reassociate pass is unable to do that because it processes each
27// instruction individually and believes (a + 2) + b is the best form according
28// to its rank system.
29//
30// To address this limitation, NaryReassociate reassociates an expression in a
31// form that reuses existing instructions. As a result, NaryReassociate can
32// reassociate (a + 2) + b in the example to (a + b) + 2 because it detects that
33// (a + b) is computed before.
34//
35// NaryReassociate works as follows. For every instruction in the form of (a +
36// b) + c, it checks whether a + c or b + c is already computed by a dominating
37// instruction. If so, it then reassociates (a + b) + c into (a + c) + b or (b +
38// c) + a and removes the redundancy accordingly. To efficiently look up whether
39// an expression is computed before, we store each instruction seen and its SCEV
40// into an SCEV-to-instruction map.
41//
42// Although the algorithm pattern-matches only ternary additions, it
43// automatically handles many >3-ary expressions by walking through the function
44// in the depth-first order. For example, given
45//
46// (a + c) + d
47// ((a + b) + c) + d
48//
49// NaryReassociate first rewrites (a + b) + c to (a + c) + b, and then rewrites
50// ((a + c) + b) + d into ((a + c) + d) + b.
51//
52// Finally, the above dominator-based algorithm may need to be run multiple
53// iterations before emitting optimal code. One source of this need is that we
54// only split an operand when it is used only once. The above algorithm can
55// eliminate an instruction and decrease the usage count of its operands. As a
56// result, an instruction that previously had multiple uses may become a
57// single-use instruction and thus eligible for split consideration. For
58// example,
59//
60// ac = a + c
61// ab = a + b
62// abc = ab + c
63// ab2 = ab + b
64// ab2c = ab2 + c
65//
66// In the first iteration, we cannot reassociate abc to ac+b because ab is used
67// twice. However, we can reassociate ab2c to abc+b in the first iteration. As a
68// result, ab2 becomes dead and ab will be used only once in the second
69// iteration.
70//
71// Limitations and TODO items:
72//
73// 1) We only considers n-ary adds and muls for now. This should be extended
74// and generalized.
75//
76//===----------------------------------------------------------------------===//
77
87#include "llvm/IR/BasicBlock.h"
88#include "llvm/IR/Constants.h"
89#include "llvm/IR/DataLayout.h"
91#include "llvm/IR/Dominators.h"
92#include "llvm/IR/Function.h"
94#include "llvm/IR/IRBuilder.h"
95#include "llvm/IR/InstrTypes.h"
96#include "llvm/IR/Instruction.h"
98#include "llvm/IR/Module.h"
99#include "llvm/IR/Operator.h"
100#include "llvm/IR/PatternMatch.h"
101#include "llvm/IR/Type.h"
102#include "llvm/IR/Value.h"
103#include "llvm/IR/ValueHandle.h"
105#include "llvm/Pass.h"
106#include "llvm/Support/Casting.h"
111#include <cassert>
112#include <cstdint>
113
114using namespace llvm;
115using namespace PatternMatch;
116
117#define DEBUG_TYPE "nary-reassociate"
118
119namespace {
120
121class NaryReassociateLegacyPass : public FunctionPass {
122public:
123 static char ID;
124
125 NaryReassociateLegacyPass() : FunctionPass(ID) {
127 }
128
129 bool doInitialization(Module &M) override {
130 return false;
131 }
132
133 bool runOnFunction(Function &F) override;
134
135 void getAnalysisUsage(AnalysisUsage &AU) const override {
144 AU.setPreservesCFG();
145 }
146
147private:
149};
150
151} // end anonymous namespace
152
153char NaryReassociateLegacyPass::ID = 0;
154
155INITIALIZE_PASS_BEGIN(NaryReassociateLegacyPass, "nary-reassociate",
156 "Nary reassociation", false, false)
162INITIALIZE_PASS_END(NaryReassociateLegacyPass, "nary-reassociate",
163 "Nary reassociation", false, false)
164
166 return new NaryReassociateLegacyPass();
167}
168
169bool NaryReassociateLegacyPass::runOnFunction(Function &F) {
170 if (skipFunction(F))
171 return false;
172
173 auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
174 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
175 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
176 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
177 auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
178
179 return Impl.runImpl(F, AC, DT, SE, TLI, TTI);
180}
181
184 auto *AC = &AM.getResult<AssumptionAnalysis>(F);
185 auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
186 auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
187 auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
188 auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
189
190 if (!runImpl(F, AC, DT, SE, TLI, TTI))
191 return PreservedAnalyses::all();
192
196 return PA;
197}
198
201 TargetLibraryInfo *TLI_,
202 TargetTransformInfo *TTI_) {
203 AC = AC_;
204 DT = DT_;
205 SE = SE_;
206 TLI = TLI_;
207 TTI = TTI_;
208 DL = &F.getDataLayout();
209
210 bool Changed = false, ChangedInThisIteration;
211 do {
212 ChangedInThisIteration = doOneIteration(F);
213 Changed |= ChangedInThisIteration;
214 } while (ChangedInThisIteration);
215 return Changed;
216}
217
218bool NaryReassociatePass::doOneIteration(Function &F) {
219 bool Changed = false;
220 SeenExprs.clear();
221 // Process the basic blocks in a depth first traversal of the dominator
222 // tree. This order ensures that all bases of a candidate are in Candidates
223 // when we process it.
225 for (const auto Node : depth_first(DT)) {
226 BasicBlock *BB = Node->getBlock();
227 for (Instruction &OrigI : *BB) {
228 SCEVUse OrigSCEV = nullptr;
229 if (Instruction *NewI = tryReassociate(&OrigI, OrigSCEV)) {
230 Changed = true;
231 OrigI.replaceAllUsesWith(NewI);
232
233 // Add 'OrigI' to the list of dead instructions.
234 DeadInsts.push_back(WeakTrackingVH(&OrigI));
235 // Add the rewritten instruction to SeenExprs; the original
236 // instruction is deleted.
237 SCEVUse NewSCEV = SE->getSCEV(NewI);
238 SeenExprs[NewSCEV].push_back(WeakTrackingVH(NewI));
239
240 // Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
241 // is equivalent to I. However, ScalarEvolution::getSCEV may
242 // weaken nsw causing NewSCEV not to equal OldSCEV. For example,
243 // suppose we reassociate
244 // I = &a[sext(i +nsw j)] // assuming sizeof(a[0]) = 4
245 // to
246 // NewI = &a[sext(i)] + sext(j).
247 //
248 // ScalarEvolution computes
249 // getSCEV(I) = a + 4 * sext(i + j)
250 // getSCEV(newI) = a + 4 * sext(i) + 4 * sext(j)
251 // which are different SCEVs.
252 //
253 // To alleviate this issue of ScalarEvolution not always capturing
254 // equivalence, we add I to SeenExprs[OldSCEV] as well so that we can
255 // map both SCEV before and after tryReassociate(I) to I.
256 //
257 // This improvement is exercised in @reassociate_gep_nsw in
258 // nary-gep.ll.
259 if (NewSCEV != OrigSCEV)
260 SeenExprs[OrigSCEV].push_back(WeakTrackingVH(NewI));
261 } else if (OrigSCEV)
262 SeenExprs[OrigSCEV].push_back(WeakTrackingVH(&OrigI));
263 }
264 }
265 // Delete all dead instructions from 'DeadInsts'.
266 // Please note ScalarEvolution is updated along the way.
268 DeadInsts, TLI, nullptr, [this](Value *V) { SE->forgetValue(V); });
269
270 return Changed;
271}
272
273Instruction *NaryReassociatePass::tryReassociate(Instruction *I,
274 SCEVUse &OrigSCEV) {
275
276 if (!SE->isSCEVable(I->getType()))
277 return nullptr;
278
279 switch (I->getOpcode()) {
280 case Instruction::Add:
281 case Instruction::Mul:
282 OrigSCEV = SE->getSCEV(I);
283 return tryReassociateBinaryOp(cast<BinaryOperator>(I));
284 case Instruction::GetElementPtr:
285 OrigSCEV = SE->getSCEV(I);
286 return tryReassociateGEP(cast<GetElementPtrInst>(I));
287 default:
288 break;
289 }
290
291 // Try to match signed/unsigned Min/Max.
292 if (match(I, m_MaxOrMin(m_Value(), m_Value()))) {
293 OrigSCEV = SE->getSCEV(I);
295 tryReassociateMinOrMax(cast<IntrinsicInst>(I)));
296 }
297
298 return nullptr;
299}
300
302 const TargetTransformInfo *TTI) {
303 SmallVector<const Value *, 4> Indices(GEP->indices());
304 return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
306}
307
308Instruction *NaryReassociatePass::tryReassociateGEP(GetElementPtrInst *GEP) {
309 // Not worth reassociating GEP if it is foldable.
310 if (isGEPFoldable(GEP, TTI))
311 return nullptr;
312
314 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) {
315 if (GTI.isSequential()) {
316 if (auto *NewGEP = tryReassociateGEPAtIndex(GEP, I - 1,
317 GTI.getIndexedType())) {
318 return NewGEP;
319 }
320 }
321 }
322 return nullptr;
323}
324
325bool NaryReassociatePass::requiresSignExtension(Value *Index,
326 GetElementPtrInst *GEP) {
327 unsigned IndexSizeInBits =
328 DL->getIndexSizeInBits(GEP->getType()->getPointerAddressSpace());
329 return cast<IntegerType>(Index->getType())->getBitWidth() < IndexSizeInBits;
330}
331
332GetElementPtrInst *
333NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
334 unsigned I, Type *IndexedType) {
335 SimplifyQuery SQ(*DL, DT, AC, GEP);
336 Value *IndexToSplit = GEP->getOperand(I + 1);
337 if (SExtInst *SExt = dyn_cast<SExtInst>(IndexToSplit)) {
338 IndexToSplit = SExt->getOperand(0);
339 } else if (ZExtInst *ZExt = dyn_cast<ZExtInst>(IndexToSplit)) {
340 // zext can be treated as sext if the source is non-negative.
341 if (isKnownNonNegative(ZExt->getOperand(0), SQ))
342 IndexToSplit = ZExt->getOperand(0);
343 }
344
345 if (AddOperator *AO = dyn_cast<AddOperator>(IndexToSplit)) {
346 // If the I-th index needs sext and the underlying add is not equipped with
347 // nsw, we cannot split the add because
348 // sext(LHS + RHS) != sext(LHS) + sext(RHS).
349 if (requiresSignExtension(IndexToSplit, GEP) &&
350 computeOverflowForSignedAdd(AO, SQ) != OverflowResult::NeverOverflows)
351 return nullptr;
352
353 Value *LHS = AO->getOperand(0), *RHS = AO->getOperand(1);
354 // IndexToSplit = LHS + RHS.
355 if (auto *NewGEP = tryReassociateGEPAtIndex(GEP, I, LHS, RHS, IndexedType))
356 return NewGEP;
357 // Symmetrically, try IndexToSplit = RHS + LHS.
358 if (LHS != RHS) {
359 if (auto *NewGEP =
360 tryReassociateGEPAtIndex(GEP, I, RHS, LHS, IndexedType))
361 return NewGEP;
362 }
363 }
364 return nullptr;
365}
366
367GetElementPtrInst *
368NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
369 unsigned I, Value *LHS,
370 Value *RHS, Type *IndexedType) {
371 // Look for GEP's closest dominator that has the same SCEV as GEP except that
372 // the I-th index is replaced with LHS.
373 SmallVector<SCEVUse, 4> IndexExprs;
374 for (Use &Index : GEP->indices())
375 IndexExprs.push_back(SE->getSCEV(Index));
376 // Replace the I-th index with LHS.
377 IndexExprs[I] = SE->getSCEV(LHS);
378 Type *GEPArgType = SE->getEffectiveSCEVType(GEP->getOperand(I)->getType());
379 Type *LHSType = SE->getEffectiveSCEVType(LHS->getType());
380 size_t LHSSize = DL->getTypeSizeInBits(LHSType).getFixedValue();
381 size_t GEPArgSize = DL->getTypeSizeInBits(GEPArgType).getFixedValue();
382 if (isKnownNonNegative(LHS, SimplifyQuery(*DL, DT, AC, GEP)) &&
383 LHSSize < GEPArgSize) {
384 // Zero-extend LHS if it is non-negative. InstCombine canonicalizes sext to
385 // zext if the source operand is proved non-negative. We should do that
386 // consistently so that CandidateExpr more likely appears before. See
387 // @reassociate_gep_assume for an example of this canonicalization.
388 IndexExprs[I] = SE->getZeroExtendExpr(IndexExprs[I], GEPArgType);
389 }
390 SCEVUse CandidateExpr = SE->getGEPExpr(cast<GEPOperator>(GEP), IndexExprs);
391
392 Value *Candidate = findClosestMatchingDominator(CandidateExpr, GEP);
393 if (Candidate == nullptr)
394 return nullptr;
395
396 IRBuilder<> Builder(GEP);
397 // Candidate should have the same pointer type as GEP.
398 assert(Candidate->getType() == GEP->getType());
399
400 // NewGEP = (char *)Candidate + RHS * sizeof(IndexedType)
401 uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType);
402 Type *ElementType = GEP->getResultElementType();
403 uint64_t ElementSize = DL->getTypeAllocSize(ElementType);
404 // Another less rare case: because I is not necessarily the last index of the
405 // GEP, the size of the type at the I-th index (IndexedSize) is not
406 // necessarily divisible by ElementSize. For example,
407 //
408 // #pragma pack(1)
409 // struct S {
410 // int a[3];
411 // int64 b[8];
412 // };
413 // #pragma pack()
414 //
415 // sizeof(S) = 100 is indivisible by sizeof(int64) = 8.
416 //
417 // TODO: bail out on this case for now. We could emit uglygep.
418 if (ElementSize == 0 || IndexedSize % ElementSize != 0)
419 return nullptr;
420
421 // NewGEP = &Candidate[RHS * (sizeof(IndexedType) / sizeof(Candidate[0])));
422 Type *PtrIdxTy = DL->getIndexType(GEP->getType());
423 if (RHS->getType() != PtrIdxTy)
424 RHS = Builder.CreateSExtOrTrunc(RHS, PtrIdxTy);
425 if (IndexedSize != ElementSize) {
426 RHS = Builder.CreateMul(
427 RHS, ConstantInt::get(PtrIdxTy, IndexedSize / ElementSize));
428 }
429 GetElementPtrInst *NewGEP = cast<GetElementPtrInst>(
430 Builder.CreateGEP(GEP->getResultElementType(), Candidate, RHS));
431 NewGEP->setIsInBounds(GEP->isInBounds());
432 NewGEP->takeName(GEP);
433 return NewGEP;
434}
435
436Instruction *NaryReassociatePass::tryReassociateBinaryOp(BinaryOperator *I) {
437 Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
438 // There is no need to reassociate 0.
439 if (SE->getSCEV(I)->isZero())
440 return nullptr;
441 if (auto *NewI = tryReassociateBinaryOp(LHS, RHS, I))
442 return NewI;
443 if (auto *NewI = tryReassociateBinaryOp(RHS, LHS, I))
444 return NewI;
445 return nullptr;
446}
447
448Instruction *NaryReassociatePass::tryReassociateBinaryOp(Value *LHS, Value *RHS,
449 BinaryOperator *I) {
450 Value *A = nullptr, *B = nullptr;
451 // To be conservative, we reassociate I only when it is the only user of (A op
452 // B).
453 if (LHS->hasOneUse() && matchTernaryOp(I, LHS, A, B)) {
454 // I = (A op B) op RHS
455 // = (A op RHS) op B or (B op RHS) op A
456 SCEVUse AExpr = SE->getSCEV(A), BExpr = SE->getSCEV(B);
457 SCEVUse RHSExpr = SE->getSCEV(RHS);
458 if (BExpr != RHSExpr) {
459 if (auto *NewI =
460 tryReassociatedBinaryOp(getBinarySCEV(I, AExpr, RHSExpr), B, I))
461 return NewI;
462 }
463 if (AExpr != RHSExpr) {
464 if (auto *NewI =
465 tryReassociatedBinaryOp(getBinarySCEV(I, BExpr, RHSExpr), A, I))
466 return NewI;
467 }
468 }
469 return nullptr;
470}
471
472Instruction *NaryReassociatePass::tryReassociatedBinaryOp(SCEVUse LHSExpr,
473 Value *RHS,
474 BinaryOperator *I) {
475 // Look for the closest dominator LHS of I that computes LHSExpr, and replace
476 // I with LHS op RHS.
477 auto *LHS = findClosestMatchingDominator(LHSExpr, I);
478 if (LHS == nullptr)
479 return nullptr;
480
481 Instruction *NewI = nullptr;
482 switch (I->getOpcode()) {
483 case Instruction::Add:
484 NewI = BinaryOperator::CreateAdd(LHS, RHS, "", I->getIterator());
485 break;
486 case Instruction::Mul:
487 NewI = BinaryOperator::CreateMul(LHS, RHS, "", I->getIterator());
488 break;
489 default:
490 llvm_unreachable("Unexpected instruction.");
491 }
492 NewI->setDebugLoc(I->getDebugLoc());
493 NewI->takeName(I);
494 return NewI;
495}
496
497bool NaryReassociatePass::matchTernaryOp(BinaryOperator *I, Value *V,
498 Value *&Op1, Value *&Op2) {
499 switch (I->getOpcode()) {
500 case Instruction::Add:
501 return match(V, m_Add(m_Value(Op1), m_Value(Op2)));
502 case Instruction::Mul:
503 return match(V, m_Mul(m_Value(Op1), m_Value(Op2)));
504 default:
505 llvm_unreachable("Unexpected instruction.");
506 }
507 return false;
508}
509
510SCEVUse NaryReassociatePass::getBinarySCEV(BinaryOperator *I, SCEVUse LHS,
511 SCEVUse RHS) {
512 switch (I->getOpcode()) {
513 case Instruction::Add:
514 return SE->getAddExpr(LHS, RHS);
515 case Instruction::Mul:
516 return SE->getMulExpr(LHS, RHS);
517 default:
518 llvm_unreachable("Unexpected instruction.");
519 }
520 return nullptr;
521}
522
524NaryReassociatePass::findClosestMatchingDominator(SCEVUse CandidateExpr,
525 Instruction *Dominatee) {
526 auto Pos = SeenExprs.find(CandidateExpr);
527 if (Pos == SeenExprs.end())
528 return nullptr;
529
530 auto &Candidates = Pos->second;
531 // Because we process the basic blocks in pre-order of the dominator tree, a
532 // candidate that doesn't dominate the current instruction won't dominate any
533 // future instruction either. Therefore, we pop it out of the stack. This
534 // optimization makes the algorithm O(n).
535 while (!Candidates.empty()) {
536 // Candidates stores WeakTrackingVHs, so a candidate can be nullptr if it's
537 // removed during rewriting.
538 if (Value *Candidate = Candidates.pop_back_val()) {
539 Instruction *CandidateInstruction = cast<Instruction>(Candidate);
540 if (!DT->dominates(CandidateInstruction, Dominatee))
541 continue;
542
543 // Make sure that the instruction is safe to reuse without introducing
544 // poison.
545 SmallVector<Instruction *> DropPoisonGeneratingInsts;
546 if (!SE->canReuseInstruction(CandidateExpr, CandidateInstruction,
547 DropPoisonGeneratingInsts))
548 continue;
549
550 for (Instruction *I : DropPoisonGeneratingInsts)
551 I->dropPoisonGeneratingAnnotations();
552
553 return CandidateInstruction;
554 }
555 }
556 return nullptr;
557}
558
560 switch (IntrinID) {
561 case Intrinsic::smax:
562 return scSMaxExpr;
563 case Intrinsic::umax:
564 return scUMaxExpr;
565 case Intrinsic::smin:
566 return scSMinExpr;
567 case Intrinsic::umin:
568 return scUMinExpr;
569 default:
570 llvm_unreachable("Can't convert MinMax pattern to SCEV type");
571 return scUnknown;
572 }
573}
574
575Value *NaryReassociatePass::tryReassociateMinOrMax(IntrinsicInst *I) {
576 Value *LHS = I->getArgOperand(0);
577 Value *RHS = I->getArgOperand(1);
578 if (auto *RHSI = dyn_cast<IntrinsicInst>(RHS);
579 RHSI && RHSI->getIntrinsicID() == I->getIntrinsicID())
580 std::swap(LHS, RHS);
581 auto *LHSI = dyn_cast<IntrinsicInst>(LHS);
582 if (!LHSI || LHSI->getIntrinsicID() != I->getIntrinsicID())
583 return nullptr;
584
585 Value *A = LHSI->getArgOperand(0), *B = LHSI->getArgOperand(1);
586
587 if (LHS->hasNUsesOrMore(3) ||
588 // The optimization is profitable only if LHS can be removed in the end.
589 // In other words LHS should be used (directly or indirectly) by I only.
590 llvm::any_of(LHS->users(), [&](auto *U) {
591 return U != I && !(U->hasOneUser() && *U->users().begin() == I);
592 }))
593 return nullptr;
594
595 auto tryCombination = [&](Value *A, SCEVUse AExpr, Value *B, SCEVUse BExpr,
596 Value *C, SCEVUse CExpr) -> Value * {
597 SmallVector<SCEVUse, 2> Ops1{BExpr, AExpr};
598 SCEVTypes SCEVType = convertToSCEVType(I->getIntrinsicID());
599 SCEVUse R1Expr = SE->getMinMaxExpr(SCEVType, Ops1);
600
601 Instruction *R1MinMax = findClosestMatchingDominator(R1Expr, I);
602
603 if (!R1MinMax)
604 return nullptr;
605
606 LLVM_DEBUG(dbgs() << "NARY: Found common sub-expr: " << *R1MinMax << "\n");
607
608 SmallVector<SCEVUse, 2> Ops2{SE->getUnknown(C), SE->getUnknown(R1MinMax)};
609 SCEVUse R2Expr = SE->getMinMaxExpr(SCEVType, Ops2);
610
611 SCEVExpander Expander(*SE, "nary-reassociate");
612 Value *NewMinMax = Expander.expandCodeFor(R2Expr, I->getType(), I);
613 NewMinMax->setName(Twine(I->getName()).concat(".nary"));
614
615 LLVM_DEBUG(dbgs() << "NARY: Deleting: " << *I << "\n"
616 << "NARY: Inserting: " << *NewMinMax << "\n");
617 return NewMinMax;
618 };
619
620 SCEVUse AExpr = SE->getSCEV(A);
621 SCEVUse BExpr = SE->getSCEV(B);
622 SCEVUse RHSExpr = SE->getSCEV(RHS);
623
624 if (BExpr != RHSExpr) {
625 // Try (A op RHS) op B
626 if (auto *NewMinMax = tryCombination(A, AExpr, RHS, RHSExpr, B, BExpr))
627 return NewMinMax;
628 }
629
630 if (AExpr != RHSExpr) {
631 // Try (RHS op B) op A
632 if (auto *NewMinMax = tryCombination(RHS, RHSExpr, B, BExpr, A, AExpr))
633 return NewMinMax;
634 }
635
636 return nullptr;
637}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
Definition CFIFixup.cpp:304
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static bool isGEPFoldable(GetElementPtrInst *GEP, const TargetTransformInfo *TTI)
static SCEVTypes convertToSCEVType(Intrinsic::ID IntrinID)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
Value * RHS
Value * LHS
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:306
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
LLVM_ABI void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
LLVM_ABI bool runImpl(Function &F, AssumptionCache *AC_, DominatorTree *DT_, ScalarEvolution *SE_, TargetLibraryInfo *TLI_, TargetTransformInfo *TTI_)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
@ TCC_Free
Expected to fold away in lowering.
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:394
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
Definition Value.cpp:155
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
Value handle that is nullable, but tries to track the Value.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_MaxOrMin(const Opnd0 &Op0, const Opnd1 &Op1)
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI FunctionPass * createNaryReassociatePass()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
generic_gep_type_iterator<> gep_type_iterator
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const SimplifyQuery &SQ)
LLVM_ABI void initializeNaryReassociateLegacyPassPass(PassRegistry &)
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
Definition Local.cpp:550
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
gep_type_iterator gep_type_begin(const User *GEP)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
SCEVUseT< const SCEV * > SCEVUse
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862