2 +----------------------------------------------------------------------+
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_VASM_SIMPLIFY_INTERNAL_H_
18 #define incl_HPHP_JIT_VASM_SIMPLIFY_INTERNAL_H_
20 #include "hphp/runtime/vm/jit/containers.h"
21 #include "hphp/runtime/vm/jit/vasm.h"
22 #include "hphp/runtime/vm/jit/vasm-gen.h"
23 #include "hphp/runtime/vm/jit/vasm-instr.h"
24 #include "hphp/runtime/vm/jit/vasm-unit.h"
25 #include "hphp/runtime/vm/jit/vasm-visit.h"
30 namespace HPHP
{ namespace jit
{
32 ///////////////////////////////////////////////////////////////////////////////
37 // Number of uses of each Vreg.
38 jit::vector
<uint32_t> use_counts
;
40 // Instruction which def'd each Vreg. Probably only useful when the def
41 // instruction only has a single dst, but that's all we need right now.
42 jit::vector
<Vinstr::Opcode
> def_insts
;
45 template<Vinstr::Opcode op
>
46 using op_type
= typename
Vinstr::op_matcher
<op
>::type
;
49 * Check if the instruction at block `b', index `i' of `env.unit' is an `op'.
50 * If so, call `f' on the specific instruction, and return the result. If not,
51 * return a default-constructed instance of f's return type.
53 template<Vinstr::Opcode op
, typename F
>
54 auto if_inst(const Env
& env
, Vlabel b
, size_t i
, F f
)
55 -> decltype(f(std::declval
<const op_type
<op
>&>()))
57 auto const& code
= env
.unit
.blocks
[b
].code
;
58 if (i
>= code
.size() || code
[i
].op
!= op
) {
59 return decltype(f(code
[i
].get
<op
>())){};
61 return f(code
[i
].get
<op
>());
65 * Helper for vasm-simplification routines.
67 * This just wraps vmodify() with some accounting logic for `env'.
69 template<typename Simplify
>
70 auto simplify_impl(Env
& env
, Vlabel b
, size_t i
, Simplify simplify
)
71 -> decltype(simplify(std::declval
<Vout
&>()), false)
73 auto& unit
= env
.unit
;
75 return vmodify(unit
, b
, i
, [&] (Vout
& v
) {
76 auto& blocks
= unit
.blocks
;
77 auto const nremove
= simplify(v
);
79 // Update use counts for to-be-removed instructions.
80 for (auto j
= i
; j
< i
+ nremove
; ++j
) {
81 visitUses(unit
, blocks
[b
].code
[j
], [&] (Vreg r
) {
86 // Update use counts and def instructions for to-be-added instructions.
87 for (auto const& inst
: blocks
[Vlabel(v
)].code
) {
88 visitUses(unit
, inst
, [&] (Vreg r
) {
89 if (r
>= env
.use_counts
.size()) {
90 env
.use_counts
.resize(size_t{r
} + 1);
94 visitDefs(unit
, inst
, [&] (Vreg r
) {
95 if (r
>= env
.def_insts
.size()) {
96 env
.def_insts
.resize(size_t{r
} + 1, Vinstr::nop
);
98 env
.def_insts
[r
] = inst
.op
;
106 inline bool simplify_impl(Env
& env
, Vlabel b
, size_t i
, const Vinstr
& instr
) {
107 return simplify_impl(env
, b
, i
, [&] (Vout
& v
) {
113 namespace x64
{ bool simplify(Env
& env
, Vlabel b
, size_t i
); }
114 namespace arm
{ bool simplify(Env
& env
, Vlabel b
, size_t i
); }
115 namespace ppc64
{ bool simplify(Env
& env
, Vlabel b
, size_t i
); }
117 ///////////////////////////////////////////////////////////////////////////////