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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_HHBBC_PEEPHOLE_H_
17 #define incl_HPHP_HHBBC_PEEPHOLE_H_
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
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
)
44 m_next
.emplace_back(bc::Nop
{});
48 void push_back(const Bytecode
& op
);
49 std::string
show(const Bytecode
& op
);
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
)
66 ConcatPeephole(ConcatPeephole
&&) = default;
67 ConcatPeephole
& operator=(const ConcatPeephole
&) = delete;
70 * Ensure the output stream is in a finished state.
75 * Register the next bytecode into the stream.
77 * The State `state' is the pre-step interp state.
79 void append(const Bytecode
& op
,
81 const std::vector
<Op
>& srcStack
);
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.
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.
97 void push_back(const Bytecode
& op
, bool is_concat
= false);
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 //////////////////////////////////////////////////////////////////////