Remove SpillFrame, merge its memory effects into CallEffects and InlineEnterEffects
[hiphop-php.git] / hphp / runtime / vm / jit / types.h
blob4b0b02361ea8f578103cd73b673057e7f32943f9
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_TRANSL_TYPES_H_
18 #define incl_HPHP_TRANSL_TYPES_H_
20 #include <vector>
22 #include <folly/Optional.h>
24 #include "hphp/runtime/base/runtime-option.h"
25 #include "hphp/runtime/base/types.h"
27 #include "hphp/util/assertions.h"
28 #include "hphp/util/hash-set.h"
30 namespace HPHP { namespace jit {
32 ///////////////////////////////////////////////////////////////////////////////
35 * Core types.
37 typedef unsigned char* TCA; // "Translation cache address."
38 typedef const unsigned char* CTCA;
40 using LowTCA = LowPtr<uint8_t>;
41 using AtomicLowTCA = AtomicLowPtr<uint8_t,
42 std::memory_order_acquire,
43 std::memory_order_release>;
45 struct ctca_identity_hash {
46 size_t operator()(CTCA val) const {
47 // Experiments show that this is a sufficient "hash function" on
48 // TCAs for now; using stronger functions didn't help given current
49 // data. Patterns of code emission in the translator could invalidate
50 // this finding going forward, though; e.g., if we frequently emit
51 // a call instruction N bytes into a cache-aligned region.
52 return uintptr_t(val);
56 ///////////////////////////////////////////////////////////////////////////////
58 using TransIDSet = hphp_hash_set<TransID>;
59 using TransIDVec = std::vector<TransID>;
61 using Annotation = std::pair<std::string, std::string>;
62 using Annotations = std::vector<Annotation>;
64 ///////////////////////////////////////////////////////////////////////////////
66 /**
67 * The different kinds of translations that the JIT generates:
69 * - Anchor : a service request for retranslating
70 * - Interp : a service request to interpret at least one instruction
71 * - Live : translate one tracelet by inspecting live VM state
72 * - Profile : translate one block by inspecting live VM state and
73 * inserting profiling counters
74 * - Optimize : translate one region performing optimizations that may
75 * leverage data collected by Profile translations
76 * - LivePrologue : prologue for a function being JITed in Live mode
77 * - ProfPrologue : prologue for a function being JITed in Profile mode
78 * - OptPrologue : prologue for a function being JITed in Optimize mode
80 #define TRANS_KINDS \
81 DO(Anchor) \
82 DO(Interp) \
83 DO(Live) \
84 DO(Profile) \
85 DO(Optimize) \
86 DO(LivePrologue)\
87 DO(ProfPrologue)\
88 DO(OptPrologue) \
89 DO(Invalid) \
91 enum class TransKind {
92 #define DO(KIND) KIND,
93 TRANS_KINDS
94 #undef DO
97 constexpr size_t NumTransKinds =
98 #define DO(KIND) + 1
99 TRANS_KINDS
100 #undef DO
103 inline std::string show(TransKind k) {
104 #define DO(name) case TransKind::name: return "Trans" #name;
105 switch (k) { TRANS_KINDS }
106 #undef DO
107 not_reached();
110 inline folly::Optional<TransKind> nameToTransKind(const std::string& str) {
111 #define DO(name) if (str == "Trans" #name) return TransKind::name;
112 TRANS_KINDS
113 #undef DO
114 return folly::none;
117 inline bool isProfiling(TransKind k) {
118 switch (k) {
119 case TransKind::Profile:
120 case TransKind::ProfPrologue:
121 return true;
123 case TransKind::Anchor:
124 case TransKind::Interp:
125 case TransKind::Live:
126 case TransKind::LivePrologue:
127 case TransKind::Optimize:
128 case TransKind::OptPrologue:
129 case TransKind::Invalid:
130 return false;
132 always_assert(false);
135 inline bool isPrologue(TransKind k) {
136 switch (k) {
137 case TransKind::LivePrologue:
138 case TransKind::ProfPrologue:
139 case TransKind::OptPrologue:
140 return true;
142 case TransKind::Anchor:
143 case TransKind::Interp:
144 case TransKind::Live:
145 case TransKind::Profile:
146 case TransKind::Optimize:
147 case TransKind::Invalid:
148 return false;
150 always_assert(false);
154 * Compact flags which may be threaded through a service request to provide
155 * hints or demands for retranslations.
157 struct TransFlags {
158 /* implicit */ TransFlags(uint64_t flags = 0) : packed(flags) {}
160 bool operator==(TransFlags o) const { return packed == o.packed; }
161 bool operator!=(TransFlags o) const { return packed != o.packed; }
163 union {
164 struct {
166 uint64_t packed;
170 static_assert(sizeof(TransFlags) <= sizeof(uint64_t), "Too many TransFlags!");
172 ///////////////////////////////////////////////////////////////////////////////
175 * The "kind" of code being generated.
177 * Different contexts of code generation constrain codegen differently; e.g.,
178 * cross-trace code has fewer available registers.
180 enum class CodeKind : uint8_t {
182 * Normal PHP code in the TC.
184 Trace,
187 * Code for function prologues. Similar to CrossTrace, but may allow more
188 * registers.
190 Prologue,
193 * Code at the TC boundaries, e.g., service requests, unique stubs.
195 CrossTrace,
198 * Helper code that uses native scratch registers only.
200 * This roughly means unreserved, caller-saved, non-argument registers---but
201 * best to just look at the helper ABI in the appropriate abi-*.cpp file.
203 Helper,
207 * Enumeration representing the various areas that we emit code.
209 * kNumAreas must be kept up to date.
211 enum class AreaIndex : uint8_t { Main, Cold, Frozen };
212 constexpr size_t kNumAreas = 3;
214 inline std::string areaAsString(AreaIndex area) {
215 switch (area) {
216 case AreaIndex::Main:
217 return "Main";
218 case AreaIndex::Cold:
219 return "Cold";
220 case AreaIndex::Frozen:
221 return "Frozen";
223 always_assert(false);
226 inline folly::Optional<AreaIndex> nameToAreaIndex(const std::string name) {
227 if (name == "Main") return AreaIndex::Main;
228 if (name == "Cold") return AreaIndex::Cold;
229 if (name == "Frozen") return AreaIndex::Frozen;
230 return folly::none;
234 * Multiplying factors used to compute the block weights for each code area.
235 * We multiply the corresponding IR block's profile counter by the following
236 * factors, depending on the code area the block is assigned to.
238 inline uint64_t areaWeightFactor(AreaIndex area) {
239 switch (area) {
240 case AreaIndex::Main: return RuntimeOption::EvalJitLayoutMainFactor;
241 case AreaIndex::Cold: return RuntimeOption::EvalJitLayoutColdFactor;
242 case AreaIndex::Frozen: return 1;
244 always_assert(false);
247 ///////////////////////////////////////////////////////////////////////////////
250 * Some data structures are accessed often enough from translated code that we
251 * have shortcuts for getting offsets into them.
253 #define TVOFF(nm) int(offsetof(TypedValue, nm))
254 #define AROFF(nm) int(offsetof(ActRec, nm))
255 #define AFWHOFF(nm) int(offsetof(c_AsyncFunctionWaitHandle, nm))
256 #define GENDATAOFF(nm) int(offsetof(Generator, nm))
258 ///////////////////////////////////////////////////////////////////////////////
261 * Generalization of Status Flag bits encoded in Vinstr and used by the
262 * annotateSFUses() pass and platform-specific lowerers/emitters.
264 * In order for a platform to utilize the pass, they'll need to implement
265 * mappings between ConditionCodes and an operator|-able bit sequence held in a
266 * Vflags byte. This implies that the platform will need to define their
267 * status flag bits as well. See required_flags() in abi-arm.h for an example.
269 using Vflags = uint8_t;
271 ///////////////////////////////////////////////////////////////////////////////
274 * Information attached to an assertion in emitted code.
276 struct Reason {
277 const char* file;
278 unsigned line;
280 bool operator==(const Reason& o) const {
281 return line == o.line && std::string{file} == std::string{o.file};
283 bool operator!=(const Reason& o) const {
284 return line != o.line || std::string{file} != std::string{o.file};
288 inline std::string show(const Reason &r) {
289 return folly::sformat("{}:{}", r.file, r.line);
294 #endif