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