mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
instcombine: Migrate strto* optimizations
This patch migrates the strto* optimizations from the simplify-libcalls pass into the instcombine library call simplifier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167119 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2857866138
commit
e0f1dca1c8
@ -118,29 +118,6 @@ static bool IsOnlyUsedInEqualityComparison(Value *V, Value *With) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
//===---------------------------------------===//
|
||||
// 'strto*' Optimizations. This handles strtol, strtod, strtof, strtoul, etc.
|
||||
|
||||
struct StrToOpt : public LibCallOptimization {
|
||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||
FunctionType *FT = Callee->getFunctionType();
|
||||
if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
|
||||
!FT->getParamType(0)->isPointerTy() ||
|
||||
!FT->getParamType(1)->isPointerTy())
|
||||
return 0;
|
||||
|
||||
Value *EndPtr = CI->getArgOperand(1);
|
||||
if (isa<ConstantPointerNull>(EndPtr)) {
|
||||
// With a null EndPtr, this function won't capture the main argument.
|
||||
// It would be readonly too, except that it still may write to errno.
|
||||
CI->addAttribute(1, Attributes::get(Callee->getContext(),
|
||||
Attributes::NoCapture));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===---------------------------------------===//
|
||||
// 'strspn' Optimizations
|
||||
|
||||
@ -1066,7 +1043,7 @@ namespace {
|
||||
|
||||
StringMap<LibCallOptimization*> Optimizations;
|
||||
// String and Memory LibCall Optimizations
|
||||
StrToOpt StrTo; StrSpnOpt StrSpn; StrCSpnOpt StrCSpn; StrStrOpt StrStr;
|
||||
StrSpnOpt StrSpn; StrCSpnOpt StrCSpn; StrStrOpt StrStr;
|
||||
MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
|
||||
// Math Library Optimizations
|
||||
CosOpt Cos; PowOpt Pow; Exp2Opt Exp2;
|
||||
@ -1134,13 +1111,6 @@ void SimplifyLibCalls::AddOpt(LibFunc::Func F1, LibFunc::Func F2,
|
||||
/// we know.
|
||||
void SimplifyLibCalls::InitOptimizations() {
|
||||
// String and Memory LibCall Optimizations
|
||||
Optimizations["strtol"] = &StrTo;
|
||||
Optimizations["strtod"] = &StrTo;
|
||||
Optimizations["strtof"] = &StrTo;
|
||||
Optimizations["strtoul"] = &StrTo;
|
||||
Optimizations["strtoll"] = &StrTo;
|
||||
Optimizations["strtold"] = &StrTo;
|
||||
Optimizations["strtoull"] = &StrTo;
|
||||
Optimizations["strspn"] = &StrSpn;
|
||||
Optimizations["strcspn"] = &StrCSpn;
|
||||
Optimizations["strstr"] = &StrStr;
|
||||
|
@ -752,6 +752,26 @@ struct StrPBrkOpt : public LibCallOptimization {
|
||||
}
|
||||
};
|
||||
|
||||
struct StrToOpt : public LibCallOptimization {
|
||||
virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
|
||||
FunctionType *FT = Callee->getFunctionType();
|
||||
if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
|
||||
!FT->getParamType(0)->isPointerTy() ||
|
||||
!FT->getParamType(1)->isPointerTy())
|
||||
return 0;
|
||||
|
||||
Value *EndPtr = CI->getArgOperand(1);
|
||||
if (isa<ConstantPointerNull>(EndPtr)) {
|
||||
// With a null EndPtr, this function won't capture the main argument.
|
||||
// It would be readonly too, except that it still may write to errno.
|
||||
CI->addAttribute(1, Attributes::get(Callee->getContext(),
|
||||
Attributes::NoCapture));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // End anonymous namespace.
|
||||
|
||||
namespace llvm {
|
||||
@ -781,6 +801,7 @@ class LibCallSimplifierImpl {
|
||||
StrNCpyOpt StrNCpy;
|
||||
StrLenOpt StrLen;
|
||||
StrPBrkOpt StrPBrk;
|
||||
StrToOpt StrTo;
|
||||
|
||||
void initOptimizations();
|
||||
public:
|
||||
@ -814,6 +835,13 @@ void LibCallSimplifierImpl::initOptimizations() {
|
||||
Optimizations["strncpy"] = &StrNCpy;
|
||||
Optimizations["strlen"] = &StrLen;
|
||||
Optimizations["strpbrk"] = &StrPBrk;
|
||||
Optimizations["strtol"] = &StrTo;
|
||||
Optimizations["strtod"] = &StrTo;
|
||||
Optimizations["strtof"] = &StrTo;
|
||||
Optimizations["strtoul"] = &StrTo;
|
||||
Optimizations["strtoll"] = &StrTo;
|
||||
Optimizations["strtold"] = &StrTo;
|
||||
Optimizations["strtoull"] = &StrTo;
|
||||
}
|
||||
|
||||
Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
|
||||
|
82
test/Transforms/InstCombine/strto-1.ll
Normal file
82
test/Transforms/InstCombine/strto-1.ll
Normal file
@ -0,0 +1,82 @@
|
||||
; Test that the strto* library call simplifiers works correctly.
|
||||
;
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
|
||||
declare i64 @strtol(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare i64 @strtol(i8*, i8**, i32)
|
||||
|
||||
declare double @strtod(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare double @strtod(i8*, i8**, i32)
|
||||
|
||||
declare float @strtof(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare float @strtof(i8*, i8**, i32)
|
||||
|
||||
declare i64 @strtoul(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare i64 @strtoul(i8*, i8**, i32)
|
||||
|
||||
declare i64 @strtoll(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare i64 @strtoll(i8*, i8**, i32)
|
||||
|
||||
declare double @strtold(i8* %s, i8** %endptr)
|
||||
; CHECK: declare double @strtold(i8*, i8**)
|
||||
|
||||
declare i64 @strtoull(i8* %s, i8** %endptr, i32 %base)
|
||||
; CHECK: declare i64 @strtoull(i8*, i8**, i32)
|
||||
|
||||
define void @test_simplify1(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify1
|
||||
call i64 @strtol(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call i64 @strtol(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify2(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify2
|
||||
call double @strtod(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call double @strtod(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify3(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify3
|
||||
call float @strtof(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call float @strtof(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify4(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify4
|
||||
call i64 @strtoul(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call i64 @strtoul(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify5(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify5
|
||||
call i64 @strtoll(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call i64 @strtoll(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify6(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify6
|
||||
call double @strtold(i8* %x, i8** null)
|
||||
; CHECK-NEXT: call double @strtold(i8* nocapture %x, i8** null)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_simplify7(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_simplify7
|
||||
call i64 @strtoull(i8* %x, i8** null, i32 10)
|
||||
; CHECK-NEXT: call i64 @strtoull(i8* nocapture %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_no_simplify1(i8* %x, i8** %endptr) {
|
||||
; CHECK: @test_no_simplify1
|
||||
call i64 @strtol(i8* %x, i8** %endptr, i32 10)
|
||||
; CHECK-NEXT: call i64 @strtol(i8* %x, i8** %endptr, i32 10)
|
||||
ret void
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
|
||||
|
||||
; Test that we add nocapture to the declaration, and to the second call only.
|
||||
|
||||
; CHECK: declare float @strtol(i8*, i8** nocapture, i32) nounwind
|
||||
declare float @strtol(i8* %s, i8** %endptr, i32 %base)
|
||||
|
||||
define void @foo(i8* %x, i8** %endptr) {
|
||||
; CHECK: call float @strtol(i8* %x, i8** %endptr, i32 10)
|
||||
call float @strtol(i8* %x, i8** %endptr, i32 10)
|
||||
; CHECK: %2 = call float @strtol(i8* nocapture %x, i8** null, i32 10)
|
||||
call float @strtol(i8* %x, i8** null, i32 10)
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user