File: CodeGenTest.cpp

package info (click to toggle)
llvm-toolchain-15 1%3A15.0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,554,644 kB
  • sloc: cpp: 5,922,452; ansic: 1,012,136; asm: 674,362; python: 191,568; objc: 73,855; f90: 42,327; lisp: 31,913; pascal: 11,973; javascript: 10,144; sh: 9,421; perl: 7,447; ml: 5,527; awk: 3,523; makefile: 2,520; xml: 885; cs: 573; fortran: 567
file content (224 lines) | stat: -rw-r--r-- 9,930 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//===-- Automemcpy CodeGen Test -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "automemcpy/CodeGen.h"
#include "automemcpy/RandomFunctionGenerator.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using testing::AllOf;
using testing::AnyOf;
using testing::ElementsAre;
using testing::Ge;
using testing::Gt;
using testing::Le;
using testing::Lt;

namespace llvm {
namespace automemcpy {
namespace {

TEST(Automemcpy, Codegen) {
  static constexpr FunctionDescriptor kDescriptors[] = {
      {FunctionType::MEMCPY, llvm::None, llvm::None, llvm::None, llvm::None,
       Accelerator{{0, kMaxSize}}, ElementTypeClass::NATIVE},
      {FunctionType::MEMCPY, Contiguous{{0, 4}}, Overlap{{4, 256}},
       Loop{{256, kMaxSize}, 64}, llvm::None, llvm::None,
       ElementTypeClass::NATIVE},
      {FunctionType::MEMCMP, Contiguous{{0, 2}}, Overlap{{2, 64}}, llvm::None,
       AlignedLoop{Loop{{64, kMaxSize}, 16}, 16, AlignArg::_1}, llvm::None,
       ElementTypeClass::NATIVE},
      {FunctionType::MEMSET, Contiguous{{0, 2}}, Overlap{{2, 256}}, llvm::None,
       AlignedLoop{Loop{{256, kMaxSize}, 32}, 16, AlignArg::_1}, llvm::None,
       ElementTypeClass::NATIVE},
      {FunctionType::MEMSET, Contiguous{{0, 2}}, Overlap{{2, 256}}, llvm::None,
       AlignedLoop{Loop{{256, kMaxSize}, 32}, 32, AlignArg::_1}, llvm::None,
       ElementTypeClass::NATIVE},
      {FunctionType::BZERO, Contiguous{{0, 4}}, Overlap{{4, 128}}, llvm::None,
       AlignedLoop{Loop{{128, kMaxSize}, 32}, 32, AlignArg::_1}, llvm::None,
       ElementTypeClass::NATIVE},
  };

  std::string Output;
  raw_string_ostream OutputStream(Output);
  Serialize(OutputStream, kDescriptors);

  EXPECT_STREQ(OutputStream.str().c_str(),
               R"(// This file is auto-generated by libc/benchmarks/automemcpy.
// Functions : 6

#include "LibcFunctionPrototypes.h"
#include "automemcpy/FunctionDescriptor.h"
#include "src/string/memory_utils/elements.h"

using llvm::libc_benchmarks::BzeroConfiguration;
using llvm::libc_benchmarks::MemcmpOrBcmpConfiguration;
using llvm::libc_benchmarks::MemcpyConfiguration;
using llvm::libc_benchmarks::MemmoveConfiguration;
using llvm::libc_benchmarks::MemsetConfiguration;

namespace __llvm_libc {

static void memcpy_0xE00E29EE73994E2B(char *__restrict dst, const char *__restrict src, size_t size) {
  using namespace __llvm_libc::x86;
  return copy<Accelerator>(dst, src, size);
}
static void memcpy_0x7381B60C7BE75EF9(char *__restrict dst, const char *__restrict src, size_t size) {
  using namespace __llvm_libc::x86;
  if(size == 0) return;
  if(size == 1) return copy<_1>(dst, src);
  if(size == 2) return copy<_2>(dst, src);
  if(size == 3) return copy<_3>(dst, src);
  if(size < 8) return copy<HeadTail<_4>>(dst, src, size);
  if(size < 16) return copy<HeadTail<_8>>(dst, src, size);
  if(size < 32) return copy<HeadTail<_16>>(dst, src, size);
  if(size < 64) return copy<HeadTail<_32>>(dst, src, size);
  if(size < 128) return copy<HeadTail<_64>>(dst, src, size);
  if(size < 256) return copy<HeadTail<_128>>(dst, src, size);
  return copy<Loop<_64>>(dst, src, size);
}
static int memcmp_0x348D7BA6DB0EE033(const char * lhs, const char * rhs, size_t size) {
  using namespace __llvm_libc::x86;
  if(size == 0) return 0;
  if(size == 1) return three_way_compare<_1>(lhs, rhs);
  if(size < 4) return three_way_compare<HeadTail<_2>>(lhs, rhs, size);
  if(size < 8) return three_way_compare<HeadTail<_4>>(lhs, rhs, size);
  if(size < 16) return three_way_compare<HeadTail<_8>>(lhs, rhs, size);
  if(size < 32) return three_way_compare<HeadTail<_16>>(lhs, rhs, size);
  if(size < 64) return three_way_compare<HeadTail<_32>>(lhs, rhs, size);
  return three_way_compare<Align<_16,Arg::Lhs>::Then<Loop<_16>>>(lhs, rhs, size);
}
static void memset_0x71E761699B999863(char * dst, int value, size_t size) {
  using namespace __llvm_libc::x86;
  if(size == 0) return;
  if(size == 1) return splat_set<_1>(dst, value);
  if(size < 4) return splat_set<HeadTail<_2>>(dst, value, size);
  if(size < 8) return splat_set<HeadTail<_4>>(dst, value, size);
  if(size < 16) return splat_set<HeadTail<_8>>(dst, value, size);
  if(size < 32) return splat_set<HeadTail<_16>>(dst, value, size);
  if(size < 64) return splat_set<HeadTail<_32>>(dst, value, size);
  if(size < 128) return splat_set<HeadTail<_64>>(dst, value, size);
  if(size < 256) return splat_set<HeadTail<_128>>(dst, value, size);
  return splat_set<Align<_16,Arg::Dst>::Then<Loop<_32>>>(dst, value, size);
}
static void memset_0x3DF0F44E2ED6A50F(char * dst, int value, size_t size) {
  using namespace __llvm_libc::x86;
  if(size == 0) return;
  if(size == 1) return splat_set<_1>(dst, value);
  if(size < 4) return splat_set<HeadTail<_2>>(dst, value, size);
  if(size < 8) return splat_set<HeadTail<_4>>(dst, value, size);
  if(size < 16) return splat_set<HeadTail<_8>>(dst, value, size);
  if(size < 32) return splat_set<HeadTail<_16>>(dst, value, size);
  if(size < 64) return splat_set<HeadTail<_32>>(dst, value, size);
  if(size < 128) return splat_set<HeadTail<_64>>(dst, value, size);
  if(size < 256) return splat_set<HeadTail<_128>>(dst, value, size);
  return splat_set<Align<_32,Arg::Dst>::Then<Loop<_32>>>(dst, value, size);
}
static void bzero_0x475977492C218AD4(char * dst, size_t size) {
  using namespace __llvm_libc::x86;
  if(size == 0) return;
  if(size == 1) return splat_set<_1>(dst, 0);
  if(size == 2) return splat_set<_2>(dst, 0);
  if(size == 3) return splat_set<_3>(dst, 0);
  if(size < 8) return splat_set<HeadTail<_4>>(dst, 0, size);
  if(size < 16) return splat_set<HeadTail<_8>>(dst, 0, size);
  if(size < 32) return splat_set<HeadTail<_16>>(dst, 0, size);
  if(size < 64) return splat_set<HeadTail<_32>>(dst, 0, size);
  if(size < 128) return splat_set<HeadTail<_64>>(dst, 0, size);
  return splat_set<Align<_32,Arg::Dst>::Then<Loop<_32>>>(dst, 0, size);
}

} // namespace __llvm_libc

namespace llvm {
namespace automemcpy {

ArrayRef<NamedFunctionDescriptor> getFunctionDescriptors() {
  static constexpr NamedFunctionDescriptor kDescriptors[] = {
    {"memcpy_0xE00E29EE73994E2B",{FunctionType::MEMCPY,llvm::None,llvm::None,llvm::None,llvm::None,Accelerator{{0,kMaxSize}},ElementTypeClass::NATIVE}},
    {"memcpy_0x7381B60C7BE75EF9",{FunctionType::MEMCPY,Contiguous{{0,4}},Overlap{{4,256}},Loop{{256,kMaxSize},64},llvm::None,llvm::None,ElementTypeClass::NATIVE}},
    {"memcmp_0x348D7BA6DB0EE033",{FunctionType::MEMCMP,Contiguous{{0,2}},Overlap{{2,64}},llvm::None,AlignedLoop{Loop{{64,kMaxSize},16},16,AlignArg::_1},llvm::None,ElementTypeClass::NATIVE}},
    {"memset_0x71E761699B999863",{FunctionType::MEMSET,Contiguous{{0,2}},Overlap{{2,256}},llvm::None,AlignedLoop{Loop{{256,kMaxSize},32},16,AlignArg::_1},llvm::None,ElementTypeClass::NATIVE}},
    {"memset_0x3DF0F44E2ED6A50F",{FunctionType::MEMSET,Contiguous{{0,2}},Overlap{{2,256}},llvm::None,AlignedLoop{Loop{{256,kMaxSize},32},32,AlignArg::_1},llvm::None,ElementTypeClass::NATIVE}},
    {"bzero_0x475977492C218AD4",{FunctionType::BZERO,Contiguous{{0,4}},Overlap{{4,128}},llvm::None,AlignedLoop{Loop{{128,kMaxSize},32},32,AlignArg::_1},llvm::None,ElementTypeClass::NATIVE}},
  };
  return makeArrayRef(kDescriptors);
}

} // namespace automemcpy
} // namespace llvm


using MemcpyStub = void (*)(char *__restrict, const char *__restrict, size_t);
template <MemcpyStub Foo>
void *Wrap(void *__restrict dst, const void *__restrict src, size_t size) {
  Foo(reinterpret_cast<char *__restrict>(dst),
      reinterpret_cast<const char *__restrict>(src), size);
  return dst;
}
llvm::ArrayRef<MemcpyConfiguration> getMemcpyConfigurations() {
  using namespace __llvm_libc;
  static constexpr MemcpyConfiguration kConfigurations[] = {
    {Wrap<memcpy_0xE00E29EE73994E2B>, "memcpy_0xE00E29EE73994E2B"},
    {Wrap<memcpy_0x7381B60C7BE75EF9>, "memcpy_0x7381B60C7BE75EF9"},
  };
  return llvm::makeArrayRef(kConfigurations);
}

using MemcmpStub = int (*)(const char *, const char *, size_t);
template <MemcmpStub Foo>
int Wrap(const void *lhs, const void *rhs, size_t size) {
  return Foo(reinterpret_cast<const char *>(lhs),
             reinterpret_cast<const char *>(rhs), size);
}
llvm::ArrayRef<MemcmpOrBcmpConfiguration> getMemcmpConfigurations() {
  using namespace __llvm_libc;
  static constexpr MemcmpOrBcmpConfiguration kConfigurations[] = {
    {Wrap<memcmp_0x348D7BA6DB0EE033>, "memcmp_0x348D7BA6DB0EE033"},
  };
  return llvm::makeArrayRef(kConfigurations);
}
llvm::ArrayRef<MemcmpOrBcmpConfiguration> getBcmpConfigurations() {
  return {};
}

using MemsetStub = void (*)(char *, int, size_t);
template <MemsetStub Foo> void *Wrap(void *dst, int value, size_t size) {
  Foo(reinterpret_cast<char *>(dst), value, size);
  return dst;
}
llvm::ArrayRef<MemsetConfiguration> getMemsetConfigurations() {
  using namespace __llvm_libc;
  static constexpr MemsetConfiguration kConfigurations[] = {
    {Wrap<memset_0x71E761699B999863>, "memset_0x71E761699B999863"},
    {Wrap<memset_0x3DF0F44E2ED6A50F>, "memset_0x3DF0F44E2ED6A50F"},
  };
  return llvm::makeArrayRef(kConfigurations);
}

using BzeroStub = void (*)(char *, size_t);
template <BzeroStub Foo> void Wrap(void *dst, size_t size) {
  Foo(reinterpret_cast<char *>(dst), size);
}
llvm::ArrayRef<BzeroConfiguration> getBzeroConfigurations() {
  using namespace __llvm_libc;
  static constexpr BzeroConfiguration kConfigurations[] = {
    {Wrap<bzero_0x475977492C218AD4>, "bzero_0x475977492C218AD4"},
  };
  return llvm::makeArrayRef(kConfigurations);
}

llvm::ArrayRef<MemmoveConfiguration> getMemmoveConfigurations() {
  return {};
}
// Functions : 6
)");
}
} // namespace
} // namespace automemcpy
} // namespace llvm