]> git.proxmox.com Git - rustc.git/blob - src/binaryen/src/ir/properties.h
New upstream version 1.23.0+dfsg1
[rustc.git] / src / binaryen / src / ir / properties.h
1 /*
2 * Copyright 2016 WebAssembly Community Group participants
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef wasm_ir_properties_h
18 #define wasm_ir_properties_h
19
20 #include "wasm.h"
21 #include "ir/bits.h"
22
23 namespace wasm {
24
25 struct Properties {
26 static bool emitsBoolean(Expression* curr) {
27 if (auto* unary = curr->dynCast<Unary>()) {
28 return unary->isRelational();
29 } else if (auto* binary = curr->dynCast<Binary>()) {
30 return binary->isRelational();
31 }
32 return false;
33 }
34
35 static bool isSymmetric(Binary* binary) {
36 switch (binary->op) {
37 case AddInt32:
38 case MulInt32:
39 case AndInt32:
40 case OrInt32:
41 case XorInt32:
42 case EqInt32:
43 case NeInt32:
44
45 case AddInt64:
46 case MulInt64:
47 case AndInt64:
48 case OrInt64:
49 case XorInt64:
50 case EqInt64:
51 case NeInt64: return true;
52
53 default: return false;
54 }
55 }
56
57 // Check if an expression is a sign-extend, and if so, returns the value
58 // that is extended, otherwise nullptr
59 static Expression* getSignExtValue(Expression* curr) {
60 if (auto* outer = curr->dynCast<Binary>()) {
61 if (outer->op == ShrSInt32) {
62 if (auto* outerConst = outer->right->dynCast<Const>()) {
63 if (outerConst->value.geti32() != 0) {
64 if (auto* inner = outer->left->dynCast<Binary>()) {
65 if (inner->op == ShlInt32) {
66 if (auto* innerConst = inner->right->dynCast<Const>()) {
67 if (outerConst->value == innerConst->value) {
68 return inner->left;
69 }
70 }
71 }
72 }
73 }
74 }
75 }
76 }
77 return nullptr;
78 }
79
80 // gets the size of the sign-extended value
81 static Index getSignExtBits(Expression* curr) {
82 return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right);
83 }
84
85 // Check if an expression is almost a sign-extend: perhaps the inner shift
86 // is too large. We can split the shifts in that case, which is sometimes
87 // useful (e.g. if we can remove the signext)
88 static Expression* getAlmostSignExt(Expression* curr) {
89 if (auto* outer = curr->dynCast<Binary>()) {
90 if (outer->op == ShrSInt32) {
91 if (auto* outerConst = outer->right->dynCast<Const>()) {
92 if (outerConst->value.geti32() != 0) {
93 if (auto* inner = outer->left->dynCast<Binary>()) {
94 if (inner->op == ShlInt32) {
95 if (auto* innerConst = inner->right->dynCast<Const>()) {
96 if (Bits::getEffectiveShifts(outerConst) <= Bits::getEffectiveShifts(innerConst)) {
97 return inner->left;
98 }
99 }
100 }
101 }
102 }
103 }
104 }
105 }
106 return nullptr;
107 }
108
109 // gets the size of the almost sign-extended value, as well as the
110 // extra shifts, if any
111 static Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) {
112 extraShifts = Bits::getEffectiveShifts(curr->cast<Binary>()->left->cast<Binary>()->right) -
113 Bits::getEffectiveShifts(curr->cast<Binary>()->right);
114 return getSignExtBits(curr);
115 }
116
117 // Check if an expression is a zero-extend, and if so, returns the value
118 // that is extended, otherwise nullptr
119 static Expression* getZeroExtValue(Expression* curr) {
120 if (auto* binary = curr->dynCast<Binary>()) {
121 if (binary->op == AndInt32) {
122 if (auto* c = binary->right->dynCast<Const>()) {
123 if (Bits::getMaskedBits(c->value.geti32())) {
124 return binary->right;
125 }
126 }
127 }
128 }
129 return nullptr;
130 }
131
132 // gets the size of the sign-extended value
133 static Index getZeroExtBits(Expression* curr) {
134 return Bits::getMaskedBits(curr->cast<Binary>()->right->cast<Const>()->value.geti32());
135 }
136 };
137
138 } // wasm
139
140 #endif // wams_ir_properties_h
141