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 |