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_HHBBC_ANALYZE_H_
17 #define incl_HHBBC_ANALYZE_H_
22 #include "hphp/hhbbc/misc.h"
23 #include "hphp/hhbbc/representation.h"
24 #include "hphp/hhbbc/interp-state.h"
25 #include "hphp/hhbbc/interp.h"
26 #include "hphp/hhbbc/index.h"
27 #include "hphp/hhbbc/type-system.h"
28 #include "hphp/hhbbc/context.h"
30 namespace HPHP
{ namespace HHBBC
{
32 //////////////////////////////////////////////////////////////////////
35 * The result of a function-at-a-time type analysis, as needed for
36 * updating the index. Does not include per-block state.
38 struct FuncAnalysisResult
{
40 * Initializes this structure so rpoBlocks contains the func's
41 * blocks according to rpoSortAddDVs(), each bdata entry has an
42 * rpoId index, and all block states are uninitialized.
44 explicit FuncAnalysisResult(Context
);
46 FuncAnalysisResult(FuncAnalysisResult
&&) = default;
47 FuncAnalysisResult
& operator=(FuncAnalysisResult
&&) = default;
50 * FuncAnalysis carries the Context it was created for because
51 * generally you'll need it again when you look at the analysis
54 * Note that the Context is adjusted to account for the fact that
55 * Closure __invoke methods run in the context of a class other than
56 * their declaring class. So ctx.func->cls will not be the same as
57 * ctx->cls in this case.
62 * The inferred function return type. May be TBottom if the
63 * function never returns.
68 * If this function allocates closures, this maps each of those
69 * closure classes to the types of its used variables, in their
72 ClosureUseVarMap closureUseTypes
;
75 * With HardConstProp enabled, the set of constants that this
76 * function could define.
81 * Reads a constant thats not in the index (yet - this can only
82 * happen on the first iteration). We'll need to revisit it.
84 bool readsUntrackedConstants
{false};
87 * Flag to indicate that the function does something that requires a
88 * variable environment.
93 * Flag to indicate that the function is effectFree, in the sense
94 * that calls to it can be constant folded or dced (note that calls
95 * are never truly effect free, because profilers could be enabled,
96 * or other surprise flags could fire - but we ignore that for this
99 bool effectFree
{false};
102 * Flag to indicate that an iterator's base was unchanged on at least one path
103 * to that iterator's release. If this is false, we can skip doing the more
104 * expensive LIter optimization pass (because it will never succeed).
106 bool hasInvariantIterBase
{false};
109 * A set of pair of functions and their push blocks that we failed to fold.
111 std::unordered_set
<std::pair
<borrowed_ptr
<const php::Func
>, BlockId
>>
115 * Known types of local statics.
117 CompactVector
<Type
> localStaticTypes
;
119 // For an 86cinit, any constants that we resolved.
120 // The size_t is the index into ctx.cls->constants
121 CompactVector
<std::pair
<size_t,TypedValue
>> resolvedConstants
;
124 struct FuncAnalysis
: FuncAnalysisResult
{
125 using BlockData
= struct { uint32_t rpoId
; State stateIn
; };
127 explicit FuncAnalysis(Context
);
129 FuncAnalysis(FuncAnalysis
&&) = default;
130 FuncAnalysis
& operator=(FuncAnalysis
&&) = default;
132 // Blocks in a reverse post order, with DV initializers.
133 std::vector
<borrowed_ptr
<php::Block
>> rpoBlocks
;
135 // Block data is indexed by Block::id.
136 std::vector
<BlockData
> bdata
;
140 * The result of a class-at-a-time analysis.
142 struct ClassAnalysis
{
143 ClassAnalysis(Context ctx
, bool anyInterceptable
) :
144 ctx(ctx
), anyInterceptable(anyInterceptable
) {}
146 ClassAnalysis(ClassAnalysis
&&) = default;
147 ClassAnalysis
& operator=(ClassAnalysis
&&) = default;
149 // The context that describes the class we did this analysis for.
152 // FuncAnalysis results for each of the methods on the class, and
153 // for each closure allocated in the class's context.
154 CompactVector
<FuncAnalysisResult
> methods
;
155 CompactVector
<FuncAnalysisResult
> closures
;
157 // Inferred types for private instance and static properties.
158 PropState privateProperties
;
159 PropState privateStatics
;
160 bool anyInterceptable
;
163 //////////////////////////////////////////////////////////////////////
166 * Perform a flow-sensitive type analysis on a function, using the
167 * given Index and Context when we need information about things
168 * outside of this function.
170 * This routine makes no changes to the php::Func.
172 FuncAnalysis
analyze_func(const Index
&, Context
, CollectionOpts opts
);
175 * Analyze a function like analyze_func, but exposing gathered CollectedInfo
176 * results. The CollectedInfo structure can be initialized by the caller to
177 * enable collecting some pass-specific types of information (e.g. public
178 * static property types).
180 FuncAnalysis
analyze_func_collect(const Index
&, Context
, CollectedInfo
&);
183 * Perform a flow-sensitive type analysis on a function, using the
184 * given Index and Context when we need information about things
185 * outside of this function, and assuming that the arguments to the
186 * function have the supplied types.
188 * This function is used to perform callsite-sensitive type inference.
190 * Currently this is not supported for closure bodies.
192 FuncAnalysis
analyze_func_inline(const Index
&,
194 std::vector
<Type
> args
,
195 CollectionOpts opts
=
196 CollectionOpts::TrackConstantArrays
);
199 * Perform an analysis for a whole php::Class at a time.
201 * This involves doing a analyze_func call on each of its functions,
202 * and inferring some whole-class information at the same time.
204 ClassAnalysis
analyze_class(const Index
&, Context
);
207 * Propagate a block input State to each instruction in the block.
209 * Returns a vector that is parallel to the instruction array in the
210 * block, with one extra element. The vector contains a state before
211 * each instruction, and the StepFlags for executing that instruction.
213 * The last element in the vector contains the state after the last
214 * instruction in the block, with undefined StepFlags.
216 * Pre: stateIn.initialized == true
218 std::vector
<std::pair
<State
,StepFlags
>>
219 locally_propagated_states(const Index
&,
221 CollectedInfo
& collect
,
222 borrowed_ptr
<const php::Block
>,
225 //////////////////////////////////////////////////////////////////////