mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Add strpbrk folding to SimplifyLibCalls.
llvm-svn: 115111
This commit is contained in:
parent
711a5e60fa
commit
476bfb7a10
@ -522,6 +522,46 @@ struct StrLenOpt : public LibCallOptimization {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'strpbrk' Optimizations
|
||||
|
||||
struct StrPBrkOpt : public LibCallOptimization {
|
||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||
const FunctionType *FT = Callee->getFunctionType();
|
||||
if (FT->getNumParams() != 2 ||
|
||||
FT->getParamType(0) != Type::getInt8PtrTy(*Context) ||
|
||||
FT->getParamType(1) != FT->getParamType(0) ||
|
||||
FT->getReturnType() != FT->getParamType(0))
|
||||
return 0;
|
||||
|
||||
std::string S1, S2;
|
||||
bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1);
|
||||
bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2);
|
||||
|
||||
// strpbrk(s, "") -> NULL
|
||||
// strpbrk("", s) -> NULL
|
||||
if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
|
||||
return Constant::getNullValue(CI->getType());
|
||||
|
||||
// Constant folding.
|
||||
if (HasS1 && HasS2) {
|
||||
size_t I = S1.find_first_of(S2);
|
||||
if (I == std::string::npos) // No match.
|
||||
return Constant::getNullValue(CI->getType());
|
||||
|
||||
Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), I);
|
||||
return B.CreateGEP(CI->getArgOperand(0), Idx, "strpbrk");
|
||||
}
|
||||
|
||||
// strpbrk(s, "a") -> strchr(s, 'a')
|
||||
if (TD && HasS2 && S2.size() == 1)
|
||||
return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'strto*' Optimizations. This handles strtol, strtod, strtof, strtoul, etc.
|
||||
|
||||
@ -1256,7 +1296,7 @@ namespace {
|
||||
// String and Memory LibCall Optimizations
|
||||
StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrRChrOpt StrRChr;
|
||||
StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrCpyOpt StrCpyChk;
|
||||
StrNCpyOpt StrNCpy; StrLenOpt StrLen;
|
||||
StrNCpyOpt StrNCpy; StrLenOpt StrLen; StrPBrkOpt StrPBrk;
|
||||
StrToOpt StrTo; StrStrOpt StrStr;
|
||||
MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
|
||||
// Math Library Optimizations
|
||||
@ -1309,6 +1349,7 @@ void SimplifyLibCalls::InitOptimizations() {
|
||||
Optimizations["strcpy"] = &StrCpy;
|
||||
Optimizations["strncpy"] = &StrNCpy;
|
||||
Optimizations["strlen"] = &StrLen;
|
||||
Optimizations["strpbrk"] = &StrPBrk;
|
||||
Optimizations["strtol"] = &StrTo;
|
||||
Optimizations["strtod"] = &StrTo;
|
||||
Optimizations["strtof"] = &StrTo;
|
||||
@ -2209,12 +2250,6 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
|
||||
// * stpcpy(str, "literal") ->
|
||||
// llvm.memcpy(str,"literal",strlen("literal")+1,1)
|
||||
//
|
||||
// strpbrk:
|
||||
// * strpbrk(s,a) -> offset_in_for(s,a)
|
||||
// (if s and a are both constant strings)
|
||||
// * strpbrk(s,"") -> 0
|
||||
// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
|
||||
//
|
||||
// strspn, strcspn:
|
||||
// * strspn(s,a) -> const_int (if both args are constant)
|
||||
// * strspn("",a) -> 0
|
||||
|
25
test/Transforms/SimplifyLibCalls/StrPBrk.ll
Normal file
25
test/Transforms/SimplifyLibCalls/StrPBrk.ll
Normal file
@ -0,0 +1,25 @@
|
||||
; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
|
||||
|
||||
target datalayout = "-p:64:64:64"
|
||||
|
||||
@hello = constant [12 x i8] c"hello world\00"
|
||||
@w = constant [2 x i8] c"w\00"
|
||||
@null = constant [1 x i8] zeroinitializer
|
||||
|
||||
declare i8* @strpbrk(i8*, i8*)
|
||||
|
||||
define void @test(i8* %s1, i8* %s2) {
|
||||
%hello_p = getelementptr [12 x i8]* @hello, i32 0, i32 0
|
||||
%w_p = getelementptr [2 x i8]* @w, i32 0, i32 0
|
||||
%null_p = getelementptr [1 x i8]* @null, i32 0, i32 0
|
||||
%test1 = call i8* @strpbrk(i8* %null_p, i8* %s2)
|
||||
%test2 = call i8* @strpbrk(i8* %s1, i8* %null_p)
|
||||
; CHECK-NOT: call i8* @strpbrk
|
||||
%test3 = call i8* @strpbrk(i8* %s1, i8* %w_p)
|
||||
; CHECK: call i8* @strchr(i8* %s1, i32 119)
|
||||
%test4 = call i8* @strpbrk(i8* %hello_p, i8* %w_p)
|
||||
; CHECK: getelementptr i8* %hello_p, i64 6
|
||||
%test5 = call i8* @strpbrk(i8* %s1, i8* %s2)
|
||||
; CHECK: call i8* @strpbrk(i8* %s1, i8* %s2)
|
||||
ret void
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user