[libcxx-commits] [PATCH] D59999: Make it easier for the compiler to optimize `operator==(string, char*)`.
Samuel Benzaquen via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Mar 29 13:53:13 PDT 2019
sbenza added a comment.
Maybe the generated code would be better if `basic_string::compare` was being inlined, but the compiler chose not to do it. `char_traits::compare`, on the other hand is much smaller and easier to inline.
IR examples before and after this change: https://gcc.godbolt.org/z/0N90W2
For something like str=="".
Before:
define dso_local zeroext i1 @_Z5EmptyRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE(%"class.std::__1::basic_string"* dereferenceable(24)) local_unnamed_addr #0 personality i32 (...)* @__gxx_personality_v0 !dbg !918 {
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !927, metadata !DIExpression()), !dbg !928
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !929, metadata !DIExpression()) #4, !dbg !1031
call void @llvm.dbg.value(metadata i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0), metadata !936, metadata !DIExpression()) #4, !dbg !1033
call void @llvm.dbg.value(metadata i64 0, metadata !937, metadata !DIExpression()) #4, !dbg !1034
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !1035, metadata !DIExpression()) #4, !dbg !1152
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !1155, metadata !DIExpression()) #4, !dbg !1161
%2 = bitcast %"class.std::__1::basic_string"* %0 to i8*, !dbg !1163
%3 = load i8, i8* %2, align 8, !dbg !1163, !tbaa !1164
%4 = and i8 %3, 1, !dbg !1167
%5 = icmp eq i8 %4, 0, !dbg !1168
%6 = getelementptr inbounds %"class.std::__1::basic_string", %"class.std::__1::basic_string"* %0, i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, !dbg !1169
%7 = load i64, i64* %6, align 8, !dbg !1169
%8 = lshr i8 %3, 1, !dbg !1169
%9 = zext i8 %8 to i64, !dbg !1169
%10 = select i1 %5, i64 %9, i64 %7, !dbg !1169
%11 = icmp eq i64 %10, 0, !dbg !1170
br i1 %11, label %12, label %19, !dbg !1171
12: ; preds = %1
%13 = invoke i32 @_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEmmPKcm(%"class.std::__1::basic_string"* nonnull %0, i64 0, i64 -1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0), i64 0)
to label %14 unwind label %16, !dbg !1172
14: ; preds = %12
%15 = icmp eq i32 %13, 0, !dbg !1173
br label %19, !dbg !1174
16: ; preds = %12
%17 = landingpad { i8*, i32 }
catch i8* null, !dbg !1175
%18 = extractvalue { i8*, i32 } %17, 0, !dbg !1175
tail call void @__clang_call_terminate(i8* %18) #5, !dbg !1175
unreachable, !dbg !1175
19: ; preds = %1, %14
%20 = phi i1 [ %15, %14 ], [ false, %1 ], !dbg !1176
ret i1 %20, !dbg !1177
}
After:
define dso_local zeroext i1 @_Z5EmptyRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE(%"class.std::__1::basic_string"* nocapture readonly dereferenceable(24)) local_unnamed_addr #0 !dbg !918 {
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !927, metadata !DIExpression()), !dbg !928
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !929, metadata !DIExpression()) #3, !dbg !1031
call void @llvm.dbg.value(metadata i64 0, metadata !937, metadata !DIExpression()) #3, !dbg !1033
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !1034, metadata !DIExpression()) #3, !dbg !1151
call void @llvm.dbg.value(metadata %"class.std::__1::basic_string"* %0, metadata !1154, metadata !DIExpression()) #3, !dbg !1160
%2 = bitcast %"class.std::__1::basic_string"* %0 to i8*, !dbg !1162
%3 = load i8, i8* %2, align 8, !dbg !1162, !tbaa !1163
%4 = and i8 %3, 1, !dbg !1166
%5 = icmp eq i8 %4, 0, !dbg !1167
%6 = getelementptr inbounds %"class.std::__1::basic_string", %"class.std::__1::basic_string"* %0, i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, !dbg !1168
%7 = load i64, i64* %6, align 8, !dbg !1168
%8 = lshr i8 %3, 1, !dbg !1168
%9 = zext i8 %8 to i64, !dbg !1168
%10 = select i1 %5, i64 %9, i64 %7, !dbg !1168
%11 = icmp eq i64 %10, 0, !dbg !1169
ret i1 %11, !dbg !1170
}
Other simple comparisons like str=="ABCDEFG" get better too. (see link above).
I'm adding a few more benchmarks in https://reviews.llvm.org/D59781 that show the improvement.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59999/new/
https://reviews.llvm.org/D59999
More information about the libcxx-commits
mailing list