[llvm-commits] [llvm] r168893 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyLibCalls.cpp lib/Transforms/Utils/SimplifyLibCalls.cpp test/Transforms/InstCombine/fprintf-1.ll test/Transforms/InstCombine/fputs-1.ll test/Transforms/SimplifyLibCalls/FPuts.ll
Nadav Rotem
nrotem at apple.com
Tue Mar 5 14:52:29 PST 2013
Hi Meador,
I am now working on improving the clang compile time and I ran into a severe compile time regression in InstCombine and I think that it is due to your LibCallOptimization changes. The problem is that InstCombiner::visitCallSite() calls LibCallSimplifier::initOptimizations(). InitOptimizations inserts dozens of function names into string map. It rehashes the map and allocates memory very often, and this initialization takes a long time. I am profiling a typical C++ programs that uses STL, and I see lots of functions don't do much beside calling other functions. I already optimized the memory allocation, but not the insertion into the StringMap. On my program, initOptimizations takes 13.5% of the execution time of InstCombine. I understand that we only initialize this data structure once per function, but many c++ programs have lots of small functions and the cost of initialization is still high. Can you please look into this problem ?
Thanks,
Nadav
On Nov 29, 2012, at 7:45 AM, Meador Inge <meadori at codesourcery.com> wrote:
> Author: meadori
> Date: Thu Nov 29 09:45:43 2012
> New Revision: 168893
>
> URL: http://llvm.org/viewvc/llvm-project?rev=168893&view=rev
> Log:
> instcombine: Migrate fputs optimizations
>
> This patch migrates the fputs optimizations from the simplify-libcalls
> pass into the instcombine library call simplifier.
>
> Added:
> llvm/trunk/test/Transforms/InstCombine/fputs-1.ll
> Removed:
> llvm/trunk/test/Transforms/SimplifyLibCalls/FPuts.ll
> Modified:
> llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
> llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
> llvm/trunk/test/Transforms/InstCombine/fprintf-1.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=168893&r1=168892&r2=168893&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Thu Nov 29 09:45:43 2012
> @@ -87,31 +87,6 @@
> //===----------------------------------------------------------------------===//
>
> //===---------------------------------------===//
> -// 'fputs' Optimizations
> -
> -struct FPutsOpt : public LibCallOptimization {
> - virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> - // These optimizations require DataLayout.
> - if (!TD) return 0;
> -
> - // Require two pointers. Also, we can't optimize if return value is used.
> - FunctionType *FT = Callee->getFunctionType();
> - if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
> - !FT->getParamType(1)->isPointerTy() ||
> - !CI->use_empty())
> - return 0;
> -
> - // fputs(s,F) --> fwrite(s,1,strlen(s),F)
> - uint64_t Len = GetStringLength(CI->getArgOperand(0));
> - if (!Len) return 0;
> - // Known to have no uses (see above).
> - return EmitFWrite(CI->getArgOperand(0),
> - ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
> - CI->getArgOperand(1), B, TD, TLI);
> - }
> -};
> -
> -//===---------------------------------------===//
> // 'puts' Optimizations
>
> struct PutsOpt : public LibCallOptimization {
> @@ -153,7 +128,6 @@
>
> StringMap<LibCallOptimization*> Optimizations;
> // Formatting and IO Optimizations
> - FPutsOpt FPuts;
> PutsOpt Puts;
>
> bool Modified; // This is only used by doInitialization.
> @@ -210,7 +184,6 @@
> /// we know.
> void SimplifyLibCalls::InitOptimizations() {
> // Formatting and IO Optimizations
> - AddOpt(LibFunc::fputs, &FPuts);
> Optimizations["puts"] = &Puts;
> }
>
>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=168893&r1=168892&r2=168893&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Thu Nov 29 09:45:43 2012
> @@ -1610,6 +1610,28 @@
> }
> };
>
> +struct FPutsOpt : public LibCallOptimization {
> + virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
> + // These optimizations require DataLayout.
> + if (!TD) return 0;
> +
> + // Require two pointers. Also, we can't optimize if return value is used.
> + FunctionType *FT = Callee->getFunctionType();
> + if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
> + !FT->getParamType(1)->isPointerTy() ||
> + !CI->use_empty())
> + return 0;
> +
> + // fputs(s,F) --> fwrite(s,1,strlen(s),F)
> + uint64_t Len = GetStringLength(CI->getArgOperand(0));
> + if (!Len) return 0;
> + // Known to have no uses (see above).
> + return EmitFWrite(CI->getArgOperand(0),
> + ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
> + CI->getArgOperand(1), B, TD, TLI);
> + }
> +};
> +
> } // End anonymous namespace.
>
> namespace llvm {
> @@ -1668,6 +1690,7 @@
> SPrintFOpt SPrintF;
> FPrintFOpt FPrintF;
> FWriteOpt FWrite;
> + FPutsOpt FPuts;
>
> void initOptimizations();
> void addOpt(LibFunc::Func F, LibCallOptimization* Opt);
> @@ -1795,6 +1818,7 @@
> addOpt(LibFunc::sprintf, &SPrintF);
> addOpt(LibFunc::fprintf, &FPrintF);
> addOpt(LibFunc::fwrite, &FWrite);
> + addOpt(LibFunc::fputs, &FPuts);
> }
>
> Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
>
> Modified: llvm/trunk/test/Transforms/InstCombine/fprintf-1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fprintf-1.ll?rev=168893&r1=168892&r2=168893&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/fprintf-1.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/fprintf-1.ll Thu Nov 29 09:45:43 2012
> @@ -38,13 +38,14 @@
> }
>
> ; Check fprintf(fp, "%s", str) -> fputs(str, fp).
> +; NOTE: The fputs simplifier simplifies this further to fwrite.
>
> define void @test_simplify3(%FILE* %fp) {
> ; CHECK: @test_simplify3
> %fmt = getelementptr [3 x i8]* @percent_s, i32 0, i32 0
> %str = getelementptr [13 x i8]* @hello_world, i32 0, i32 0
> call i32 (%FILE*, i8*, ...)* @fprintf(%FILE* %fp, i8* %fmt, i8* %str)
> -; CHECK-NEXT: call i32 @fputs(i8* getelementptr inbounds ([13 x i8]* @hello_world, i32 0, i32 0), %FILE* %fp)
> +; CHECK-NEXT: call i32 @fwrite(i8* getelementptr inbounds ([13 x i8]* @hello_world, i32 0, i32 0), i32 12, i32 1, %FILE* %fp)
> ret void
> ; CHECK-NEXT: ret void
> }
>
> Added: llvm/trunk/test/Transforms/InstCombine/fputs-1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fputs-1.ll?rev=168893&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/fputs-1.ll (added)
> +++ llvm/trunk/test/Transforms/InstCombine/fputs-1.ll Thu Nov 29 09:45:43 2012
> @@ -0,0 +1,43 @@
> +; Test that the fputs library call simplifier 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"
> +
> +%FILE = type { }
> +
> + at empty = constant [1 x i8] zeroinitializer
> + at A = constant [2 x i8] c"A\00"
> + at hello = constant [7 x i8] c"hello\0A\00"
> +
> +declare i32 @fputs(i8*, %FILE*)
> +
> +; Check fputs(str, fp) --> fwrite(str, 1, strlen(s), fp).
> +
> +define void @test_simplify1(%FILE* %fp) {
> +; CHECK: @test_simplify1
> + %str = getelementptr [1 x i8]* @empty, i32 0, i32 0
> + call i32 @fputs(i8* %str, %FILE* %fp)
> + ret void
> +; CHECK-NEXT: ret void
> +}
> +
> +; NOTE: The fwrite simplifier simplifies this further to fputc.
> +
> +define void @test_simplify2(%FILE* %fp) {
> +; CHECK: @test_simplify2
> + %str = getelementptr [2 x i8]* @A, i32 0, i32 0
> + call i32 @fputs(i8* %str, %FILE* %fp)
> +; CHECK-NEXT: call i32 @fputc(i32 65, %FILE* %fp)
> + ret void
> +; CHECK-NEXT: ret void
> +}
> +
> +define void @test_simplify3(%FILE* %fp) {
> +; CHECK: @test_simplify3
> + %str = getelementptr [7 x i8]* @hello, i32 0, i32 0
> + call i32 @fputs(i8* %str, %FILE* %fp)
> +; CHECK-NEXT: call i32 @fwrite(i8* getelementptr inbounds ([7 x i8]* @hello, i32 0, i32 0), i32 6, i32 1, %FILE* %fp)
> + ret void
> +; CHECK-NEXT: ret void
> +}
>
> Removed: llvm/trunk/test/Transforms/SimplifyLibCalls/FPuts.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/FPuts.ll?rev=168892&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/SimplifyLibCalls/FPuts.ll (original)
> +++ llvm/trunk/test/Transforms/SimplifyLibCalls/FPuts.ll (removed)
> @@ -1,30 +0,0 @@
> -; Test that the FPutsOptimizer works correctly
> -; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
> -
> -; This transformation requires the pointer size, as it assumes that size_t is
> -; the size of a pointer.
> -target datalayout = "p:64:64:64"
> -
> - %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i32, [52 x i8] }
> - %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
> - at stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=1]
> - at empty = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1]
> - at len1 = constant [2 x i8] c"A\00" ; <[2 x i8]*> [#uses=1]
> - at long = constant [7 x i8] c"hello\0A\00" ; <[7 x i8]*> [#uses=1]
> -
> -declare i32 @fputs(i8*, %struct._IO_FILE*)
> -
> -define i32 @main() {
> -; CHECK: define i32 @main() {
> -entry:
> - %out = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=3]
> - %s1 = getelementptr [1 x i8]* @empty, i32 0, i32 0 ; <i8*> [#uses=1]
> - %s2 = getelementptr [2 x i8]* @len1, i32 0, i32 0 ; <i8*> [#uses=1]
> - %s3 = getelementptr [7 x i8]* @long, i32 0, i32 0 ; <i8*> [#uses=1]
> - %a = call i32 @fputs( i8* %s1, %struct._IO_FILE* %out ) ; <i32> [#uses=0]
> - %b = call i32 @fputs( i8* %s2, %struct._IO_FILE* %out ) ; <i32> [#uses=0]
> - %c = call i32 @fputs( i8* %s3, %struct._IO_FILE* %out ) ; <i32> [#uses=0]
> - ret i32 0
> -
> -; CHECK-NOT: @fputs(
> -}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130305/a65c5db4/attachment.html>
More information about the llvm-commits
mailing list