1 // Copyright 2019 Google LLC
2 //
3 // This source code is licensed under the BSD-style license found in the
4 // LICENSE file in the root directory of this source tree.
5 
6 #pragma once
7 
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #if defined(_MSC_VER)
13   #include <malloc.h>
14 #elif !defined(__GNUC__)
15   #include <alloca.h>
16 #endif
17 
18 #include <xnnpack/common.h>
19 #include <xnnpack/params.h>
20 
21 
22 #if XNN_ARCH_WASM
23   #define XNN_ALLOCATION_ALIGNMENT 4
24 #elif (XNN_ARCH_X86 || XNN_ARCH_X86_64) && !XNN_PLATFORM_MOBILE
25   #define XNN_ALLOCATION_ALIGNMENT 64
26 #else
27   #define XNN_ALLOCATION_ALIGNMENT 16
28 #endif
29 
xnn_allocate_memory(size_t memory_size)30 inline static void* xnn_allocate_memory(size_t memory_size) {
31   return xnn_params.allocator.allocate(xnn_params.allocator.context, memory_size);
32 }
33 
xnn_allocate_zero_memory(size_t memory_size)34 inline static void* xnn_allocate_zero_memory(size_t memory_size) {
35   void* memory_pointer = xnn_params.allocator.allocate(xnn_params.allocator.context, memory_size);
36   if (memory_pointer != NULL) {
37     memset(memory_pointer, 0, memory_size);
38   }
39   return memory_pointer;
40 }
41 
xnn_reallocate_memory(void * memory_pointer,size_t memory_size)42 inline static void* xnn_reallocate_memory(void* memory_pointer, size_t memory_size) {
43   return xnn_params.allocator.reallocate(xnn_params.allocator.context, memory_pointer, memory_size);
44 }
45 
xnn_release_memory(void * memory_pointer)46 inline static void xnn_release_memory(void* memory_pointer) {
47   xnn_params.allocator.deallocate(xnn_params.allocator.context, memory_pointer);
48 }
49 
xnn_allocate_simd_memory(size_t memory_size)50 inline static void* xnn_allocate_simd_memory(size_t memory_size) {
51   return xnn_params.allocator.aligned_allocate(xnn_params.allocator.context, XNN_ALLOCATION_ALIGNMENT, memory_size);
52 }
53 
xnn_allocate_zero_simd_memory(size_t memory_size)54 inline static void* xnn_allocate_zero_simd_memory(size_t memory_size) {
55   void* memory_pointer = xnn_params.allocator.aligned_allocate(
56     xnn_params.allocator.context, XNN_ALLOCATION_ALIGNMENT, memory_size);
57   if (memory_pointer != NULL) {
58     memset(memory_pointer, 0, memory_size);
59   }
60   return memory_pointer;
61 }
62 
xnn_release_simd_memory(void * memory_pointer)63 inline static void xnn_release_simd_memory(void* memory_pointer) {
64   xnn_params.allocator.aligned_deallocate(xnn_params.allocator.context, memory_pointer);
65 }
66 
67 #if defined(__GNUC__) && defined(__BIGGEST_ALIGNMENT__) && (__BIGGEST_ALIGNMENT__ >= XNN_ALLOCATION_ALIGNMENT)
68   #define XNN_SIMD_ALLOCA(size) __builtin_alloca((size))
69 #elif (defined(__clang_major__) && (__clang_major__ >= 4)) || \
70     (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 7) && !defined(__INTEL_COMPILER))
71   #define XNN_SIMD_ALLOCA(size) __builtin_alloca_with_align((size), XNN_ALLOCATION_ALIGNMENT)
72 #elif defined(__GNUC__)
73   #define XNN_SIMD_ALLOCA(size) \
74     ((void*) ((((uintptr_t) __builtin_alloca((size) + XNN_ALLOCATION_ALIGNMENT)) | (XNN_ALLOCATION_ALIGNMENT - 1)) + 1))
75 #elif defined(_MSC_VER)
76   #define XNN_SIMD_ALLOCA(size) \
77     ((void*) ((((uintptr_t) _alloca((size) + XNN_ALLOCATION_ALIGNMENT)) | (XNN_ALLOCATION_ALIGNMENT - 1)) + 1))
78 #else
79   #define XNN_SIMD_ALLOCA(size) \
80     ((void*) ((((uintptr_t) alloca((size) + XNN_ALLOCATION_ALIGNMENT)) | (XNN_ALLOCATION_ALIGNMENT - 1)) + 1))
81 #endif
82