Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:42

0001 //===- NaryReassociate.h - Reassociate n-ary expressions --------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This pass reassociates n-ary add expressions and eliminates the redundancy
0010 // exposed by the reassociation.
0011 //
0012 // A motivating example:
0013 //
0014 //   void foo(int a, int b) {
0015 //     bar(a + b);
0016 //     bar((a + 2) + b);
0017 //   }
0018 //
0019 // An ideal compiler should reassociate (a + 2) + b to (a + b) + 2 and simplify
0020 // the above code to
0021 //
0022 //   int t = a + b;
0023 //   bar(t);
0024 //   bar(t + 2);
0025 //
0026 // However, the Reassociate pass is unable to do that because it processes each
0027 // instruction individually and believes (a + 2) + b is the best form according
0028 // to its rank system.
0029 //
0030 // To address this limitation, NaryReassociate reassociates an expression in a
0031 // form that reuses existing instructions. As a result, NaryReassociate can
0032 // reassociate (a + 2) + b in the example to (a + b) + 2 because it detects that
0033 // (a + b) is computed before.
0034 //
0035 // NaryReassociate works as follows. For every instruction in the form of (a +
0036 // b) + c, it checks whether a + c or b + c is already computed by a dominating
0037 // instruction. If so, it then reassociates (a + b) + c into (a + c) + b or (b +
0038 // c) + a and removes the redundancy accordingly. To efficiently look up whether
0039 // an expression is computed before, we store each instruction seen and its SCEV
0040 // into an SCEV-to-instruction map.
0041 //
0042 // Although the algorithm pattern-matches only ternary additions, it
0043 // automatically handles many >3-ary expressions by walking through the function
0044 // in the depth-first order. For example, given
0045 //
0046 //   (a + c) + d
0047 //   ((a + b) + c) + d
0048 //
0049 // NaryReassociate first rewrites (a + b) + c to (a + c) + b, and then rewrites
0050 // ((a + c) + b) + d into ((a + c) + d) + b.
0051 //
0052 // Finally, the above dominator-based algorithm may need to be run multiple
0053 // iterations before emitting optimal code. One source of this need is that we
0054 // only split an operand when it is used only once. The above algorithm can
0055 // eliminate an instruction and decrease the usage count of its operands. As a
0056 // result, an instruction that previously had multiple uses may become a
0057 // single-use instruction and thus eligible for split consideration. For
0058 // example,
0059 //
0060 //   ac = a + c
0061 //   ab = a + b
0062 //   abc = ab + c
0063 //   ab2 = ab + b
0064 //   ab2c = ab2 + c
0065 //
0066 // In the first iteration, we cannot reassociate abc to ac+b because ab is used
0067 // twice. However, we can reassociate ab2c to abc+b in the first iteration. As a
0068 // result, ab2 becomes dead and ab will be used only once in the second
0069 // iteration.
0070 //
0071 // Limitations and TODO items:
0072 //
0073 // 1) We only considers n-ary adds and muls for now. This should be extended
0074 // and generalized.
0075 //
0076 //===----------------------------------------------------------------------===//
0077 
0078 #ifndef LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H
0079 #define LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H
0080 
0081 #include "llvm/ADT/DenseMap.h"
0082 #include "llvm/ADT/SmallVector.h"
0083 #include "llvm/IR/PassManager.h"
0084 #include "llvm/IR/ValueHandle.h"
0085 
0086 namespace llvm {
0087 
0088 class AssumptionCache;
0089 class BinaryOperator;
0090 class DataLayout;
0091 class DominatorTree;
0092 class Function;
0093 class GetElementPtrInst;
0094 class Instruction;
0095 class ScalarEvolution;
0096 class SCEV;
0097 class TargetLibraryInfo;
0098 class TargetTransformInfo;
0099 class Type;
0100 class Value;
0101 
0102 class NaryReassociatePass : public PassInfoMixin<NaryReassociatePass> {
0103 public:
0104   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0105 
0106   // Glue for old PM.
0107   bool runImpl(Function &F, AssumptionCache *AC_, DominatorTree *DT_,
0108                ScalarEvolution *SE_, TargetLibraryInfo *TLI_,
0109                TargetTransformInfo *TTI_);
0110 
0111 private:
0112   // Runs only one iteration of the dominator-based algorithm. See the header
0113   // comments for why we need multiple iterations.
0114   bool doOneIteration(Function &F);
0115 
0116   // Reassociates I for better CSE.
0117   Instruction *tryReassociate(Instruction *I, const SCEV *&OrigSCEV);
0118 
0119   // Reassociate GEP for better CSE.
0120   Instruction *tryReassociateGEP(GetElementPtrInst *GEP);
0121 
0122   // Try splitting GEP at the I-th index and see whether either part can be
0123   // CSE'ed. This is a helper function for tryReassociateGEP.
0124   //
0125   // \p IndexedType The element type indexed by GEP's I-th index. This is
0126   //                equivalent to
0127   //                  GEP->getIndexedType(GEP->getPointerOperand(), 0-th index,
0128   //                                      ..., i-th index).
0129   GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
0130                                               unsigned I, Type *IndexedType);
0131 
0132   // Given GEP's I-th index = LHS + RHS, see whether &Base[..][LHS][..] or
0133   // &Base[..][RHS][..] can be CSE'ed and rewrite GEP accordingly.
0134   GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
0135                                               unsigned I, Value *LHS,
0136                                               Value *RHS, Type *IndexedType);
0137 
0138   // Reassociate binary operators for better CSE.
0139   Instruction *tryReassociateBinaryOp(BinaryOperator *I);
0140 
0141   // A helper function for tryReassociateBinaryOp. LHS and RHS are explicitly
0142   // passed.
0143   Instruction *tryReassociateBinaryOp(Value *LHS, Value *RHS,
0144                                       BinaryOperator *I);
0145   // Rewrites I to (LHS op RHS) if LHS is computed already.
0146   Instruction *tryReassociatedBinaryOp(const SCEV *LHS, Value *RHS,
0147                                        BinaryOperator *I);
0148 
0149   // Tries to match Op1 and Op2 by using V.
0150   bool matchTernaryOp(BinaryOperator *I, Value *V, Value *&Op1, Value *&Op2);
0151 
0152   // Gets SCEV for (LHS op RHS).
0153   const SCEV *getBinarySCEV(BinaryOperator *I, const SCEV *LHS,
0154                             const SCEV *RHS);
0155 
0156   // Returns the closest dominator of \c Dominatee that computes
0157   // \c CandidateExpr. Returns null if not found.
0158   Instruction *findClosestMatchingDominator(const SCEV *CandidateExpr,
0159                                             Instruction *Dominatee);
0160 
0161   // Try to match \p I as signed/unsigned Min/Max and reassociate it. \p
0162   // OrigSCEV is set if \I matches Min/Max regardless whether resassociation is
0163   // done or not. If reassociation was successful newly generated instruction is
0164   // returned, otherwise nullptr.
0165   template <typename PredT>
0166   Instruction *matchAndReassociateMinOrMax(Instruction *I,
0167                                            const SCEV *&OrigSCEV);
0168 
0169   // Reassociate Min/Max.
0170   template <typename MaxMinT>
0171   Value *tryReassociateMinOrMax(Instruction *I, MaxMinT MaxMinMatch, Value *LHS,
0172                                 Value *RHS);
0173 
0174   // GetElementPtrInst implicitly sign-extends an index if the index is shorter
0175   // than the pointer size. This function returns whether Index is shorter than
0176   // GEP's pointer size, i.e., whether Index needs to be sign-extended in order
0177   // to be an index of GEP.
0178   bool requiresSignExtension(Value *Index, GetElementPtrInst *GEP);
0179 
0180   AssumptionCache *AC;
0181   const DataLayout *DL;
0182   DominatorTree *DT;
0183   ScalarEvolution *SE;
0184   TargetLibraryInfo *TLI;
0185   TargetTransformInfo *TTI;
0186 
0187   // A lookup table quickly telling which instructions compute the given SCEV.
0188   // Note that there can be multiple instructions at different locations
0189   // computing to the same SCEV, so we map a SCEV to an instruction list.  For
0190   // example,
0191   //
0192   //   if (p1)
0193   //     foo(a + b);
0194   //   if (p2)
0195   //     bar(a + b);
0196   DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs;
0197 };
0198 
0199 } // end namespace llvm
0200 
0201 #endif // LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H