[llvm] r176766 - TLI: Microoptimize calls to strlen+memcmp to strncmp.

Anton Yartsev anton.yartsev at gmail.com
Wed Mar 13 06:42:28 PDT 2013


Hi Benjamin,

I failed to compile Clang after this change. VS2008 complains:

1>------ Build started: Project: LLVMTarget, Configuration: Debug Win32 
------
1>Compiling...
1>TargetLibraryInfo.cpp
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\include\xutility(346) 
: error C2666: '`anonymous-namespace'::StringComparator::operator ()' : 
3 overloads have similar conversions
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(604): could be 'bool 
`anonymous-namespace'::StringComparator::operator ()(const char 
*,llvm::StringRef) const'
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(611): or       'bool 
`anonymous-namespace'::StringComparator::operator 
()(llvm::StringRef,const char *) const'
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(612): or       'bool 
`anonymous-namespace'::StringComparator::operator 
()(llvm::StringRef,llvm::StringRef) const'
1>        while trying to match the argument list '(const char *, const 
char *)'
1>        C:\Program Files\Microsoft Visual Studio 
9.0\VC\include\xutility(1699) : see reference to function template 
instantiation 'bool std::_Debug_lt_pred<_Pr,const char*,const 
char*>(_Pr,_Ty1 &,_Ty2 &,const wchar_t *,unsigned int)' being compiled
1>        with
1>        [
1>            _Pr=`anonymous-namespace'::StringComparator,
1>            _Ty1=const char *,
1>            _Ty2=const char *
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 
9.0\VC\include\xutility(1709) : see reference to function template 
instantiation 'void 
std::_Debug_order_single2<_InIt,_Pr>(_FwdIt,_FwdIt,_Pr,bool,const 
wchar_t *,unsigned int,std::forward_iterator_tag)' being compiled
1>        with
1>        [
1>            _InIt=const char **,
1>            _Pr=`anonymous-namespace'::StringComparator,
1>            _FwdIt=const char **
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 
9.0\VC\include\algorithm(2290) : see reference to function template 
instantiation 'void 
std::_Debug_order_single<_FwdIt,_Pr>(_InIt,_InIt,_Pr,bool,const wchar_t 
*,unsigned int)' being compiled
1>        with
1>        [
1>            _FwdIt=const char **,
1>            _Pr=`anonymous-namespace'::StringComparator,
1>            _InIt=const char **
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 
9.0\VC\include\algorithm(2314) : see reference to function template 
instantiation '_FwdIt std::_Lower_bound<const 
char**,_Ty,std::iterator_traits<_Iter>::difference_type,_Pr>(_FwdIt,_FwdIt,const 
_Ty &,_Pr,_Diff *)' being compiled
1>        with
1>        [
1>            _FwdIt=const char **,
1>            _Ty=llvm::StringRef,
1>            _Iter=const char **,
1>            _Pr=`anonymous-namespace'::StringComparator,
1>            _Diff=std::iterator_traits<const char **>::difference_type
1>        ]
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(630) : see reference 
to function template instantiation '_FwdIt std::lower_bound<const 
char**,llvm::StringRef,`anonymous-namespace'::StringComparator>(_FwdIt,_FwdIt,const 
_Ty &,_Pr)' being compiled
1>        with
1>        [
1>            _FwdIt=const char **,
1>            _Ty=llvm::StringRef,
1>            _Pr=`anonymous-namespace'::StringComparator
1>        ]
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\include\xutility(348) 
: error C2666: '`anonymous-namespace'::StringComparator::operator ()' : 
3 overloads have similar conversions
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(604): could be 'bool 
`anonymous-namespace'::StringComparator::operator ()(const char 
*,llvm::StringRef) const'
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(611): or       'bool 
`anonymous-namespace'::StringComparator::operator 
()(llvm::StringRef,const char *) const'
1>        ..\..\..\lib\Target\TargetLibraryInfo.cpp(612): or       'bool 
`anonymous-namespace'::StringComparator::operator 
()(llvm::StringRef,llvm::StringRef) const'
1>        while trying to match the argument list '(const char *, const 
char *)'
1>Build log was saved at 
"file://f:\llvm_COMMON\-VS_build-\lib\Target\LLVMTarget.dir\Debug\BuildLog.htm"
1>LLVMTarget - 2 error(s), 0 warning(s)

> Author: d0k
> Date: Sat Mar  9 07:48:23 2013
> New Revision: 176766
>
> URL: http://llvm.org/viewvc/llvm-project?rev=176766&view=rev
> Log:
> TLI: Microoptimize calls to strlen+memcmp to strncmp.
>
> The strlen+memcmp was hidden in a call to StringRef::operator==. We check if
> there are any null bytes in the string upfront so we can simplify the comparison
> Small speedup when compiling code with many function calls.
>
> Modified:
>      llvm/trunk/lib/Target/TargetLibraryInfo.cpp
>
> Modified: llvm/trunk/lib/Target/TargetLibraryInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLibraryInfo.cpp?rev=176766&r1=176765&r2=176766&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/TargetLibraryInfo.cpp (original)
> +++ llvm/trunk/lib/Target/TargetLibraryInfo.cpp Sat Mar  9 07:48:23 2013
> @@ -597,15 +597,37 @@ TargetLibraryInfo::TargetLibraryInfo(con
>     CustomNames = TLI.CustomNames;
>   }
>   
> +namespace {
> +struct StringComparator {
> +  /// Compare two strings and return true if LHS is lexicographically less than
> +  /// RHS. Requires that RHS doesn't contain any zero bytes.
> +  bool operator()(const char *LHS, StringRef RHS) const {
> +    // Compare prefixes with strncmp. If prefixes match we know that LHS is
> +    // greater or equal to RHS as RHS can't contain any '\0'.
> +    return std::strncmp(LHS, RHS.data(), RHS.size()) < 0;
> +  }
> +
> +  // Provided for compatibility with MSVC's debug mode.
> +  bool operator()(StringRef LHS, const char *RHS) const { return LHS < RHS; }
> +  bool operator()(StringRef LHS, StringRef RHS) const { return LHS < RHS; }
> +};
> +}
> +
>   bool TargetLibraryInfo::getLibFunc(StringRef funcName,
>                                      LibFunc::Func &F) const {
>     const char **Start = &StandardNames[0];
>     const char **End = &StandardNames[LibFunc::NumLibFuncs];
> +
> +  // Filter out empty names and names containing null bytes, those can't be in
> +  // our table.
> +  if (funcName.empty() || funcName.find('\0') != StringRef::npos)
> +    return false;
> +
>     // Check for \01 prefix that is used to mangle __asm declarations and
>     // strip it if present.
> -  if (!funcName.empty() && funcName.front() == '\01')
> +  if (funcName.front() == '\01')
>       funcName = funcName.substr(1);
> -  const char **I = std::lower_bound(Start, End, funcName);
> +  const char **I = std::lower_bound(Start, End, funcName, StringComparator());
>     if (I != End && *I == funcName) {
>       F = (LibFunc::Func)(I - Start);
>       return true;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


-- 
Anton




More information about the llvm-commits mailing list