#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
namespace llvm {
class StringRef;
class Value;
class CallInst;
class DataLayout;
class Instruction;
class IRBuilderBase;
class Function;
class OptimizationRemarkEmitter;
class BlockFrequencyInfo;
class ProfileSummaryInfo;
class FortifiedLibCallSimplifier {
private:
const TargetLibraryInfo *TLI;
bool OnlyLowerUnknownSize;
public:
FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI,
bool OnlyLowerUnknownSize = false);
Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
Value *optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemMoveChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemSetChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrpCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
Value *optimizeStrLenChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemPCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeSNPrintfChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeSPrintfChk(CallInst *CI,IRBuilderBase &B);
Value *optimizeStrCatChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrLCat(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNCatChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrLCpyChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeVSNPrintfChk(CallInst *CI, IRBuilderBase &B);
Value *optimizeVSPrintfChk(CallInst *CI, IRBuilderBase &B);
bool isFortifiedCallFoldable(CallInst *CI, unsigned ObjSizeOp,
Optional<unsigned> SizeOp = None,
Optional<unsigned> StrOp = None,
Optional<unsigned> FlagsOp = None);
};
class LibCallSimplifier {
private:
FortifiedLibCallSimplifier FortifiedSimplifier;
const DataLayout &DL;
const TargetLibraryInfo *TLI;
OptimizationRemarkEmitter &ORE;
BlockFrequencyInfo *BFI;
ProfileSummaryInfo *PSI;
bool UnsafeFPShrink = false;
function_ref<void(Instruction *, Value *)> Replacer;
function_ref<void(Instruction *)> Eraser;
static void replaceAllUsesWithDefault(Instruction *I, Value *With) {
I->replaceAllUsesWith(With);
}
static void eraseFromParentDefault(Instruction *I) { I->eraseFromParent(); }
void replaceAllUsesWith(Instruction *I, Value *With);
void eraseFromParent(Instruction *I);
void substituteInParent(Instruction *I, Value *With) {
replaceAllUsesWith(I, With);
eraseFromParent(I);
}
public:
LibCallSimplifier(
const DataLayout &DL, const TargetLibraryInfo *TLI,
OptimizationRemarkEmitter &ORE,
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
function_ref<void(Instruction *, Value *)> Replacer =
&replaceAllUsesWithDefault,
function_ref<void(Instruction *)> Eraser = &eraseFromParentDefault);
Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
Value *optimizeStrCat(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNCat(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrChr(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrRChr(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrCmp(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNCmp(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNDup(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStpCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrLen(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrNLen(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrPBrk(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrTo(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrSpn(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrCSpn(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrStr(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemChr(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemRChr(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCmp(CallInst *CI, IRBuilderBase &B);
Value *optimizeBCmp(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemPCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemCpy(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemMove(CallInst *CI, IRBuilderBase &B);
Value *optimizeMemSet(CallInst *CI, IRBuilderBase &B);
Value *optimizeRealloc(CallInst *CI, IRBuilderBase &B);
Value *optimizeWcslen(CallInst *CI, IRBuilderBase &B);
Value *optimizeBCopy(CallInst *CI, IRBuilderBase &B);
Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilderBase &B);
Value *optimizeCAbs(CallInst *CI, IRBuilderBase &B);
Value *optimizePow(CallInst *CI, IRBuilderBase &B);
Value *replacePowWithExp(CallInst *Pow, IRBuilderBase &B);
Value *replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B);
Value *optimizeExp2(CallInst *CI, IRBuilderBase &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilderBase &B);
Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
Value *optimizeSinCosPi(CallInst *CI, IRBuilderBase &B);
Value *optimizeTan(CallInst *CI, IRBuilderBase &B);
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
IRBuilderBase &B);
Value *optimizeFFS(CallInst *CI, IRBuilderBase &B);
Value *optimizeFls(CallInst *CI, IRBuilderBase &B);
Value *optimizeAbs(CallInst *CI, IRBuilderBase &B);
Value *optimizeIsDigit(CallInst *CI, IRBuilderBase &B);
Value *optimizeIsAscii(CallInst *CI, IRBuilderBase &B);
Value *optimizeToAscii(CallInst *CI, IRBuilderBase &B);
Value *optimizeAtoi(CallInst *CI, IRBuilderBase &B);
Value *optimizeStrToInt(CallInst *CI, IRBuilderBase &B, bool AsSigned);
Value *optimizeErrorReporting(CallInst *CI, IRBuilderBase &B,
int StreamArg = -1);
Value *optimizePrintF(CallInst *CI, IRBuilderBase &B);
Value *optimizeSPrintF(CallInst *CI, IRBuilderBase &B);
Value *optimizeSnPrintF(CallInst *CI, IRBuilderBase &B);
Value *optimizeFPrintF(CallInst *CI, IRBuilderBase &B);
Value *optimizeFWrite(CallInst *CI, IRBuilderBase &B);
Value *optimizeFPuts(CallInst *CI, IRBuilderBase &B);
Value *optimizePuts(CallInst *CI, IRBuilderBase &B);
Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
IRBuilderBase &B);
void classifyArgUse(Value *Val, Function *F, bool IsFloat,
SmallVectorImpl<CallInst *> &SinCalls,
SmallVectorImpl<CallInst *> &CosCalls,
SmallVectorImpl<CallInst *> &SinCosCalls);
Value *optimizePrintFString(CallInst *CI, IRBuilderBase &B);
Value *optimizeSPrintFString(CallInst *CI, IRBuilderBase &B);
Value *optimizeSnPrintFString(CallInst *CI, IRBuilderBase &B);
Value *optimizeFPrintFString(CallInst *CI, IRBuilderBase &B);
bool hasFloatVersion(const Module *M, StringRef FuncName);
Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B, unsigned CharSize,
Value *Bound = nullptr);
};
}
#endif