20
20
#include < variant>
21
21
22
22
#include " ir/properties.h"
23
+ #include " support/utilities.h"
23
24
#include " wasm-builder.h"
24
25
#include " wasm.h"
25
26
@@ -85,6 +86,45 @@ struct PossibleConstantValues {
85
86
// identify a constant value here.
86
87
void noteUnknown () { value = Many (); }
87
88
89
+ // Modify the possible constant to account for being written to or read from a
90
+ // possibly-packed field. When used to model a read, `isSigned` controls
91
+ // whether the value will be sign-extended or not.
92
+ void packForField (const Field& field, bool isSigned = false ) {
93
+ if (field.type != Type::i32 || !field.isPacked ()) {
94
+ return ;
95
+ }
96
+ if (!isConstant ()) {
97
+ // Nothing to pack.
98
+ return ;
99
+ }
100
+ if (isConstantGlobal ()) {
101
+ // Cannot track global and bit masking simultaneously, so give up.
102
+ noteUnknown ();
103
+ return ;
104
+ }
105
+ assert (isConstantLiteral ());
106
+ auto val = getConstantLiteral ();
107
+ assert (val.type == Type::i32 );
108
+ switch (field.packedType ) {
109
+ case Field::i8 :
110
+ if (isSigned) {
111
+ value = val.extendS8 ();
112
+ } else {
113
+ value = val.and_ (Literal (uint32_t (0xff )));
114
+ }
115
+ break ;
116
+ case Field::i16 :
117
+ if (isSigned) {
118
+ value = val.extendS16 ();
119
+ } else {
120
+ value = val.and_ (Literal (uint32_t (0xffff )));
121
+ }
122
+ break ;
123
+ case Field::not_packed:
124
+ WASM_UNREACHABLE (" unexpected packed type" );
125
+ }
126
+ }
127
+
88
128
// Combine the information in a given PossibleConstantValues to this one. This
89
129
// is the same as if we have called note*() on us with all the history of
90
130
// calls to that other object.
@@ -109,28 +149,6 @@ struct PossibleConstantValues {
109
149
return true ;
110
150
}
111
151
112
- // Nulls compare equal, and we could consider any of the input nulls as the
113
- // combination of the two (as any of them would be valid to place in the
114
- // location we are working to optimize). In order to have simple symmetric
115
- // behavior here, which does not depend on the order of the inputs, use the
116
- // LUB.
117
- if (isNull () && other.isNull ()) {
118
- auto type = getConstantLiteral ().type .getHeapType ();
119
- auto otherType = other.getConstantLiteral ().type .getHeapType ();
120
- auto lub = HeapType::getLeastUpperBound (type, otherType);
121
- if (!lub) {
122
- // TODO: Remove this workaround once we have bottom types to assign to
123
- // null literals.
124
- value = Many ();
125
- return true ;
126
- }
127
- if (*lub != type) {
128
- value = Literal::makeNull (*lub);
129
- return true ;
130
- }
131
- return false ;
132
- }
133
-
134
152
return false ;
135
153
}
136
154
0 commit comments