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) DLSimplifyQuery62 : 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) DLSimplifyQuery68 : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {} getWithInstructionSimplifyQuery69 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 InsertElement, fold the result or return null. 165 Value *SimplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, 166 const SimplifyQuery &Q); 167 168 /// Given operands for an ExtractValueInst, fold the result or return null. 169 Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs, 170 const SimplifyQuery &Q); 171 172 /// Given operands for an ExtractElementInst, fold the result or return null. 173 Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, 174 const SimplifyQuery &Q); 175 176 /// Given operands for a CastInst, fold the result or return null. 177 Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, 178 const SimplifyQuery &Q); 179 180 /// Given operands for a ShuffleVectorInst, fold the result or return null. 181 Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, 182 Type *RetTy, const SimplifyQuery &Q); 183 184 //=== Helper functions for higher up the class hierarchy. 185 186 /// Given operands for a CmpInst, fold the result or return null. 187 Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, 188 const SimplifyQuery &Q); 189 190 /// Given operands for a BinaryOperator, fold the result or return null. 191 Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, 192 const SimplifyQuery &Q); 193 194 /// Given operands for an FP BinaryOperator, fold the result or return null. 195 /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the 196 /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp. 197 Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, 198 FastMathFlags FMF, const SimplifyQuery &Q); 199 200 /// Given a callsite, fold the result or return null. 201 Value *SimplifyCall(ImmutableCallSite CS, const SimplifyQuery &Q); 202 203 /// Given a function and iterators over arguments, fold the result or return 204 /// null. 205 Value *SimplifyCall(ImmutableCallSite CS, Value *V, User::op_iterator ArgBegin, 206 User::op_iterator ArgEnd, const SimplifyQuery &Q); 207 208 /// Given a function and set of arguments, fold the result or return null. 209 Value *SimplifyCall(ImmutableCallSite CS, Value *V, ArrayRef<Value *> Args, 210 const SimplifyQuery &Q); 211 212 /// See if we can compute a simplified version of this instruction. If not, 213 /// return null. 214 Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, 215 OptimizationRemarkEmitter *ORE = nullptr); 216 217 /// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively. 218 /// 219 /// This first performs a normal RAUW of I with SimpleV. It then recursively 220 /// attempts to simplify those users updated by the operation. The 'I' 221 /// instruction must not be equal to the simplified value 'SimpleV'. 222 /// 223 /// The function returns true if any simplifications were performed. 224 bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, 225 const TargetLibraryInfo *TLI = nullptr, 226 const DominatorTree *DT = nullptr, 227 AssumptionCache *AC = nullptr); 228 229 /// Recursively attempt to simplify an instruction. 230 /// 231 /// This routine uses SimplifyInstruction to simplify 'I', and if successful 232 /// replaces uses of 'I' with the simplified value. It then recurses on each 233 /// of the users impacted. It returns true if any simplifications were 234 /// performed. 235 bool recursivelySimplifyInstruction(Instruction *I, 236 const TargetLibraryInfo *TLI = nullptr, 237 const DominatorTree *DT = nullptr, 238 AssumptionCache *AC = nullptr); 239 240 // These helper functions return a SimplifyQuery structure that contains as 241 // many of the optional analysis we use as are currently valid. This is the 242 // strongly preferred way of constructing SimplifyQuery in passes. 243 const SimplifyQuery getBestSimplifyQuery(Pass &, Function &); 244 template <class T, class... TArgs> 245 const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &, 246 Function &); 247 const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &, 248 const DataLayout &); 249 } // end namespace llvm 250 251 #endif 252 253