|
31 | 31 | #include "ir/iteration.h" |
32 | 32 | #include "ir/literal-utils.h" |
33 | 33 | #include "ir/properties.h" |
| 34 | +#include "ir/utils.h" |
34 | 35 | #include "pass.h" |
35 | 36 | #include "support/colors.h" |
36 | 37 | #include "support/command-line.h" |
|
42 | 43 | #include "wasm-builder.h" |
43 | 44 | #include "wasm-io.h" |
44 | 45 | #include "wasm-validator.h" |
| 46 | + |
45 | 47 | #ifdef _WIN32 |
46 | 48 | #ifndef NOMINMAX |
47 | 49 | #define NOMINMAX |
@@ -71,6 +73,7 @@ std::string GetLastErrorStdStr() { |
71 | 73 | return std::string(); |
72 | 74 | } |
73 | 75 | #endif |
| 76 | + |
74 | 77 | using namespace wasm; |
75 | 78 |
|
76 | 79 | // A timeout on every execution of the command. |
@@ -1139,33 +1142,47 @@ struct Reducer |
1139 | 1142 | return false; |
1140 | 1143 | } |
1141 | 1144 |
|
1142 | | - // try to replace a concrete value with a trivial constant |
| 1145 | + // Try to replace a concrete value with a trivial constant. |
1143 | 1146 | bool tryToReduceCurrentToConst() { |
1144 | 1147 | auto* curr = getCurrent(); |
1145 | | - if (curr->is<Const>()) { |
1146 | | - return false; |
1147 | | - } |
1148 | | - // try to replace with a trivial value |
1149 | | - if (curr->type.isNullable()) { |
| 1148 | + |
| 1149 | + // References. |
| 1150 | + if (curr->type.isNullable() && !curr->is<RefNull>()) { |
1150 | 1151 | RefNull* n = builder->makeRefNull(curr->type.getHeapType()); |
1151 | 1152 | return tryToReplaceCurrent(n); |
1152 | 1153 | } |
| 1154 | + |
| 1155 | + // Tuples. |
1153 | 1156 | if (curr->type.isTuple() && curr->type.isDefaultable()) { |
1154 | 1157 | Expression* n = |
1155 | 1158 | builder->makeConstantExpression(Literal::makeZeros(curr->type)); |
| 1159 | + if (ExpressionAnalyzer::equal(n, curr)) { |
| 1160 | + return false; |
| 1161 | + } |
1156 | 1162 | return tryToReplaceCurrent(n); |
1157 | 1163 | } |
| 1164 | + |
| 1165 | + // Numbers. We try to replace them with a 0 or a 1. |
1158 | 1166 | if (!curr->type.isNumber()) { |
1159 | 1167 | return false; |
1160 | 1168 | } |
1161 | | - // It's a number: try to replace it with a 0 or a 1 (trying more values |
1162 | | - // could make sense too, but these handle most cases). |
| 1169 | + auto* existing = curr->dynCast<Const>(); |
| 1170 | + if (existing && existing->value.isZero()) { |
| 1171 | + // It's already a zero. |
| 1172 | + return false; |
| 1173 | + } |
1163 | 1174 | auto* c = builder->makeConst(Literal::makeZero(curr->type)); |
1164 | 1175 | if (tryToReplaceCurrent(c)) { |
1165 | 1176 | return true; |
1166 | 1177 | } |
| 1178 | + // It's not a zero, and can't be replaced with a zero. Try to make it a one, |
| 1179 | + // if it isn't already. |
| 1180 | + if (existing && |
| 1181 | + existing->value == Literal::makeFromInt32(1, existing->type)) { |
| 1182 | + // It's already a one. |
| 1183 | + return false; |
| 1184 | + } |
1167 | 1185 | c->value = Literal::makeOne(curr->type); |
1168 | | - c->type = curr->type; |
1169 | 1186 | return tryToReplaceCurrent(c); |
1170 | 1187 | } |
1171 | 1188 |
|
|
0 commit comments