LLVM 24.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 {
143 AU.setPreservesCFG();
144 }
145
146private:
148};
149
150} // end anonymous namespace
151
152char NaryReassociateLegacyPass::ID = 0;
153
154INITIALIZE_PASS_BEGIN(NaryReassociateLegacyPass, "nary-reassociate",
155 "Nary reassociation", false, false)
161INITIALIZE_PASS_END(NaryReassociateLegacyPass, "nary-reassociate",
162 "Nary reassociation", false, false)
163
165 return new NaryReassociateLegacyPass();
166}
167
168bool NaryReassociateLegacyPass::runOnFunction(Function &F) {
169 if (skipFunction(F))
170 return false;
171
172 auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
173 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
174 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
175 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
176 auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
177
178 return Impl.runImpl(F, AC, DT, SE, TLI, TTI);
179}
180
183 auto *AC = &AM.getResult<AssumptionAnalysis>(F);
184 auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
185 auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
186 auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
187 auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
188
189 if (!runImpl(F, AC, DT, SE, TLI, TTI))
190 return PreservedAnalyses::all();
191
195 return PA;
196}
197
200 TargetLibraryInfo *TLI_,
201 TargetTransformInfo *TTI_) {
202 AC = AC_;
203 DT = DT_;
204 SE = SE_;
205 TLI = TLI_;
206 TTI = TTI_;
207 DL = &F.getDataLayout();
208
209 bool Changed = false, ChangedInThisIteration;
210 do {
211 ChangedInThisIteration = doOneIteration(F);
212 Changed |= ChangedInThisIteration;
213 } while (ChangedInThisIteration);
214 return Changed;
215}
216
217bool NaryReassociatePass::doOneIteration(Function &F) {
218 bool Changed = false;
219 SeenExprs.clear();
220 // Process the basic blocks in a depth first traversal of the dominator
221 // tree. This order ensures that all bases of a candidate are in Candidates
222 // when we process it.
224 for (const auto Node : depth_first(DT)) {
225 BasicBlock *BB = Node->getBlock();
226 for (Instruction &OrigI : *BB) {
227 SCEVUse OrigSCEV = nullptr;
228 if (Instruction *NewI = tryReassociate(&OrigI, OrigSCEV)) {
229 Changed = true;
230 OrigI.replaceAllUsesWith(NewI);
231
232 // Add 'OrigI' to the list of dead instructions.
233 DeadInsts.push_back(WeakTrackingVH(&OrigI));
234 // Add the rewritten instruction to SeenExprs; the original
235 // instruction is deleted.
236 SCEVUse NewSCEV = SE->getSCEV(NewI);
237 SeenExprs[NewSCEV].push_back(WeakTrackingVH(NewI));
238
239 // Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
240 // is equivalent to I. However, ScalarEvolution::getSCEV may
241 // weaken nsw causing NewSCEV not to equal OldSCEV. For example,
242 // suppose we reassociate
243 // I = &a[sext(i +nsw j)] // assuming sizeof(a[0]) = 4
244 // to
245 // NewI = &a[sext(i)] + sext(j).
246 //
247 // ScalarEvolution computes
248 // getSCEV(I) = a + 4 * sext(i + j)
249 // getSCEV(newI) = a + 4 * sext(i) + 4 * sext(j)
250 // which are different SCEVs.
251 //
252 // To alleviate this issue of ScalarEvolution not always capturing
253 // equivalence, we add I to SeenExprs[OldSCEV] as well so that we can
254 // map both SCEV before and after tryReassociate(I) to I.
255 //
256 // This improvement is exercised in @reassociate_gep_nsw in
257 // nary-gep.ll.
258 if (NewSCEV != OrigSCEV)
259 SeenExprs[OrigSCEV].push_back(WeakTrackingVH(NewI));
260 } else if (OrigSCEV)
261 SeenExprs[OrigSCEV].push_back(WeakTrackingVH(&OrigI));
262 }
263 }
264 // Delete all dead instructions from 'DeadInsts'.
265 // Please note ScalarEvolution is updated along the way.
267 DeadInsts, TLI, nullptr, [this](Value *V) { SE->forgetValue(V); });
268
269 return Changed;
270}
271
272Instruction *NaryReassociatePass::tryReassociate(Instruction *I,
273 SCEVUse &OrigSCEV) {
274
275 if (!SE->isSCEVable(I->getType()))
276 return nullptr;
277
278 switch (I->getOpcode()) {
279 case Instruction::Add:
280 case Instruction::Mul:
281 OrigSCEV = SE->getSCEV(I);
282 return tryReassociateBinaryOp(cast<BinaryOperator>(I));
283 case Instruction::GetElementPtr:
284 OrigSCEV = SE->getSCEV(I);
285 return tryReassociateGEP(cast<GetElementPtrInst>(I));
286 default:
287 break;
288 }
289
290 // Try to match signed/unsigned Min/Max.
291 if (match(I, m_MaxOrMin(m_Value(), m_Value()))) {
292 OrigSCEV = SE->getSCEV(I);
294 tryReassociateMinOrMax(cast<IntrinsicInst>(I)));
295 }
296
297 return nullptr;
298}
299
301 const TargetTransformInfo *TTI) {
302 SmallVector<const Value *, 4> Indices(GEP->indices());
303 return TTI->getGEPCost(
304 GEP->getSourceElementType(), GEP->getPointerOperand(), Indices,
307}
308
309Instruction *NaryReassociatePass::tryReassociateGEP(GetElementPtrInst *GEP) {
310 // Not worth reassociating GEP if it is foldable.
311 if (isGEPFoldable(GEP, TTI))
312 return nullptr;
313
315 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) {
316 if (GTI.isSequential()) {
317 if (auto *NewGEP = tryReassociateGEPAtIndex(GEP, I - 1,
318 GTI.getIndexedType())) {
319 return NewGEP;
320 }
321 }
322 }
323 return nullptr;
324}
325
326bool NaryReassociatePass::requiresSignExtension(Value *Index,
327 GetElementPtrInst *GEP) {
328 unsigned IndexSizeInBits =
329 DL->getIndexSizeInBits(GEP->getType()->getPointerAddressSpace());
330 return cast<IntegerType>(Index->getType())->getBitWidth() < IndexSizeInBits;
331}
332
333GetElementPtrInst *
334NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
335 unsigned I, Type *IndexedType) {
336 SimplifyQuery SQ(*DL, DT, AC, GEP);
337 Value *IndexToSplit = GEP->getOperand(I + 1);
338 if (SExtInst *SExt = dyn_cast<SExtInst>(IndexToSplit)) {
339 IndexToSplit = SExt->getOperand(0);
340 } else if (ZExtInst *ZExt = dyn_cast<ZExtInst>(IndexToSplit)) {
341 // zext can be treated as sext if the source is non-negative.
342 if (isKnownNonNegative(ZExt->getOperand(0), SQ))
343 IndexToSplit = ZExt->getOperand(0);
344 }
345
346 if (AddOperator *AO = dyn_cast<AddOperator>(IndexToSplit)) {
347 // If the I-th index needs sext and the underlying add is not equipped with
348 // nsw, we cannot split the add because
349 // sext(LHS + RHS) != sext(LHS) + sext(RHS).
350 if (requiresSignExtension(IndexToSplit, GEP) &&
351 computeOverflowForSignedAdd(AO, SQ) != OverflowResult::NeverOverflows)
352 return nullptr;
353
354 Value *LHS = AO->getOperand(0), *RHS = AO->getOperand(1);
355 // IndexToSplit = LHS + RHS.
356 if (auto *NewGEP = tryReassociateGEPAtIndex(GEP, I, LHS, RHS, IndexedType))
357 return NewGEP;
358 // Symmetrically, try IndexToSplit = RHS + LHS.
359 if (LHS != RHS) {
360 if (auto *NewGEP =
361 tryReassociateGEPAtIndex(GEP, I, RHS, LHS, IndexedType))
362 return NewGEP;
363 }
364 }
365 return nullptr;
366}
367
368GetElementPtrInst *
369NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
370 unsigned I, Value *LHS,
371 Value *RHS, Type *IndexedType) {
372 // Look for GEP's closest dominator that has the same SCEV as GEP except that
373 // the I-th index is replaced with LHS.
374 SmallVector<SCEVUse, 4> IndexExprs;
375 for (Use &Index : GEP->indices())
376 IndexExprs.push_back(SE->getSCEV(Index));
377 // Replace the I-th index with LHS.
378 IndexExprs[I] = SE->getSCEV(LHS);
379 Type *GEPArgType = SE->getEffectiveSCEVType(GEP->getOperand(I)->getType());
380 Type *LHSType = SE->getEffectiveSCEVType(LHS->getType());
381 size_t LHSSize = DL->getTypeSizeInBits(LHSType).getFixedValue();
382 size_t GEPArgSize = DL->getTypeSizeInBits(GEPArgType).getFixedValue();
383 if (isKnownNonNegative(LHS, SimplifyQuery(*DL, DT, AC, GEP)) &&
384 LHSSize < GEPArgSize) {
385 // Zero-extend LHS if it is non-negative. InstCombine canonicalizes sext to
386 // zext if the source operand is proved non-negative. We should do that
387 // consistently so that CandidateExpr more likely appears before. See
388 // @reassociate_gep_assume for an example of this canonicalization.
389 IndexExprs[I] = SE->getZeroExtendExpr(IndexExprs[I], GEPArgType);
390 }
391 SCEVUse CandidateExpr = SE->getGEPExpr(cast<GEPOperator>(GEP), IndexExprs);
392
393 Value *Candidate = findClosestMatchingDominator(CandidateExpr, GEP);
394 if (Candidate == nullptr)
395 return nullptr;
396
397 IRBuilder<> Builder(GEP);
398 // Candidate should have the same pointer type as GEP.
399 assert(Candidate->getType() == GEP->getType());
400
401 // NewGEP = (char *)Candidate + RHS * sizeof(IndexedType)
402 uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType);
403 Type *ElementType = GEP->getResultElementType();
404 uint64_t ElementSize = DL->getTypeAllocSize(ElementType);
405 // Another less rare case: because I is not necessarily the last index of the
406 // GEP, the size of the type at the I-th index (IndexedSize) is not
407 // necessarily divisible by ElementSize. For example,
408 //
409 // #pragma pack(1)
410 // struct S {
411 // int a[3];
412 // int64 b[8];
413 // };
414 // #pragma pack()
415 //
416 // sizeof(S) = 100 is indivisible by sizeof(int64) = 8.
417 //
418 // TODO: bail out on this case for now. We could emit uglygep.
419 if (ElementSize == 0 || IndexedSize % ElementSize != 0)
420 return nullptr;
421
422 // NewGEP = &Candidate[RHS * (sizeof(IndexedType) / sizeof(Candidate[0])));
423 Type *PtrIdxTy = DL->getIndexType(GEP->getType());
424 if (RHS->getType() != PtrIdxTy)
425 RHS = Builder.CreateSExtOrTrunc(RHS, PtrIdxTy);
426 if (IndexedSize != ElementSize) {
427 RHS = Builder.CreateMul(
428 RHS, ConstantInt::get(PtrIdxTy, IndexedSize / ElementSize));
429 }
430 GetElementPtrInst *NewGEP = cast<GetElementPtrInst>(
431 Builder.CreateGEP(GEP->getResultElementType(), Candidate, RHS));
432 NewGEP->setIsInBounds(GEP->isInBounds());
433 NewGEP->takeName(GEP);
434 return NewGEP;
435}
436
437Instruction *NaryReassociatePass::tryReassociateBinaryOp(BinaryOperator *I) {
438 Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
439 // There is no need to reassociate 0.
440 if (SE->getSCEV(I)->isZero())
441 return nullptr;
442 if (auto *NewI = tryReassociateBinaryOp(LHS, RHS, I))
443 return NewI;
444 if (auto *NewI = tryReassociateBinaryOp(RHS, LHS, I))
445 return NewI;
446 return nullptr;
447}
448
449Instruction *NaryReassociatePass::tryReassociateBinaryOp(Value *LHS, Value *RHS,
450 BinaryOperator *I) {
451 Value *A = nullptr, *B = nullptr;
452 // To be conservative, we reassociate I only when it is the only user of (A op
453 // B).
454 if (LHS->hasOneUse() && matchTernaryOp(I, LHS, A, B)) {
455 // I = (A op B) op RHS
456 // = (A op RHS) op B or (B op RHS) op A
457 SCEVUse AExpr = SE->getSCEV(A), BExpr = SE->getSCEV(B);
458 SCEVUse RHSExpr = SE->getSCEV(RHS);
459 if (BExpr != RHSExpr) {
460 if (auto *NewI =
461 tryReassociatedBinaryOp(getBinarySCEV(I, AExpr, RHSExpr), B, I))
462 return NewI;
463 }
464 if (AExpr != RHSExpr) {
465 if (auto *NewI =
466 tryReassociatedBinaryOp(getBinarySCEV(I, BExpr, RHSExpr), A, I))
467 return NewI;
468 }
469 }
470 return nullptr;
471}
472
473Instruction *NaryReassociatePass::tryReassociatedBinaryOp(SCEVUse LHSExpr,
474 Value *RHS,
475 BinaryOperator *I) {
476 // Look for the closest dominator LHS of I that computes LHSExpr, and replace
477 // I with LHS op RHS.
478 auto *LHS = findClosestMatchingDominator(LHSExpr, I);
479 if (LHS == nullptr)
480 return nullptr;
481
482 Instruction *NewI = nullptr;
483 switch (I->getOpcode()) {
484 case Instruction::Add:
485 NewI = BinaryOperator::CreateAdd(LHS, RHS, "", I->getIterator());
486 break;
487 case Instruction::Mul:
488 NewI = BinaryOperator::CreateMul(LHS, RHS, "", I->getIterator());
489 break;
490 default:
491 llvm_unreachable("Unexpected instruction.");
492 }
493 NewI->setDebugLoc(I->getDebugLoc());
494 NewI->takeName(I);
495 return NewI;
496}
497
498bool NaryReassociatePass::matchTernaryOp(BinaryOperator *I, Value *V,
499 Value *&Op1, Value *&Op2) {
500 switch (I->getOpcode()) {
501 case Instruction::Add:
502 return match(V, m_Add(m_Value(Op1), m_Value(Op2)));
503 case Instruction::Mul:
504 return match(V, m_Mul(m_Value(Op1), m_Value(Op2)));
505 default:
506 llvm_unreachable("Unexpected instruction.");
507 }
508 return false;
509}
510
511SCEVUse NaryReassociatePass::getBinarySCEV(BinaryOperator *I, SCEVUse LHS,
512 SCEVUse RHS) {
513 switch (I->getOpcode()) {
514 case Instruction::Add:
515 return SE->getAddExpr(LHS, RHS);
516 case Instruction::Mul:
517 return SE->getMulExpr(LHS, RHS);
518 default:
519 llvm_unreachable("Unexpected instruction.");
520 }
521 return nullptr;
522}
523
525NaryReassociatePass::findClosestMatchingDominator(SCEVUse CandidateExpr,
526 Instruction *Dominatee) {
527 auto Pos = SeenExprs.find(CandidateExpr);
528 if (Pos == SeenExprs.end())
529 return nullptr;
530
531 auto &Candidates = Pos->second;
532 // Because we process the basic blocks in pre-order of the dominator tree, a
533 // candidate that doesn't dominate the current instruction won't dominate any
534 // future instruction either. Therefore, we pop it out of the stack. This
535 // optimization makes the algorithm O(n).
536 while (!Candidates.empty()) {
537 // Candidates stores WeakTrackingVHs, so a candidate can be nullptr if it's
538 // removed during rewriting.
539 if (Value *Candidate = Candidates.pop_back_val()) {
540 Instruction *CandidateInstruction = cast<Instruction>(Candidate);
541 if (!DT->dominates(CandidateInstruction, Dominatee))
542 continue;
543
544 // Make sure that the instruction is safe to reuse without introducing
545 // poison.
546 SmallVector<Instruction *> DropPoisonGeneratingInsts;
547 if (!SE->canReuseInstruction(CandidateExpr, CandidateInstruction,
548 DropPoisonGeneratingInsts))
549 continue;
550
551 for (Instruction *I : DropPoisonGeneratingInsts)
552 I->dropPoisonGeneratingAnnotations();
553
554 return CandidateInstruction;
555 }
556 }
557 return nullptr;
558}
559
561 switch (IntrinID) {
562 case Intrinsic::smax:
563 return scSMaxExpr;
564 case Intrinsic::umax:
565 return scUMaxExpr;
566 case Intrinsic::smin:
567 return scSMinExpr;
568 case Intrinsic::umin:
569 return scUMinExpr;
570 default:
571 llvm_unreachable("Can't convert MinMax pattern to SCEV type");
572 return scUnknown;
573 }
574}
575
576Value *NaryReassociatePass::tryReassociateMinOrMax(IntrinsicInst *I) {
577 Value *LHS = I->getArgOperand(0);
578 Value *RHS = I->getArgOperand(1);
579 if (auto *RHSI = dyn_cast<IntrinsicInst>(RHS);
580 RHSI && RHSI->getIntrinsicID() == I->getIntrinsicID())
581 std::swap(LHS, RHS);
582 auto *LHSI = dyn_cast<IntrinsicInst>(LHS);
583 if (!LHSI || LHSI->getIntrinsicID() != I->getIntrinsicID())
584 return nullptr;
585
586 Value *A = LHSI->getArgOperand(0), *B = LHSI->getArgOperand(1);
587
588 if (LHS->hasNUsesOrMore(3) ||
589 // The optimization is profitable only if LHS can be removed in the end.
590 // In other words LHS should be used (directly or indirectly) by I only.
591 llvm::any_of(LHS->users(), [&](auto *U) {
592 return U != I && !(U->hasOneUser() && *U->users().begin() == I);
593 }))
594 return nullptr;
595
596 auto tryCombination = [&](Value *A, SCEVUse AExpr, Value *B, SCEVUse BExpr,
597 Value *C, SCEVUse CExpr) -> Value * {
598 SmallVector<SCEVUse, 2> Ops1{BExpr, AExpr};
599 SCEVTypes SCEVType = convertToSCEVType(I->getIntrinsicID());
600 SCEVUse R1Expr = SE->getMinMaxExpr(SCEVType, Ops1);
601
602 Instruction *R1MinMax = findClosestMatchingDominator(R1Expr, I);
603
604 if (!R1MinMax)
605 return nullptr;
606
607 LLVM_DEBUG(dbgs() << "NARY: Found common sub-expr: " << *R1MinMax << "\n");
608
609 SmallVector<SCEVUse, 2> Ops2{SE->getUnknown(C), SE->getUnknown(R1MinMax)};
610 SCEVUse R2Expr = SE->getMinMaxExpr(SCEVType, Ops2);
611
612 SCEVExpander Expander(*SE, "nary-reassociate");
613 Value *NewMinMax = Expander.expandCodeFor(R2Expr, I->getType(), I);
614 NewMinMax->setName(Twine(I->getName()).concat(".nary"));
615
616 LLVM_DEBUG(dbgs() << "NARY: Deleting: " << *I << "\n"
617 << "NARY: Inserting: " << *NewMinMax << "\n");
618 return NewMinMax;
619 };
620
621 SCEVUse AExpr = SE->getSCEV(A);
622 SCEVUse BExpr = SE->getSCEV(B);
623 SCEVUse RHSExpr = SE->getSCEV(RHS);
624
625 if (BExpr != RHSExpr) {
626 // Try (A op RHS) op B
627 if (auto *NewMinMax = tryCombination(A, AExpr, RHS, RHSExpr, B, BExpr))
628 return NewMinMax;
629 }
630
631 if (AExpr != RHSExpr) {
632 // Try (RHS op B) op A
633 if (auto *NewMinMax = tryCombination(RHS, RHSExpr, B, BExpr, A, AExpr))
634 return NewMinMax;
635 }
636
637 return nullptr;
638}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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:241
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:277
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
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.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ 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.
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:537
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:880