225 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- 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
 |