Optimize struct element initialization
[hiphop-php.git] / hphp / runtime / vm / coeffects.h
blob7b5613a25a85e410648ae9ed63512611fdd9dc23
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 +----------------------------------------------------------------------+
17 #pragma once
19 #include "hphp/runtime/vm/class.h"
21 #include <folly/Optional.h>
23 namespace HPHP {
24 ///////////////////////////////////////////////////////////////////////////////
25 namespace jit {
26 struct SSATmp;
27 namespace irgen {
28 struct IRGS;
31 ///////////////////////////////////////////////////////////////////////////////
32 struct RuntimeCoeffects {
33 using storage_t = uint16_t;
35 static RuntimeCoeffects fromValue(uint16_t value) {
36 return RuntimeCoeffects{value};
39 static RuntimeCoeffects none() {
40 return RuntimeCoeffects::fromValue(0);
43 static RuntimeCoeffects full() {
44 return RuntimeCoeffects::fromValue(std::numeric_limits<storage_t>::max());
47 // This function is a placeholder to indicate that the correct coeffect needs
48 // to be indentified and passed in its place
49 static RuntimeCoeffects fixme() {
50 return RuntimeCoeffects::none();
53 uint16_t value() const { return m_data; }
55 const std::string toString() const;
57 // Checks whether provided coeffects in `this` can call
58 // required coeffects in `o`
59 bool canCall(const RuntimeCoeffects o) const {
60 // a & b == a
61 // a & ~b == 0
62 return (m_data & (~o.m_data)) == 0;
65 bool canCallWithWarning(const RuntimeCoeffects) const;
67 // This operator is equivalent to | of [coeffectA | coeffectB]
68 RuntimeCoeffects& operator&=(const RuntimeCoeffects);
70 private:
71 explicit RuntimeCoeffects(uint16_t data) : m_data(data) {}
72 storage_t m_data;
75 struct StaticCoeffects {
76 using storage_t = RuntimeCoeffects::storage_t;
78 const folly::Optional<std::string> toString() const;
80 RuntimeCoeffects toAmbient() const;
81 RuntimeCoeffects toRequired() const;
83 // Returns the corresponding shallow bits for coeffects that are local
84 RuntimeCoeffects toShallowWithLocals() const;
86 static StaticCoeffects fromValue(uint16_t value) {
87 return StaticCoeffects{value};
90 uint16_t value() const { return m_data; }
92 static StaticCoeffects none() {
93 return StaticCoeffects::fromValue(0);
96 // This operator is equivalent to & of [coeffectA & coeffectB]
97 StaticCoeffects& operator|=(const StaticCoeffects);
99 template<class SerDe>
100 void serde(SerDe& sd) {
101 sd(m_data);
104 private:
105 // Returns the local bits
106 storage_t locals() const;
108 private:
109 explicit StaticCoeffects(uint16_t data) : m_data(data) {}
110 storage_t m_data;
113 static_assert(sizeof(StaticCoeffects) == sizeof(uint16_t), "");
114 static_assert(sizeof(StaticCoeffects) == sizeof(RuntimeCoeffects), "");
116 ///////////////////////////////////////////////////////////////////////////////
118 struct CoeffectRule final {
119 struct FunParam {};
120 struct CCParam {};
121 struct CCThis {};
122 struct ClosureInheritFromParent {};
123 struct GeneratorThis {};
125 CoeffectRule() = default;
127 /////////////////////////////////////////////////////////////////////////////
128 // Native coeffect rules ////////////////////////////////////////////////////
130 CoeffectRule(FunParam, uint32_t index)
131 : m_type(Type::FunParam)
132 , m_index(index)
135 CoeffectRule(CCParam, uint32_t index, const StringData* ctx_name)
136 : m_type(Type::CCParam)
137 , m_index(index)
138 , m_name(ctx_name)
139 { assertx(ctx_name); }
141 CoeffectRule(CCThis, const StringData* ctx_name)
142 : m_type(Type::CCThis)
143 , m_name(ctx_name)
144 { assertx(ctx_name); }
146 explicit CoeffectRule(ClosureInheritFromParent)
147 : m_type(Type::ClosureInheritFromParent)
150 explicit CoeffectRule(GeneratorThis)
151 : m_type(Type::GeneratorThis)
154 RuntimeCoeffects emit(const Func*, uint32_t, void*) const;
155 jit::SSATmp* emitJit(jit::irgen::IRGS&, const Func*,
156 uint32_t, jit::SSATmp*) const;
158 bool isClosureInheritFromParent() const;
159 bool isGeneratorThis() const;
161 folly::Optional<std::string> toString(const Func*) const;
162 std::string getDirectiveString() const;
164 template<class SerDe>
165 void serde(SerDe&);
167 private:
168 enum class Type {
169 Invalid = 0,
171 FunParam,
172 CCParam,
173 CCThis,
174 ClosureInheritFromParent,
175 GeneratorThis,
178 Type m_type{Type::Invalid};
179 uint32_t m_index{0};
180 LowPtr<const StringData> m_name{nullptr};
183 ///////////////////////////////////////////////////////////////////////////////