mirror of https://github.com/grpc/grpc.git
[metadata] Improve codegen for name lookups (#33237)
The approach of doing a recursive function call to expand the if checks for known metadata names was tripping up an optimization clang has to collapse that if/then tree into an optimized tree search over the set of known strings. By unrolling that loop (with a code generator) we start to present a pattern that clang *can* recognize, and hopefully get some more stable and faster code generation as a benefit. <!-- If you know who should review your pull request, please assign it to that person, otherwise the pull request would get assigned randomly. If your pull request is for a specific language, please add the appropriate lang label. --> --------- Co-authored-by: ctiller <ctiller@users.noreply.github.com>pull/33361/head
parent
683261d217
commit
1f85fb21f2
18 changed files with 4848 additions and 41 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@ |
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_LIB_GPRPP_TYPE_LIST_H |
||||
#define GRPC_SRC_CORE_LIB_GPRPP_TYPE_LIST_H |
||||
|
||||
namespace grpc_core { |
||||
|
||||
// A list of types
|
||||
template <typename... A> |
||||
struct Typelist { |
||||
template <template <typename...> class T> |
||||
using Instantiate = T<A...>; |
||||
|
||||
template <typename C> |
||||
using PushFront = Typelist<C, A...>; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_GPRPP_TYPE_LIST_H
|
@ -0,0 +1,37 @@ |
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/core/lib/gprpp/if_list.h" |
||||
|
||||
#include "gtest/gtest.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
TEST(IfListTest, Works) { |
||||
EXPECT_EQ(IfList( |
||||
0, 42, [](int) { return -1; }, [](int x) { return x == 0; }, |
||||
[](int x) { return x; }), |
||||
42); |
||||
EXPECT_EQ(IfList( |
||||
1, 42, [](int) { return -1; }, [](int x) { return x == 0; }, |
||||
[](int x) { return x; }), |
||||
-1); |
||||
} |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
@ -0,0 +1,76 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
# Copyright 2023 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
import sys |
||||
|
||||
|
||||
# utility: print a big comment block into a set of files |
||||
def put_banner(files, banner): |
||||
for f in files: |
||||
for line in banner: |
||||
print('// %s' % line, file=f) |
||||
print('', file=f) |
||||
|
||||
|
||||
with open('src/core/lib/gprpp/if_list.h', 'w') as H: |
||||
# copy-paste copyright notice from this file |
||||
with open(sys.argv[0]) as my_source: |
||||
copyright = [] |
||||
for line in my_source: |
||||
if line[0] != '#': |
||||
break |
||||
for line in my_source: |
||||
if line[0] == '#': |
||||
copyright.append(line) |
||||
break |
||||
for line in my_source: |
||||
if line[0] != '#': |
||||
break |
||||
copyright.append(line) |
||||
put_banner([H], [line[2:].rstrip() for line in copyright]) |
||||
|
||||
put_banner([H], ["", "Automatically generated by %s" % sys.argv[0], ""]) |
||||
|
||||
print("#ifndef GRPC_CORE_LIB_GPRPP_IF_LIST_H", file=H) |
||||
print("#define GRPC_CORE_LIB_GPRPP_IF_LIST_H", file=H) |
||||
print('', file=H) |
||||
print('#include <grpc/support/port_platform.h>', file=H) |
||||
print('', file=H) |
||||
print("#include <stdlib.h>", file=H) |
||||
print('', file=H) |
||||
print("namespace grpc_core {", file=H) |
||||
|
||||
for n in range(1, 64): |
||||
print('', file=H) |
||||
print( |
||||
"template <typename CheckArg, typename ActionArg, typename ActionFail, %s, %s> auto IfList(CheckArg input, ActionArg action_arg, ActionFail action_fail, %s, %s) {" |
||||
% ( |
||||
", ".join("typename Check%d" % (i) for i in range(0, n)), |
||||
", ".join("typename Action%d" % (i) for i in range(0, n)), |
||||
", ".join("Check%d check%d" % (i, i) for i in range(0, n)), |
||||
", ".join("Action%d action%d" % (i, i) for i in range(0, n)), |
||||
), |
||||
file=H) |
||||
for i in range(0, n): |
||||
print(" if (check%d(input)) return action%d(action_arg);" % (i, i), |
||||
file=H) |
||||
print(" return action_fail(action_arg);", file=H) |
||||
print("}", file=H) |
||||
|
||||
print('', file=H) |
||||
print("}", file=H) |
||||
print('', file=H) |
||||
print("#endif // GRPC_CORE_LIB_GPRPP_IF_LIST_H", file=H) |
Loading…
Reference in new issue