adding pieces of the translation function from nast to hhbc ast
[hiphop-php.git] / hphp / hhbbc / peephole.h
blob3886a30143ab83a8e854cc20fa135b7168433a6e
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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_HHBBC_PEEPHOLE_H_
17 #define incl_HPHP_HHBBC_PEEPHOLE_H_
19 #include <vector>
20 #include <utility>
22 #include <folly/Optional.h>
24 #include "hphp/runtime/vm/hhbc.h"
25 #include "hphp/hhbbc/interp-state.h"
26 #include "hphp/hhbbc/type-system.h"
28 namespace HPHP { namespace HHBBC {
30 //////////////////////////////////////////////////////////////////////
33 * Very simple peephole rules based on last few tokens. This runs behind
34 * the ConcatPeephole.
36 struct BasicPeephole {
37 explicit BasicPeephole(std::vector<Bytecode>& stream,
38 const Index& index, const Context& ctx)
39 : m_index(index), m_ctx(ctx), m_next(stream)
42 void finalize() {
43 if (!m_next.size()) {
44 m_next.emplace_back(bc::Nop {});
48 void push_back(const Bytecode& op);
49 std::string show(const Bytecode& op);
50 private:
51 const Index& m_index;
52 const Context& m_ctx;
53 std::vector<Bytecode>& m_next;
56 //////////////////////////////////////////////////////////////////////
59 * Perform a block-local optimization that folds sequences of Concat opcodes
60 * into ConcatN opcodes.
62 struct ConcatPeephole {
63 explicit ConcatPeephole(BasicPeephole next)
64 : m_next(next)
66 ConcatPeephole(ConcatPeephole&&) = default;
67 ConcatPeephole& operator=(const ConcatPeephole&) = delete;
70 * Ensure the output stream is in a finished state.
72 void finalize();
75 * Register the next bytecode into the stream.
77 * The State `state' is the pre-step interp state.
79 void append(const Bytecode& op,
80 const State& state,
81 const std::vector<Op>& srcStack);
83 private:
85 * A working stream used to reorder and accumulate Concat's as ConcatN's.
86 * The stream is reorderable up through the concats-th Concat opcode.
88 struct ConcatStream {
89 std::vector<std::pair<Bytecode,bool>> stream;
90 // The working stream; contains bytecode, plus whether
91 // or not the bytecode is a rewriteable Concat.
92 int stacksz; // Stack size at the beginning of the stream.
93 int concats; // Number of concats to accumulate.
96 private:
97 void push_back(const Bytecode& op, bool is_concat = false);
98 void squash();
100 private:
101 BasicPeephole m_next;
102 // Concat streams, nested at increasing stack depths.
103 std::vector<ConcatStream> m_working;
106 //////////////////////////////////////////////////////////////////////
108 using Peephole = ConcatPeephole;
111 * Create the chain of peephole objects. The interface to all the Peepholes is
112 * the same as the interface to ConcatPeephole, above.
114 inline Peephole make_peephole(std::vector<Bytecode>& sink,
115 const Index& index, const Context& ctx) {
116 return ConcatPeephole(BasicPeephole(sink, index, ctx));
119 //////////////////////////////////////////////////////////////////////
123 #endif