Rename RefcountProfile to IncRefProfile
[hiphop-php.git] / hphp / runtime / vm / jit / irgen.h
blobdc8a7f00a8560db7ef17df461556a75f6123222b
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_JIT_IRGEN_H_
18 #define incl_HPHP_JIT_IRGEN_H_
20 #include "hphp/runtime/base/repo-auth-type.h"
21 #include "hphp/runtime/base/types.h"
22 #include "hphp/runtime/vm/hhbc.h"
23 #include "hphp/runtime/vm/member-key.h"
24 #include "hphp/runtime/vm/srckey.h"
26 #include "hphp/runtime/vm/jit/bc-marker.h"
27 #include "hphp/runtime/vm/jit/ir-builder.h"
28 #include "hphp/runtime/vm/jit/ir-opcode.h"
29 #include "hphp/runtime/vm/jit/ir-unit.h"
30 #include "hphp/runtime/vm/jit/irgen-state.h"
31 #include "hphp/runtime/vm/jit/location.h"
32 #include "hphp/runtime/vm/jit/region-selection.h"
33 #include "hphp/runtime/vm/jit/stack-offsets.h"
34 #include "hphp/runtime/vm/jit/types.h"
36 #include "hphp/util/ringbuffer.h"
38 #include <cstdint>
39 #include <utility>
40 #include <vector>
42 namespace HPHP {
44 struct ArrayData;
45 struct Func;
46 struct ImmVector;
47 struct StringData;
49 namespace jit {
51 struct Block;
52 struct IRInstruction;
53 struct NormalizedInstruction;
54 struct SSATmp;
56 namespace irgen {
58 struct IRGS;
60 ///////////////////////////////////////////////////////////////////////////////
63 * The public interface to the HHIR frontend is exported here. Don't include
64 * other headers outside of the implementation of this module.
66 * This module is used for two tasks:
68 * o It is used by the region translator, and does most of the work of
69 * parsing HHBC into HHIR when we're trying to create an IRUnit out of a
70 * RegionDesc.
72 * o The tracelet region selector uses this code to generate a RegionDesc.
74 * To use this code, the client creates an IRGS structure, and calls these
75 * irgen::foo methods on it.
77 * TODO: we should push translateRegion and selectTracelet into this module, so
78 * we can just export functions that do the above two tasks.
81 ///////////////////////////////////////////////////////////////////////////////
84 * The main function for generating new IRInstructions. Attempts to append an
85 * IRInstruction at the end of the current Block.
87 * Uses the same argument list format as IRUnit::gen.
89 namespace detail { SSATmp* genInstruction(IRGS& env, IRInstruction*); }
90 template<class... Args>
91 SSATmp* gen(IRGS& env, Opcode op, Args&&... args) {
92 return makeInstruction(
93 [&] (IRInstruction* inst) { return detail::genInstruction(env, inst); },
94 op,
95 env.irb->nextBCContext(),
96 std::forward<Args>(args)...
101 * Create constant-valued SSATmps inside the IRUnit we're creating.
103 template<class... Args>
104 SSATmp* cns(IRGS& env, Args&&... args) {
105 return env.unit.cns(std::forward<Args>(args)...);
108 ///////////////////////////////////////////////////////////////////////////////
111 * Type checks and assertions.
113 void checkType(IRGS&, const Location&, Type,
114 Offset dest, bool outerOnly);
115 void assertTypeStack(IRGS&, BCSPRelOffset, Type);
116 void assertTypeLocal(IRGS&, uint32_t id, Type);
117 void assertTypeLocation(IRGS&, const Location&, Type);
120 * Type predictions.
122 void predictType(IRGS&, const Location&, Type);
125 * After all initial guards instructions have been emitted, the client of this
126 * module calls the following function to allow some "region header" code to be
127 * emitted.
129 void prepareEntry(IRGS&);
131 ///////////////////////////////////////////////////////////////////////////////
134 * Creates a no-op IR instruction that branches to an exit.
136 * These placeholder instructions are later removed after any passes that want
137 * to use them for their exits.
139 void makeExitPlaceholder(IRGS&);
142 * Support for Profiling counters, including reoptimization (CheckCold).
144 void incProfCounter(IRGS&, TransID);
145 void checkCold(IRGS&, TransID);
147 uint64_t curProfCount(const IRGS& env);
148 uint64_t calleeProfCount(const IRGS& env, const RegionDesc& calleeRegion);
151 * If ringbuffer tracing is enabled, generate a ringbuffer entry associated
152 * with a SrcKey or string.
154 void ringbufferEntry(IRGS&, Trace::RingBufferType, SrcKey, int level = 1);
155 void ringbufferMsg(IRGS&, Trace::RingBufferType, const StringData*,
156 int level = 1);
158 ///////////////////////////////////////////////////////////////////////////////
161 * For handling PUNT-based interpOnes. When we PUNT, an exception is thrown
162 * and the whole region is retried, with a bit set to interp the instruction
163 * that failed.
165 void interpOne(IRGS&, const NormalizedInstruction&);
167 ///////////////////////////////////////////////////////////////////////////////
170 * Before translating/processing each bytecode instruction, the driver
171 * of the irgen module calls this function to move to the next
172 * bytecode instruction (`newSk') to translate.
174 * The flag `lastBcInst' should be set if this is the last bytecode in
175 * a region that's being translated.
177 void prepareForNextHHBC(IRGS&, const NormalizedInstruction*,
178 SrcKey newSk, bool lastBcInst);
181 * After translating each bytecode instruction, the driver of the
182 * irgen module calls this function to signal that it has finished
183 * processing the HHBC instruction.
185 void finishHHBC(IRGS&);
188 * When done translating a region, or a block in a region, these calls are
189 * made.
191 void endRegion(IRGS&);
192 void endRegion(IRGS&, SrcKey);
193 void endBlock(IRGS&, Offset next);
196 * When we're done creating the IRUnit, this function must be called to ensure
197 * all the IR invariants hold.
199 void sealUnit(IRGS&);
201 ///////////////////////////////////////////////////////////////////////////////
204 * Returns whether `env' is currently inlining or not.
206 bool isInlining(const IRGS& env);
209 * Attempt to begin inlining, and return whether or not we succeeded.
211 * When doing gen-time inlining, we set up a series of IR instructions that
212 * looks like this:
214 * fp0 = DefFP
215 * sp = DefSP<offset>
217 * // ... normal stuff happens ...
219 * // FPI region:
220 * SpillFrame sp, ...
221 * // ... probably some StStks due to argument expressions
222 * BeginInlining<offset> sp
223 * fp2 = DefInlineFP<func,retBC,retSP,off> sp
225 * // ... callee body ...
227 * InlineReturn fp2
229 * In DCE we attempt to remove the InlineReturn and DefInlineFP instructions if
230 * they aren't needed.
232 bool beginInlining(IRGS& env,
233 unsigned numParams,
234 const Func* target,
235 SrcKey startSk,
236 Offset returnBcOffset,
237 ReturnTarget returnTarget,
238 int cost,
239 bool conjure);
242 * End the current inlined frame, after all its blocks have been emitted.
244 * This decrefs locals and $this and pushes the return value onto the caller's
245 * eval stack, in addition to the actual control transfer and bookkeeping done
246 * by implInlineReturn().
248 bool endInlining(IRGS& env);
251 * Begin inlining func into a dummy region used to measure the cost of
252 * inlining func. This will generate a region that cannot be executed.
254 * Simulating the inlining measures the cost of pushing a dummy frame (or not if
255 * we are able to elide it) and any effects that may have on alias analysis.
257 * Returns false if the inlined region would be invalid for inlining
259 bool conjureBeginInlining(IRGS& env,
260 const Func* func,
261 SrcKey startSk,
262 Type thisType,
263 const std::vector<Type>& args,
264 ReturnTarget returnTarget);
267 * Close an inlined function inserted using conjureBeginInlining; returns false
268 * if the inlined region would have been invalid for inlining. As with
269 * conjureBeginInlining, this function should not be used in a region that will
270 * be executed.
272 void conjureEndInlining(IRGS& env, bool builtin);
275 * We do two special-case optimizations to partially inline 'singleton'
276 * accessor functions (functions that just return a static local or static
277 * property if it's not null).
279 * This is exposed publically because the region translator drives inlining
280 * decisions.
282 void inlSingletonSProp(IRGS&, const Func*, PC clsOp, PC propOp);
283 void inlSingletonSLoc(IRGS&, const Func*, PC op);
285 ///////////////////////////////////////////////////////////////////////////////
287 * State introspection.
289 * These functions should only be used for inspecting state. None of them
290 * constrain types, so if the type information is actually used, it must be
291 * constrained appropriately.
295 * Access the type of the top of the stack.
297 Type publicTopType(const IRGS& env, BCSPRelOffset);
300 * Return the proven or predicted Type for the given location.
302 Type provenType(const IRGS&, const Location&);
303 Type predictedType(const IRGS&, const Location&);
305 ///////////////////////////////////////////////////////////////////////////////
307 * Forward-declare an irgen::emitFoo function for each bytecode Foo.
309 * The arguments to the functions are pre-unpacked bytecode immediates.
312 #define IMM_BLA const ImmVector&
313 #define IMM_SLA const ImmVector&
314 #define IMM_ILA const IterTable&
315 #define IMM_I32LA const ImmVector&
316 #define IMM_BLLA const ImmVector&
317 #define IMM_VSA const ImmVector&
318 #define IMM_IVA uint32_t
319 #define IMM_I64A int64_t
320 #define IMM_LA int32_t
321 #define IMM_IA int32_t
322 #define IMM_CAR uint32_t
323 #define IMM_CAW uint32_t
324 #define IMM_DA double
325 #define IMM_SA const StringData*
326 #define IMM_RATA RepoAuthType
327 #define IMM_AA const ArrayData*
328 #define IMM_BA Offset
329 #define IMM_OA(subop) subop
330 #define IMM_KA MemberKey
331 #define IMM_LAR LocalRange
332 #define IMM_FCA FCallArgs
334 #define NA /* */
335 #define ONE(x0) , IMM_##x0
336 #define TWO(x0, x1) , IMM_##x0, IMM_##x1
337 #define THREE(x0, x1, x2) , IMM_##x0, IMM_##x1, IMM_##x2
338 #define FOUR(x0, x1, x2, x3) , IMM_##x0, IMM_##x1, IMM_##x2, IMM_##x3
339 #define FIVE(x0, x1, x2, x3, x4) , IMM_##x0, IMM_##x1, IMM_##x2, IMM_##x3, IMM_##x4
341 #define O(name, imms, ...) void emit##name(IRGS& imms);
342 OPCODES
343 #undef O
345 #undef NA
346 #undef ONE
347 #undef TWO
348 #undef THREE
349 #undef FOUR
350 #undef FIVE
352 #undef IMM_MA
353 #undef IMM_BLA
354 #undef IMM_SLA
355 #undef IMM_ILA
356 #undef IMM_I32LA
357 #undef IMM_BLLA
358 #undef IMM_VSA
359 #undef IMM_IVA
360 #undef IMM_I64A
361 #undef IMM_LA
362 #undef IMM_IA
363 #undef IMM_CAR
364 #undef IMM_CAW
365 #undef IMM_DA
366 #undef IMM_SA
367 #undef IMM_RATA
368 #undef IMM_AA
369 #undef IMM_BA
370 #undef IMM_OA
371 #undef IMM_KA
372 #undef IMM_LAR
373 #undef IMM_FCA
375 ///////////////////////////////////////////////////////////////////////////////
379 #endif