2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 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_VASM_UNIT_H_
18 #define incl_HPHP_JIT_VASM_UNIT_H_
20 #include "hphp/runtime/base/datatype.h"
22 #include "hphp/runtime/vm/jit/types.h"
23 #include "hphp/runtime/vm/jit/containers.h"
24 #include "hphp/runtime/vm/jit/vasm.h"
25 #include "hphp/runtime/vm/jit/vasm-instr.h"
26 #include "hphp/runtime/vm/jit/vasm-reg.h"
28 #include "hphp/util/data-block.h"
29 #include "hphp/util/immed.h"
32 #include <type_traits>
34 namespace HPHP
{ namespace jit
{
35 ///////////////////////////////////////////////////////////////////////////////
38 * Block of Vinstrs, managed by Vunit.
40 * A Vblock, in addition to containing a Vinstr stream, also specifies where it
41 * should be emitted to.
44 explicit Vblock(AreaIndex area_idx
) : area_idx(area_idx
) {}
47 jit::vector
<Vinstr
> code
;
51 * Vector of Vregs, for Vtuples and VcallArgs.
53 using VregList
= jit::vector
<Vreg
>;
56 * Source operands for vcall/vinvoke instructions, packed into a struct for
57 * convenience and to keep the instructions compact.
65 ///////////////////////////////////////////////////////////////////////////////
70 * Either a 1, 4, or 8 byte unsigned value, 8 byte double, or the disp32 part
71 * of a thread-local address of an immutable constant that varies by thread.
72 * Constants may also represent an undefined value, indicated by the isUndef
75 * Also contains convenience constructors for various pointer and enum types.
78 enum Kind
{ Quad
, Long
, Byte
, Double
, ThreadLocal
};
80 using ullong
= unsigned long long;
81 using ulong
= unsigned long;
83 Vconst() : kind(Quad
), val(0) {}
84 explicit Vconst(Kind k
) : kind(k
), isUndef(true), val(0) {}
85 explicit Vconst(bool b
) : kind(Byte
), val(b
) {}
86 explicit Vconst(uint8_t b
) : kind(Byte
), val(b
) {}
87 explicit Vconst(int8_t b
) : Vconst(uint8_t(b
)) {}
88 explicit Vconst(uint32_t i
) : kind(Long
), val(i
) {}
89 // For historical reasons Vconst(int) produces an 8-byte constant.
90 explicit Vconst(int32_t i
) : Vconst(int64_t(i
)) {}
91 explicit Vconst(uint16_t) = delete;
92 explicit Vconst(int16_t) = delete;
93 explicit Vconst(ullong i
) : kind(Quad
), val(i
) {}
94 explicit Vconst(long long i
) : Vconst(ullong(i
)) {}
95 explicit Vconst(ulong i
) : Vconst(ullong(i
)) {}
96 explicit Vconst(long i
) : Vconst(ullong(i
)) {}
97 explicit Vconst(const void* p
) : Vconst(uintptr_t(p
)) {}
98 explicit Vconst(double d
) : kind(Double
), doubleVal(d
) {}
99 explicit Vconst(Vptr tl
) : kind(ThreadLocal
), disp(tl
.disp
) {
100 assertx(!tl
.base
.isValid() && !tl
.index
.isValid() && tl
.seg
== Vptr::FS
);
105 class Enable
= typename
std::enable_if
<std::is_enum
<E
>::value
>::type
107 explicit Vconst(E e
) : Vconst(typename
std::underlying_type
<E
>::type(e
)) {}
109 template<class R
, class... Args
>
110 explicit Vconst(R (*fn
)(Args
...)) : Vconst(uintptr_t(fn
)) {}
112 bool operator==(Vconst other
) const {
113 return kind
== other
.kind
&&
114 ((isUndef
&& other
.isUndef
) || val
== other
.val
);
118 size_t operator()(Vconst c
) const {
120 std::hash
<uint64_t>()(c
.val
) ^ std::hash
<int>()(c
.kind
) ^ c
.isUndef
;
124 /////////////////////////////////////////////////////////////////////////////
132 int64_t disp
; // really, int32 offset from %fs
136 ///////////////////////////////////////////////////////////////////////////////
139 * A Vunit contains all the assets that make up a vasm compilation unit. It is
140 * responsible for allocating new blocks, Vregs, and tuples.
144 * Create a new block in the given area, returning its id.
146 Vlabel
makeBlock(AreaIndex area
);
149 * Create a block intended to be used temporarily, as part of modifying
152 * Although not necessary for correctness, the block may be freed with
153 * freeScratchBlock when finished.
155 Vlabel
makeScratchBlock();
158 * Free a scratch block when finished with it. There must be no references
159 * to this block in reachable code.
161 void freeScratchBlock(Vlabel
);
163 /////////////////////////////////////////////////////////////////////////////
166 * Make various Vunit-managed vasm structures.
168 Vreg
makeReg() { return Vreg
{next_vr
++}; }
169 Vtuple
makeTuple(VregList
&& regs
);
170 Vtuple
makeTuple(const VregList
& regs
);
171 VcallArgsId
makeVcallArgs(VcallArgs
&& args
);
174 * Create or return a register representing the given constant value.
176 Vreg
makeConst(Vconst
);
177 template<typename T
> Vreg
makeConst(T v
) { return makeConst(Vconst
{v
}); }
179 /////////////////////////////////////////////////////////////////////////////
182 * Return true iff this Vunit needs register allocation before it can be
183 * emitted, either because it uses virtual registers or contains instructions
184 * that must be lowered by xls.
186 bool needsRegAlloc() const;
188 /////////////////////////////////////////////////////////////////////////////
191 unsigned next_vr
{Vreg::V0
};
193 jit::vector
<Vblock
> blocks
;
194 jit::hash_map
<Vconst
,Vreg
,Vconst::Hash
> constToReg
;
195 jit::hash_map
<size_t,Vconst
> regToConst
;
196 jit::vector
<VregList
> tuples
;
197 jit::vector
<VcallArgs
> vcallArgs
;
199 TransKind transKind
{TransKind::Invalid
};
202 ///////////////////////////////////////////////////////////////////////////////