Home | History | Annotate | Download | only in Analysis
      1 //===-- InstructionSimplify.h - Fold instrs into simpler forms --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares routines for folding instructions into simpler forms
     11 // that do not require creating new instructions.  This does constant folding
     12 // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
     13 // returning a constant ("and i32 %x, 0" -> "0") or an already existing value
     14 // ("and i32 %x, %x" -> "%x").  If the simplification is also an instruction
     15 // then it dominates the original instruction.
     16 //
     17 // These routines implicitly resolve undef uses. The easiest way to be safe when
     18 // using these routines to obtain simplified values for existing instructions is
     19 // to always replace all uses of the instructions with the resulting simplified
     20 // values. This will prevent other code from seeing the same undef uses and
     21 // resolving them to different values.
     22 //
     23 // These routines are designed to tolerate moderately incomplete IR, such as
     24 // instructions that are not connected to basic blocks yet. However, they do
     25 // require that all the IR that they encounter be valid. In particular, they
     26 // require that all non-constant values be defined in the same function, and the
     27 // same call context of that function (and not split between caller and callee
     28 // contexts of a directly recursive call, for example).
     29 //
     30 //===----------------------------------------------------------------------===//
     31 
     32 #ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
     33 #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
     34 
     35 #include "llvm/IR/User.h"
     36 
     37 namespace llvm {
     38 class Function;
     39 template <typename T, typename... TArgs> class AnalysisManager;
     40 template <class T> class ArrayRef;
     41 class AssumptionCache;
     42 class DominatorTree;
     43 class Instruction;
     44 class ImmutableCallSite;
     45 class DataLayout;
     46 class FastMathFlags;
     47 struct LoopStandardAnalysisResults;
     48 class OptimizationRemarkEmitter;
     49 class Pass;
     50 class TargetLibraryInfo;
     51 class Type;
     52 class Value;
     53 
     54 struct SimplifyQuery {
     55   const DataLayout &DL;
     56   const TargetLibraryInfo *TLI = nullptr;
     57   const DominatorTree *DT = nullptr;
     58   AssumptionCache *AC = nullptr;
     59   const Instruction *CxtI = nullptr;
     60 
     61   SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr)
     62       : DL(DL), CxtI(CXTI) {}
     63 
     64   SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
     65                 const DominatorTree *DT = nullptr,
     66                 AssumptionCache *AC = nullptr,
     67                 const Instruction *CXTI = nullptr)
     68       : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {}
     69   SimplifyQuery getWithInstruction(Instruction *I) const {
     70     SimplifyQuery Copy(*this);
     71     Copy.CxtI = I;
     72     return Copy;
     73   }
     74 };
     75 
     76 // NOTE: the explicit multiple argument versions of these functions are
     77 // deprecated.
     78 // Please use the SimplifyQuery versions in new code.
     79 
     80 /// Given operands for an Add, fold the result or return null.
     81 Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
     82                        const SimplifyQuery &Q);
     83 
     84 /// Given operands for a Sub, fold the result or return null.
     85 Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
     86                        const SimplifyQuery &Q);
     87 
     88 /// Given operands for an FAdd, fold the result or return null.
     89 Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
     90                         const SimplifyQuery &Q);
     91 
     92 /// Given operands for an FSub, fold the result or return null.
     93 Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
     94                         const SimplifyQuery &Q);
     95 
     96 /// Given operands for an FMul, fold the result or return null.
     97 Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
     98                         const SimplifyQuery &Q);
     99 
    100 /// Given operands for a Mul, fold the result or return null.
    101 Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    102 
    103 /// Given operands for an SDiv, fold the result or return null.
    104 Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    105 
    106 /// Given operands for a UDiv, fold the result or return null.
    107 Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    108 
    109 /// Given operands for an FDiv, fold the result or return null.
    110 Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
    111                         const SimplifyQuery &Q);
    112 
    113 /// Given operands for an SRem, fold the result or return null.
    114 Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    115 
    116 /// Given operands for a URem, fold the result or return null.
    117 Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    118 
    119 /// Given operands for an FRem, fold the result or return null.
    120 Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
    121                         const SimplifyQuery &Q);
    122 
    123 /// Given operands for a Shl, fold the result or return null.
    124 Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
    125                        const SimplifyQuery &Q);
    126 
    127 /// Given operands for a LShr, fold the result or return null.
    128 Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
    129                         const SimplifyQuery &Q);
    130 
    131 /// Given operands for a AShr, fold the result or return nulll.
    132 Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
    133                         const SimplifyQuery &Q);
    134 
    135 /// Given operands for an And, fold the result or return null.
    136 Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    137 
    138 /// Given operands for an Or, fold the result or return null.
    139 Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    140 
    141 /// Given operands for an Xor, fold the result or return null.
    142 Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
    143 
    144 /// Given operands for an ICmpInst, fold the result or return null.
    145 Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
    146                         const SimplifyQuery &Q);
    147 
    148 /// Given operands for an FCmpInst, fold the result or return null.
    149 Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
    150                         FastMathFlags FMF, const SimplifyQuery &Q);
    151 
    152 /// Given operands for a SelectInst, fold the result or return null.
    153 Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
    154                           const SimplifyQuery &Q);
    155 
    156 /// Given operands for a GetElementPtrInst, fold the result or return null.
    157 Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
    158                        const SimplifyQuery &Q);
    159 
    160 /// Given operands for an InsertValueInst, fold the result or return null.
    161 Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
    162                                const SimplifyQuery &Q);
    163 
    164 /// Given operands for an ExtractValueInst, fold the result or return null.
    165 Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
    166                                 const SimplifyQuery &Q);
    167 
    168 /// Given operands for an ExtractElementInst, fold the result or return null.
    169 Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
    170                                   const SimplifyQuery &Q);
    171 
    172 /// Given operands for a CastInst, fold the result or return null.
    173 Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
    174                         const SimplifyQuery &Q);
    175 
    176 /// Given operands for a ShuffleVectorInst, fold the result or return null.
    177 Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
    178                                  Type *RetTy, const SimplifyQuery &Q);
    179 
    180 //=== Helper functions for higher up the class hierarchy.
    181 
    182 /// Given operands for a CmpInst, fold the result or return null.
    183 Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
    184                        const SimplifyQuery &Q);
    185 
    186 /// Given operands for a BinaryOperator, fold the result or return null.
    187 Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
    188                      const SimplifyQuery &Q);
    189 
    190 /// Given operands for an FP BinaryOperator, fold the result or return null.
    191 /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
    192 /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
    193 Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
    194                        FastMathFlags FMF, const SimplifyQuery &Q);
    195 
    196 /// Given a function and iterators over arguments, fold the result or return
    197 /// null.
    198 Value *SimplifyCall(ImmutableCallSite CS, Value *V, User::op_iterator ArgBegin,
    199                     User::op_iterator ArgEnd, const SimplifyQuery &Q);
    200 
    201 /// Given a function and set of arguments, fold the result or return null.
    202 Value *SimplifyCall(ImmutableCallSite CS, Value *V, ArrayRef<Value *> Args,
    203                     const SimplifyQuery &Q);
    204 
    205 /// See if we can compute a simplified version of this instruction. If not,
    206 /// return null.
    207 Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
    208                            OptimizationRemarkEmitter *ORE = nullptr);
    209 
    210 /// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
    211 ///
    212 /// This first performs a normal RAUW of I with SimpleV. It then recursively
    213 /// attempts to simplify those users updated by the operation. The 'I'
    214 /// instruction must not be equal to the simplified value 'SimpleV'.
    215 ///
    216 /// The function returns true if any simplifications were performed.
    217 bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
    218                                    const TargetLibraryInfo *TLI = nullptr,
    219                                    const DominatorTree *DT = nullptr,
    220                                    AssumptionCache *AC = nullptr);
    221 
    222 /// Recursively attempt to simplify an instruction.
    223 ///
    224 /// This routine uses SimplifyInstruction to simplify 'I', and if successful
    225 /// replaces uses of 'I' with the simplified value. It then recurses on each
    226 /// of the users impacted. It returns true if any simplifications were
    227 /// performed.
    228 bool recursivelySimplifyInstruction(Instruction *I,
    229                                     const TargetLibraryInfo *TLI = nullptr,
    230                                     const DominatorTree *DT = nullptr,
    231                                     AssumptionCache *AC = nullptr);
    232 
    233 // These helper functions return a SimplifyQuery structure that contains as
    234 // many of the optional analysis we use as are currently valid.  This is the
    235 // strongly preferred way of constructing SimplifyQuery in passes.
    236 const SimplifyQuery getBestSimplifyQuery(Pass &, Function &);
    237 template <class T, class... TArgs>
    238 const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &,
    239                                          Function &);
    240 const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &,
    241                                          const DataLayout &);
    242 } // end namespace llvm
    243 
    244 #endif
    245 
    246