1 | /******************************************************************************* |
2 | * Copyright 2020-2022 Intel Corporation |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | *******************************************************************************/ |
16 | |
17 | #ifndef CPU_X64_JIT_INJECTOR_UTILS_HPP |
18 | #define CPU_X64_JIT_INJECTOR_UTILS_HPP |
19 | |
20 | #include <array> |
21 | #include <cstddef> |
22 | #include <set> |
23 | #include <stack> |
24 | |
25 | #include "cpu/x64/jit_generator.hpp" |
26 | |
27 | namespace dnnl { |
28 | namespace impl { |
29 | namespace cpu { |
30 | namespace x64 { |
31 | namespace injector_utils { |
32 | |
33 | using vmm_index_set_t = typename std::set<size_t>; |
34 | using vmm_index_set_iterator_t = typename std::set<size_t>::iterator; |
35 | |
36 | enum class layout_t { ncsp, c_blocked, nspc, cspn, unsupported }; |
37 | |
38 | inline layout_t get_layout_type(const memory_desc_wrapper &dst_d) { |
39 | const auto strides = dst_d.blocking_desc().strides; |
40 | if (!dst_d.is_plain()) return layout_t::c_blocked; |
41 | if (strides[0] >= strides[1] |
42 | && IMPLICATION(dst_d.ndims() >= 3, strides[1] >= strides[2])) |
43 | return layout_t::ncsp; |
44 | if (strides[1] == 1) return layout_t::nspc; |
45 | if (strides[0] == 1) return layout_t::cspn; |
46 | return layout_t::unsupported; |
47 | } |
48 | |
49 | /* |
50 | * Scope guard for general purpose register and vector registers preservation. |
51 | * Pushes registers to stack during construction and pops during destruction. |
52 | */ |
53 | class register_preserve_guard_t { |
54 | |
55 | public: |
56 | register_preserve_guard_t(jit_generator *host, |
57 | std::initializer_list<Xbyak::Reg64> reg64_to_preserve, |
58 | std::initializer_list<Xbyak::Xmm> vmm_to_preserve = {}); |
59 | register_preserve_guard_t(register_preserve_guard_t &&other) = default; |
60 | register_preserve_guard_t &operator=(register_preserve_guard_t &&other) |
61 | = default; |
62 | DNNL_DISALLOW_COPY_AND_ASSIGN(register_preserve_guard_t); |
63 | ~register_preserve_guard_t(); |
64 | size_t stack_space_occupied() const; |
65 | |
66 | private: |
67 | jit_generator *host_; |
68 | std::stack<Xbyak::Reg64> reg64_stack_; |
69 | std::stack<Xbyak::Xmm> vmm_stack_; |
70 | size_t vmm_to_preserve_size_bytes_; |
71 | }; |
72 | |
73 | class conditional_register_preserve_guard_t : public register_preserve_guard_t { |
74 | public: |
75 | conditional_register_preserve_guard_t(bool condition_to_be_met, |
76 | jit_generator *host, |
77 | std::initializer_list<Xbyak::Reg64> reg64_to_preserve, |
78 | std::initializer_list<Xbyak::Xmm> vmm_to_preserve = {}); |
79 | DNNL_DISALLOW_COPY_AND_ASSIGN(conditional_register_preserve_guard_t); |
80 | }; |
81 | |
82 | } // namespace injector_utils |
83 | } // namespace x64 |
84 | } // namespace cpu |
85 | } // namespace impl |
86 | } // namespace dnnl |
87 | |
88 | #endif |
89 | |