mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
On strtod and friends, mark 'endptr' nocapture in the function prototype, and
mark the first argument nocapture if endptr=NULL for each particular call. llvm-svn: 64453
This commit is contained in:
parent
ed1ea7cfe8
commit
7ec551cfad
@ -721,6 +721,26 @@ struct VISIBILITY_HIDDEN StrLenOpt : public LibCallOptimization {
|
||||
}
|
||||
};
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'strto*' Optimizations
|
||||
|
||||
struct VISIBILITY_HIDDEN StrToOpt : public LibCallOptimization {
|
||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||
const FunctionType *FT = Callee->getFunctionType();
|
||||
if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
|
||||
!isa<PointerType>(FT->getParamType(0)) ||
|
||||
!isa<PointerType>(FT->getParamType(1)))
|
||||
return 0;
|
||||
|
||||
Value *EndPtr = CI->getOperand(2);
|
||||
if (isa<ConstantPointerNull>(EndPtr))
|
||||
CI->addAttribute(1, Attribute::NoCapture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'memcmp' Optimizations
|
||||
|
||||
@ -1329,8 +1349,8 @@ namespace {
|
||||
ExitOpt Exit;
|
||||
// String and Memory LibCall Optimizations
|
||||
StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
|
||||
StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt MemCpy;
|
||||
MemMoveOpt MemMove; MemSetOpt MemSet;
|
||||
StrCpyOpt StrCpy; StrLenOpt StrLen; StrToOpt StrTo; MemCmpOpt MemCmp;
|
||||
MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
|
||||
// Math Library Optimizations
|
||||
PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
|
||||
// Integer Optimizations
|
||||
@ -1383,6 +1403,13 @@ void SimplifyLibCalls::InitOptimizations() {
|
||||
Optimizations["strncmp"] = &StrNCmp;
|
||||
Optimizations["strcpy"] = &StrCpy;
|
||||
Optimizations["strlen"] = &StrLen;
|
||||
Optimizations["strtol"] = &StrTo;
|
||||
Optimizations["strtod"] = &StrTo;
|
||||
Optimizations["strtof"] = &StrTo;
|
||||
Optimizations["strtoul"] = &StrTo;
|
||||
Optimizations["strtoll"] = &StrTo;
|
||||
Optimizations["strtold"] = &StrTo;
|
||||
Optimizations["strtoull"] = &StrTo;
|
||||
Optimizations["memcmp"] = &MemCmp;
|
||||
Optimizations["memcpy"] = &MemCpy;
|
||||
Optimizations["memmove"] = &MemMove;
|
||||
@ -1566,8 +1593,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
|
||||
} else if ((NameLen == 6 && !strcmp(NameStr, "strcpy")) ||
|
||||
(NameLen == 6 && !strcmp(NameStr, "stpcpy")) ||
|
||||
(NameLen == 6 && !strcmp(NameStr, "strcat")) ||
|
||||
(NameLen == 6 && !strcmp(NameStr, "strtol")) ||
|
||||
(NameLen == 6 && !strcmp(NameStr, "strtod")) ||
|
||||
(NameLen == 6 && !strcmp(NameStr, "strtof")) ||
|
||||
(NameLen == 7 && !strcmp(NameStr, "strtoul")) ||
|
||||
(NameLen == 7 && !strcmp(NameStr, "strtoll")) ||
|
||||
(NameLen == 7 && !strcmp(NameStr, "strtold")) ||
|
||||
(NameLen == 7 && !strcmp(NameStr, "strncat")) ||
|
||||
(NameLen == 7 && !strcmp(NameStr, "strncpy"))) {
|
||||
(NameLen == 7 && !strcmp(NameStr, "strncpy")) ||
|
||||
(NameLen == 8 && !strcmp(NameStr, "strtoull"))) {
|
||||
if (FTy->getNumParams() < 2 ||
|
||||
!isa<PointerType>(FTy->getParamType(1)))
|
||||
continue;
|
||||
|
13
test/Transforms/SimplifyLibCalls/2009-02-12-StrTo.ll
Normal file
13
test/Transforms/SimplifyLibCalls/2009-02-12-StrTo.ll
Normal file
@ -0,0 +1,13 @@
|
||||
; RUN: llvm-as < %s | opt -simplify-libcalls | llvm-dis > %t
|
||||
; RUN: grep nocapture %t | count 2
|
||||
; RUN: grep null %t | grep nocapture | count 1
|
||||
|
||||
; Test that we do add nocapture to the declaration, and to the second call only.
|
||||
|
||||
declare float @strtof(i8* %s, i8** %endptr, i32 %base)
|
||||
|
||||
define void @foo(i8* %x, i8** %endptr) {
|
||||
call float @strtof(i8* %x, i8** %endptr, i32 0)
|
||||
call float @strtof(i8* %x, i8** null, i32 0)
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user