Improve refineLocation a little
[hiphop-php.git] / hphp / hhbbc / analyze.h
blobff63b020bd54bf108540500b721b9b61d1a11698
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_HHBBC_ANALYZE_H_
17 #define incl_HHBBC_ANALYZE_H_
19 #include <vector>
20 #include <utility>
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
52 * results.
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.
59 Context ctx;
62 * The inferred function return type. May be TBottom if the
63 * function never returns.
65 Type inferredReturn;
68 * If this function allocates closures, this maps each of those
69 * closure classes to the types of its used variables, in their
70 * declared order.
72 ClosureUseVarMap closureUseTypes;
75 * With HardConstProp enabled, the set of constants that this
76 * function could define.
78 ConstantMap cnsMap;
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.
90 bool mayUseVV;
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
97 * flag).
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>>
112 unfoldableFuncs;
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.
150 Context ctx;
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&,
193 Context,
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&,
220 const FuncAnalysis&,
221 CollectedInfo& collect,
222 borrowed_ptr<const php::Block>,
223 State stateIn);
225 //////////////////////////////////////////////////////////////////////
229 #endif