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_ALIAS_ANALYSIS_H_
17 #define incl_HPHP_ALIAS_ANALYSIS_H_
23 #include "hphp/runtime/vm/jit/containers.h"
24 #include "hphp/runtime/vm/jit/alias-class.h"
25 #include "hphp/runtime/vm/jit/cfg.h"
27 #include "hphp/util/sparse-id-containers.h"
29 namespace HPHP
{ namespace jit
{
33 //////////////////////////////////////////////////////////////////////
36 * Sets of abstract locations tracked by AliasAnalysis come in ALocBits.
38 * Right now we have a static maximum number of tracked locations---passes
39 * using information from this module must be conservative about locations that
40 * aren't assigned an id. (E.g. via calls to may_alias in AliasAnalysis.)
42 constexpr uint32_t kMaxTrackedALocs
= 256;
43 using ALocBits
= std::bitset
<kMaxTrackedALocs
>;
45 //////////////////////////////////////////////////////////////////////
48 uint32_t index
; // id assigned to this location
49 ALocBits conflicts
; // flow-insensitive may-alias set, without self
53 * Information about various abstract locations an IR unit may be concerned
54 * with. See collect_aliases.
56 struct AliasAnalysis
{
57 explicit AliasAnalysis(const IRUnit
&);
59 AliasAnalysis(const AliasAnalysis
&) = delete;
60 AliasAnalysis(AliasAnalysis
&&) = default;
61 AliasAnalysis
& operator=(const AliasAnalysis
&) = delete;
62 AliasAnalysis
& operator=(AliasAnalysis
&&) = default;
65 * Bidirectional map from alias classes to metadata about that abstract
66 * memory location, primarily an assigned id. There is also an inverse map
67 * from id to the metadata structure.
69 * Two different alias classes in this map should not alias each other. If
70 * an alias class contains multiple locations (e.g., a range of stack slots,
71 * multiple frame locals), we need to use multiple bits in this map.
73 * The keyed locations in this map take their canonical form. You should use
74 * canonicalize before doing lookups.
76 jit::hash_map
<AliasClass
,ALocMeta
,AliasClass::Hash
> locations
;
77 jit::vector
<ALocMeta
> locations_inv
;
79 using LocationMap
= jit::hash_map
<AliasClass
,ALocBits
,AliasClass::Hash
>;
82 * If an AStack covers multiple locations, it will have an entry in this
83 * map. It is OK if not all locations covered by the AStack are tracked. We
84 * only store the tracked subset here.
86 LocationMap stack_ranges
;
89 * Similar to `stack_ranges', if an AFrame covers multiple locations, it will
90 * have an entry in this map.
92 LocationMap local_sets
;
95 * Similar to `stack_ranges', if an AClsRefSlot covers multiple locations, it
96 * will have an entry in this map.
98 LocationMap clsref_sets
;
101 * Short-hand to find an alias class in the locations map, or get folly::none
102 * if the alias class wasn't assigned an ALocMeta structure.
104 folly::Optional
<ALocMeta
> find(AliasClass
) const;
107 * Several larger sets of locations, we have a set of all the ids assigned to
108 * properties, elemIs, frame locals, etc. This is used by may_alias below.
114 ALocBits all_clsRefSlot
;
117 ALocBits all_iterPos
;
118 ALocBits all_iterBase
;
119 ALocBits all_cufIterFunc
;
120 ALocBits all_cufIterCtx
;
121 ALocBits all_cufIterInvName
;
122 ALocBits all_cufIterDynamic
;
125 * Return the number of distinct locations we're tracking by id
127 size_t count() const { return locations_inv
.size(); }
130 * Return a set of locations that we've assigned ids to that may alias a
131 * given AliasClass. Note that (as usual) memory locations we haven't
132 * assigned bits to may still be affected, but this module only reports
133 * effects on locations assigned bits.
135 * This function may conservatively return more bits than actually may
138 ALocBits
may_alias(AliasClass acls
) const;
141 * Return a set of locations that we've assigned ids to that are definitely
142 * contained in `acls'. This function may conservatively return a smaller
143 * set of bits: every bit that is set in the returned ALocBits is contained
144 * in `acls', but there may be locations contained in `acls' that don't have
145 * a bit set in the returned vector. As a consequence of this, any caller of
146 * expand() must produce correct (but potentially suboptimal) results if
147 * expand is hardcoded to always return an empty bitset.
149 * This should generally be used with AliasClasses that are exhaustive,
150 * must-style information. That is, AliasClasses that should be interpreted
151 * as referring to every point they contain. Right now, the primary example
152 * of that sort of AliasClasses is the class of locations in `kills' sets in
153 * certain memory effects structs: these sets indicate every location inside
154 * the class is affected.
156 * Right now, this function will work for specific AliasClasses we've
157 * assigned ids---for larger classes, it only supports stack ranges observed
158 * during alias collection, AFrameAny, and some cases of unions of those---if
159 * you need more to work, the implementation will need some improvements.
161 ALocBits
expand(AliasClass acls
) const;
164 * Sets of alias classes that are used by expand().
166 jit::hash_map
<AliasClass
,ALocBits
,AliasClass::Hash
> stk_expand_map
;
169 //////////////////////////////////////////////////////////////////////
172 * Perform a flow-insensitive analysis on the supplied blocks, collecting
173 * possibly distinct abstract memory locations that are explicitly referenced,
174 * and assigning them ids and may-alias sets. Only certain types of locations
175 * are assigned ids, based on whether it maps to an AliasClass that that passes
176 * can currently plausibly optimize (because it is sufficiently concrete).
178 * Note: it is fine to continue to reuse one AliasAnalysis structure after
179 * mutating the IR, because the information it contains is both
180 * flow-insensitive and conservative. That is: if you change the IR to
181 * reference new abstract memory locations, the fact that AliasAnalysis didn't
182 * know about it won't invalidate the things it knows about (and the general
183 * may_alias function will still work on the new location). Similarly,
184 * removing references to locations or changing control flow won't invalidate
187 AliasAnalysis
collect_aliases(const IRUnit
&, const BlockList
&);
189 //////////////////////////////////////////////////////////////////////
192 * Produce summary information for debug printing.
194 std::string
show(const AliasAnalysis
&);
195 std::string
show(ALocBits
);
197 //////////////////////////////////////////////////////////////////////