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