Remove SpillFrame, merge its memory effects into CallEffects and InlineEnterEffects
[hiphop-php.git] / hphp / runtime / vm / jit / vasm-simplify-internal.h
blobe8c4fc3bd0fd8f24506c44bd6b73bf52bce0197f
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_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"
27 #include <cstdint>
28 #include <utility>
30 namespace HPHP { namespace jit {
32 ///////////////////////////////////////////////////////////////////////////////
34 struct Env {
35 Vunit& unit;
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) {
82 --env.use_counts[r];
83 });
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);
92 ++env.use_counts[r];
93 });
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;
99 });
102 return nremove;
106 inline bool simplify_impl(Env& env, Vlabel b, size_t i, const Vinstr& instr) {
107 return simplify_impl(env, b, i, [&] (Vout& v) {
108 v << instr;
109 return 1;
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 ///////////////////////////////////////////////////////////////////////////////
121 #endif