| 1 | //===- SimplifyLibCalls.h - Library call simplifier -------------*- C++ -*-===// |
| 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 file exposes an interface to build some C language libcalls for |
| 10 | // optimization passes that need to call the various functions. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H |
| 15 | #define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H |
| 16 | |
| 17 | #include "llvm/ADT/STLFunctionalExtras.h" |
| 18 | #include "llvm/Analysis/TargetLibraryInfo.h" |
| 19 | |
| 20 | namespace llvm { |
| 21 | class AssumptionCache; |
| 22 | class StringRef; |
| 23 | class Value; |
| 24 | class CallInst; |
| 25 | class DominatorTree; |
| 26 | class DomConditionCache; |
| 27 | class DataLayout; |
| 28 | class Instruction; |
| 29 | class IRBuilderBase; |
| 30 | class Function; |
| 31 | class ; |
| 32 | class BlockFrequencyInfo; |
| 33 | class ProfileSummaryInfo; |
| 34 | |
| 35 | /// This class implements simplifications for calls to fortified library |
| 36 | /// functions (__st*cpy_chk, __memcpy_chk, __memmove_chk, __memset_chk), to, |
| 37 | /// when possible, replace them with their non-checking counterparts. |
| 38 | /// Other optimizations can also be done, but it's possible to disable them and |
| 39 | /// only simplify needless use of the checking versions (when the object size |
| 40 | /// is unknown) by passing true for OnlyLowerUnknownSize. |
| 41 | class FortifiedLibCallSimplifier { |
| 42 | private: |
| 43 | const TargetLibraryInfo *TLI; |
| 44 | bool OnlyLowerUnknownSize; |
| 45 | |
| 46 | public: |
| 47 | FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI, |
| 48 | bool OnlyLowerUnknownSize = false); |
| 49 | |
| 50 | /// Take the given call instruction and return a more |
| 51 | /// optimal value to replace the instruction with or 0 if a more |
| 52 | /// optimal form can't be found. |
| 53 | /// The call must not be an indirect call. |
| 54 | Value *optimizeCall(CallInst *CI, IRBuilderBase &B); |
| 55 | |
| 56 | private: |
| 57 | Value *optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B); |
| 58 | Value *optimizeMemMoveChk(CallInst *CI, IRBuilderBase &B); |
| 59 | Value *optimizeMemSetChk(CallInst *CI, IRBuilderBase &B); |
| 60 | |
| 61 | /// Str/Stp cpy are similar enough to be handled in the same functions. |
| 62 | Value *optimizeStrpCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func); |
| 63 | Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func); |
| 64 | Value *optimizeStrLenChk(CallInst *CI, IRBuilderBase &B); |
| 65 | Value *optimizeMemPCpyChk(CallInst *CI, IRBuilderBase &B); |
| 66 | Value *optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B); |
| 67 | Value *optimizeSNPrintfChk(CallInst *CI, IRBuilderBase &B); |
| 68 | Value *optimizeSPrintfChk(CallInst *CI,IRBuilderBase &B); |
| 69 | Value *optimizeStrCatChk(CallInst *CI, IRBuilderBase &B); |
| 70 | Value *optimizeStrLCat(CallInst *CI, IRBuilderBase &B); |
| 71 | Value *optimizeStrNCatChk(CallInst *CI, IRBuilderBase &B); |
| 72 | Value *optimizeStrLCpyChk(CallInst *CI, IRBuilderBase &B); |
| 73 | Value *optimizeVSNPrintfChk(CallInst *CI, IRBuilderBase &B); |
| 74 | Value *optimizeVSPrintfChk(CallInst *CI, IRBuilderBase &B); |
| 75 | |
| 76 | /// Checks whether the call \p CI to a fortified libcall is foldable |
| 77 | /// to the non-fortified version. |
| 78 | /// |
| 79 | /// \param CI the call to the fortified libcall. |
| 80 | /// |
| 81 | /// \param ObjSizeOp the index of the object size parameter of this chk |
| 82 | /// function. Not optional since this is mandatory. |
| 83 | /// |
| 84 | /// \param SizeOp optionally set to the parameter index of an explicit buffer |
| 85 | /// size argument. For instance, set to '2' for __strncpy_chk. |
| 86 | /// |
| 87 | /// \param StrOp optionally set to the parameter index of the source string |
| 88 | /// parameter to strcpy-like functions, where only the strlen of the source |
| 89 | /// will be writtin into the destination. |
| 90 | /// |
| 91 | /// \param FlagsOp optionally set to the parameter index of a 'flags' |
| 92 | /// parameter. These are used by an implementation to opt-into stricter |
| 93 | /// checking. |
| 94 | bool isFortifiedCallFoldable(CallInst *CI, unsigned ObjSizeOp, |
| 95 | std::optional<unsigned> SizeOp = std::nullopt, |
| 96 | std::optional<unsigned> StrOp = std::nullopt, |
| 97 | std::optional<unsigned> FlagsOp = std::nullopt); |
| 98 | }; |
| 99 | |
| 100 | /// LibCallSimplifier - This class implements a collection of optimizations |
| 101 | /// that replace well formed calls to library functions with a more optimal |
| 102 | /// form. For example, replacing 'printf("Hello!")' with 'puts("Hello!")'. |
| 103 | class LibCallSimplifier { |
| 104 | private: |
| 105 | FortifiedLibCallSimplifier FortifiedSimplifier; |
| 106 | const DataLayout &DL; |
| 107 | const TargetLibraryInfo *TLI; |
| 108 | DominatorTree *DT; |
| 109 | DomConditionCache *DC; |
| 110 | AssumptionCache *AC; |
| 111 | OptimizationRemarkEmitter &ORE; |
| 112 | BlockFrequencyInfo *BFI; |
| 113 | ProfileSummaryInfo *PSI; |
| 114 | bool UnsafeFPShrink = false; |
| 115 | function_ref<void(Instruction *, Value *)> Replacer; |
| 116 | function_ref<void(Instruction *)> Eraser; |
| 117 | |
| 118 | /// Internal wrapper for RAUW that is the default implementation. |
| 119 | /// |
| 120 | /// Other users may provide an alternate function with this signature instead |
| 121 | /// of this one. |
| 122 | static void replaceAllUsesWithDefault(Instruction *I, Value *With) { |
| 123 | I->replaceAllUsesWith(V: With); |
| 124 | } |
| 125 | |
| 126 | /// Internal wrapper for eraseFromParent that is the default implementation. |
| 127 | static void eraseFromParentDefault(Instruction *I) { I->eraseFromParent(); } |
| 128 | |
| 129 | /// Replace an instruction's uses with a value using our replacer. |
| 130 | void replaceAllUsesWith(Instruction *I, Value *With); |
| 131 | |
| 132 | /// Erase an instruction from its parent with our eraser. |
| 133 | void eraseFromParent(Instruction *I); |
| 134 | |
| 135 | /// Replace an instruction with a value and erase it from its parent. |
| 136 | void substituteInParent(Instruction *I, Value *With) { |
| 137 | replaceAllUsesWith(I, With); |
| 138 | eraseFromParent(I); |
| 139 | } |
| 140 | |
| 141 | public: |
| 142 | LibCallSimplifier( |
| 143 | const DataLayout &DL, const TargetLibraryInfo *TLI, DominatorTree *DT, |
| 144 | DomConditionCache *DC, AssumptionCache *AC, |
| 145 | OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, |
| 146 | ProfileSummaryInfo *PSI, |
| 147 | function_ref<void(Instruction *, Value *)> Replacer = |
| 148 | &replaceAllUsesWithDefault, |
| 149 | function_ref<void(Instruction *)> Eraser = &eraseFromParentDefault); |
| 150 | |
| 151 | /// optimizeCall - Take the given call instruction and return a more |
| 152 | /// optimal value to replace the instruction with or 0 if a more |
| 153 | /// optimal form can't be found. Note that the returned value may |
| 154 | /// be equal to the instruction being optimized. In this case all |
| 155 | /// other instructions that use the given instruction were modified |
| 156 | /// and the given instruction is dead. |
| 157 | /// The call must not be an indirect call. |
| 158 | Value *optimizeCall(CallInst *CI, IRBuilderBase &B); |
| 159 | |
| 160 | private: |
| 161 | // String and Memory Library Call Optimizations |
| 162 | Value *optimizeStrCat(CallInst *CI, IRBuilderBase &B); |
| 163 | Value *optimizeStrNCat(CallInst *CI, IRBuilderBase &B); |
| 164 | Value *optimizeStrChr(CallInst *CI, IRBuilderBase &B); |
| 165 | Value *optimizeStrRChr(CallInst *CI, IRBuilderBase &B); |
| 166 | Value *optimizeStrCmp(CallInst *CI, IRBuilderBase &B); |
| 167 | Value *optimizeStrNCmp(CallInst *CI, IRBuilderBase &B); |
| 168 | Value *optimizeStrNDup(CallInst *CI, IRBuilderBase &B); |
| 169 | Value *optimizeStrCpy(CallInst *CI, IRBuilderBase &B); |
| 170 | Value *optimizeStpCpy(CallInst *CI, IRBuilderBase &B); |
| 171 | Value *optimizeStrLCpy(CallInst *CI, IRBuilderBase &B); |
| 172 | Value *optimizeStrNCpy(CallInst *CI, IRBuilderBase &B); |
| 173 | Value *optimizeStrLen(CallInst *CI, IRBuilderBase &B); |
| 174 | Value *optimizeStrNLen(CallInst *CI, IRBuilderBase &B); |
| 175 | Value *optimizeStrPBrk(CallInst *CI, IRBuilderBase &B); |
| 176 | Value *optimizeStrTo(CallInst *CI, IRBuilderBase &B); |
| 177 | Value *optimizeStrSpn(CallInst *CI, IRBuilderBase &B); |
| 178 | Value *optimizeStrCSpn(CallInst *CI, IRBuilderBase &B); |
| 179 | Value *optimizeStrStr(CallInst *CI, IRBuilderBase &B); |
| 180 | Value *optimizeMemChr(CallInst *CI, IRBuilderBase &B); |
| 181 | Value *optimizeMemRChr(CallInst *CI, IRBuilderBase &B); |
| 182 | Value *optimizeMemCmp(CallInst *CI, IRBuilderBase &B); |
| 183 | Value *optimizeBCmp(CallInst *CI, IRBuilderBase &B); |
| 184 | Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilderBase &B); |
| 185 | Value *optimizeMemCCpy(CallInst *CI, IRBuilderBase &B); |
| 186 | Value *optimizeMemPCpy(CallInst *CI, IRBuilderBase &B); |
| 187 | Value *optimizeMemCpy(CallInst *CI, IRBuilderBase &B); |
| 188 | Value *optimizeMemMove(CallInst *CI, IRBuilderBase &B); |
| 189 | Value *optimizeMemSet(CallInst *CI, IRBuilderBase &B); |
| 190 | Value *optimizeRealloc(CallInst *CI, IRBuilderBase &B); |
| 191 | Value *optimizeNew(CallInst *CI, IRBuilderBase &B, LibFunc &Func); |
| 192 | Value *maybeOptimizeNoBuiltinOperatorNew(CallInst *CI, IRBuilderBase &B); |
| 193 | Value *optimizeWcslen(CallInst *CI, IRBuilderBase &B); |
| 194 | Value *optimizeBCopy(CallInst *CI, IRBuilderBase &B); |
| 195 | |
| 196 | // Helper to optimize stpncpy and strncpy. |
| 197 | Value *optimizeStringNCpy(CallInst *CI, bool RetEnd, IRBuilderBase &B); |
| 198 | // Wrapper for all String/Memory Library Call Optimizations |
| 199 | Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilderBase &B); |
| 200 | |
| 201 | // Math Library Optimizations |
| 202 | Value *optimizeCAbs(CallInst *CI, IRBuilderBase &B); |
| 203 | Value *optimizePow(CallInst *CI, IRBuilderBase &B); |
| 204 | Value *replacePowWithExp(CallInst *Pow, IRBuilderBase &B); |
| 205 | Value *replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B); |
| 206 | Value *optimizeExp2(CallInst *CI, IRBuilderBase &B); |
| 207 | Value *optimizeFMinFMax(CallInst *CI, IRBuilderBase &B); |
| 208 | Value *optimizeFMinimumnumFMaximumnum(CallInst *CI, IRBuilderBase &B); |
| 209 | Value *optimizeLog(CallInst *CI, IRBuilderBase &B); |
| 210 | Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B); |
| 211 | Value *optimizeFMod(CallInst *CI, IRBuilderBase &B); |
| 212 | Value *mergeSqrtToExp(CallInst *CI, IRBuilderBase &B); |
| 213 | Value *optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B); |
| 214 | Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B); |
| 215 | Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B); |
| 216 | Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B); |
| 217 | Value *optimizeFdim(CallInst *CI, IRBuilderBase &B); |
| 218 | // Wrapper for all floating point library call optimizations |
| 219 | Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func, |
| 220 | IRBuilderBase &B); |
| 221 | |
| 222 | // Integer Library Call Optimizations |
| 223 | Value *optimizeFFS(CallInst *CI, IRBuilderBase &B); |
| 224 | Value *optimizeFls(CallInst *CI, IRBuilderBase &B); |
| 225 | Value *optimizeAbs(CallInst *CI, IRBuilderBase &B); |
| 226 | Value *optimizeIsDigit(CallInst *CI, IRBuilderBase &B); |
| 227 | Value *optimizeIsAscii(CallInst *CI, IRBuilderBase &B); |
| 228 | Value *optimizeToAscii(CallInst *CI, IRBuilderBase &B); |
| 229 | Value *optimizeAtoi(CallInst *CI, IRBuilderBase &B); |
| 230 | Value *optimizeStrToInt(CallInst *CI, IRBuilderBase &B, bool AsSigned); |
| 231 | |
| 232 | // Formatting and IO Library Call Optimizations |
| 233 | Value *optimizeErrorReporting(CallInst *CI, IRBuilderBase &B, |
| 234 | int StreamArg = -1); |
| 235 | Value *optimizePrintF(CallInst *CI, IRBuilderBase &B); |
| 236 | Value *optimizeSPrintF(CallInst *CI, IRBuilderBase &B); |
| 237 | Value *optimizeSnPrintF(CallInst *CI, IRBuilderBase &B); |
| 238 | Value *optimizeFPrintF(CallInst *CI, IRBuilderBase &B); |
| 239 | Value *optimizeFWrite(CallInst *CI, IRBuilderBase &B); |
| 240 | Value *optimizeFPuts(CallInst *CI, IRBuilderBase &B); |
| 241 | Value *optimizePuts(CallInst *CI, IRBuilderBase &B); |
| 242 | |
| 243 | // Helper methods |
| 244 | Value* emitSnPrintfMemCpy(CallInst *CI, Value *StrArg, StringRef Str, |
| 245 | uint64_t N, IRBuilderBase &B); |
| 246 | Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, |
| 247 | IRBuilderBase &B); |
| 248 | void classifyArgUse(Value *Val, Function *F, bool IsFloat, |
| 249 | SmallVectorImpl<CallInst *> &SinCalls, |
| 250 | SmallVectorImpl<CallInst *> &CosCalls, |
| 251 | SmallVectorImpl<CallInst *> &SinCosCalls); |
| 252 | Value *optimizePrintFString(CallInst *CI, IRBuilderBase &B); |
| 253 | Value *optimizeSPrintFString(CallInst *CI, IRBuilderBase &B); |
| 254 | Value *optimizeSnPrintFString(CallInst *CI, IRBuilderBase &B); |
| 255 | Value *optimizeFPrintFString(CallInst *CI, IRBuilderBase &B); |
| 256 | |
| 257 | /// Exit functions |
| 258 | Value *optimizeExit(CallInst *CI); |
| 259 | |
| 260 | /// hasFloatVersion - Checks if there is a float version of the specified |
| 261 | /// function by checking for an existing function with name FuncName + f |
| 262 | bool hasFloatVersion(const Module *M, StringRef FuncName); |
| 263 | |
| 264 | /// Shared code to optimize strlen+wcslen and strnlen+wcsnlen. |
| 265 | Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B, unsigned CharSize, |
| 266 | Value *Bound = nullptr); |
| 267 | }; |
| 268 | } // End llvm namespace |
| 269 | |
| 270 | #endif |
| 271 | |