Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 2527083002: [turbofan] Use bounds checks to eliminate subsequent inc/dec overflow checks. (Closed)
Patch Set: Remove dead code Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/redundancy-elimination.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/address-map.h" 9 #include "src/address-map.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 private: 202 private:
203 ZoneVector<UseInfo> input_use_infos_; 203 ZoneVector<UseInfo> input_use_infos_;
204 204
205 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) { 205 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
206 return use1.truncation().IsLessGeneralThan(use2.truncation()); 206 return use1.truncation().IsLessGeneralThan(use2.truncation());
207 } 207 }
208 }; 208 };
209 209
210 #endif // DEBUG 210 #endif // DEBUG
211 211
212 bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
213 Zone* type_zone) {
214 // We assume the inputs are checked Signed32 (or known statically
215 // to be Signed32). Technically, theinputs could also be minus zero, but
216 // that cannot cause overflow.
217 left = Type::Intersect(left, Type::Signed32(), type_zone);
218 right = Type::Intersect(right, Type::Signed32(), type_zone);
219 if (!left->IsInhabited() || !right->IsInhabited()) return false;
220 switch (op->opcode()) {
221 case IrOpcode::kSpeculativeNumberAdd:
222 return (left->Max() + right->Max() > kMaxInt) ||
223 (left->Min() + right->Min() < kMinInt);
224
225 case IrOpcode::kSpeculativeNumberSubtract:
226 return (left->Max() - right->Min() > kMaxInt) ||
227 (left->Min() - right->Max() < kMinInt);
228
229 default:
230 UNREACHABLE();
231 }
232 return true;
233 }
234
212 } // namespace 235 } // namespace
213 236
214
215 class RepresentationSelector { 237 class RepresentationSelector {
216 public: 238 public:
217 // Information for each node tracked during the fixpoint. 239 // Information for each node tracked during the fixpoint.
218 class NodeInfo final { 240 class NodeInfo final {
219 public: 241 public:
220 // Adds new use to the node. Returns true if something has changed 242 // Adds new use to the node. Returns true if something has changed
221 // and the node has to be requeued. 243 // and the node has to be requeued.
222 bool AddUse(UseInfo info) { 244 bool AddUse(UseInfo info) {
223 Truncation old_truncation = truncation_; 245 Truncation old_truncation = truncation_;
224 truncation_ = Truncation::Generalize(truncation_, info.truncation()); 246 truncation_ = Truncation::Generalize(truncation_, info.truncation());
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 1179
1158 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, 1180 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
1159 SimplifiedLowering* lowering) { 1181 SimplifiedLowering* lowering) {
1160 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can 1182 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can
1161 // only eliminate an unused speculative number operation if we know that 1183 // only eliminate an unused speculative number operation if we know that
1162 // the inputs are PlainPrimitive, which excludes everything that's might 1184 // the inputs are PlainPrimitive, which excludes everything that's might
1163 // have side effects or throws during a ToNumber conversion. 1185 // have side effects or throws during a ToNumber conversion.
1164 if (BothInputsAre(node, Type::PlainPrimitive())) { 1186 if (BothInputsAre(node, Type::PlainPrimitive())) {
1165 if (truncation.IsUnused()) return VisitUnused(node); 1187 if (truncation.IsUnused()) return VisitUnused(node);
1166 } 1188 }
1189
1167 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && 1190 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
1168 (GetUpperBound(node)->Is(Type::Signed32()) || 1191 (GetUpperBound(node)->Is(Type::Signed32()) ||
1169 GetUpperBound(node)->Is(Type::Unsigned32()) || 1192 GetUpperBound(node)->Is(Type::Unsigned32()) ||
1170 truncation.IsUsedAsWord32())) { 1193 truncation.IsUsedAsWord32())) {
1171 // => Int32Add/Sub 1194 // => Int32Add/Sub
1172 VisitWord32TruncatingBinop(node); 1195 VisitWord32TruncatingBinop(node);
1173 if (lower()) ChangeToPureOp(node, Int32Op(node)); 1196 if (lower()) ChangeToPureOp(node, Int32Op(node));
1174 return; 1197 return;
1175 } 1198 }
1176 1199
1177 // Try to use type feedback. 1200 // Try to use type feedback.
1178 NumberOperationHint hint = NumberOperationHintOf(node->op()); 1201 NumberOperationHint hint = NumberOperationHintOf(node->op());
1179 1202
1180 // Handle the case when no int32 checks on inputs are necessary 1203 if (hint == NumberOperationHint::kSignedSmall ||
1181 // (but an overflow check is needed on the output). 1204 hint == NumberOperationHint::kSigned32) {
1182 if (BothInputsAre(node, Type::Signed32()) || 1205 Type* left_feedback_type = TypeOf(node->InputAt(0));
1183 (BothInputsAre(node, Type::Signed32OrMinusZero()) && 1206 Type* right_feedback_type = TypeOf(node->InputAt(1));
1184 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { 1207 // Handle the case when no int32 checks on inputs are necessary (but
1185 // If both the inputs the feedback are int32, use the overflow op. 1208 // an overflow check is needed on the output).
1186 if (hint == NumberOperationHint::kSignedSmall || 1209 // TODO(jarin) We should not look at the upper bound because the typer
1187 hint == NumberOperationHint::kSigned32) { 1210 // could have already baked in some feedback into the upper bound.
1211 if (BothInputsAre(node, Type::Signed32()) ||
1212 (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
1213 GetUpperBound(node)->Is(type_cache_.kSafeInteger))) {
1188 VisitBinop(node, UseInfo::TruncatingWord32(), 1214 VisitBinop(node, UseInfo::TruncatingWord32(),
1189 MachineRepresentation::kWord32, Type::Signed32()); 1215 MachineRepresentation::kWord32, Type::Signed32());
1190 if (lower()) ChangeToInt32OverflowOp(node); 1216 } else {
1191 return; 1217 UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint);
1218 // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
1219 // a minus zero check for the right hand side, since we already
1220 // know that the left hand side is a proper Signed32 value,
1221 // potentially guarded by a check.
1222 UseInfo right_use = CheckedUseInfoAsWord32FromHint(
1223 hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
1224 VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
1225 Type::Signed32());
1192 } 1226 }
1193 } 1227 if (lower()) {
1194 1228 if (CanOverflowSigned32(node->op(), left_feedback_type,
1195 if (hint == NumberOperationHint::kSignedSmall || 1229 right_feedback_type, graph_zone())) {
1196 hint == NumberOperationHint::kSigned32) { 1230 ChangeToInt32OverflowOp(node);
1197 UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint); 1231 } else {
1198 // For CheckedInt32Add and CheckedInt32Sub, we don't need to do 1232 ChangeToPureOp(node, Int32Op(node));
1199 // a minus zero check for the right hand side, since we already 1233 }
1200 // know that the left hand side is a proper Signed32 value, 1234 }
1201 // potentially guarded by a check.
1202 UseInfo right_use = CheckedUseInfoAsWord32FromHint(
1203 hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
1204 VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
1205 Type::Signed32());
1206 if (lower()) ChangeToInt32OverflowOp(node);
1207 return; 1235 return;
1208 } 1236 }
1209 1237
1210 // default case => Float64Add/Sub 1238 // default case => Float64Add/Sub
1211 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), 1239 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1212 MachineRepresentation::kFloat64, Type::Number()); 1240 MachineRepresentation::kFloat64, Type::Number());
1213 if (lower()) { 1241 if (lower()) {
1214 ChangeToPureOp(node, Float64Op(node)); 1242 ChangeToPureOp(node, Float64Op(node));
1215 } 1243 }
1216 return; 1244 return;
(...skipping 2194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3411 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3439 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3412 Operator::kNoProperties); 3440 Operator::kNoProperties);
3413 to_number_operator_.set(common()->Call(desc)); 3441 to_number_operator_.set(common()->Call(desc));
3414 } 3442 }
3415 return to_number_operator_.get(); 3443 return to_number_operator_.get();
3416 } 3444 }
3417 3445
3418 } // namespace compiler 3446 } // namespace compiler
3419 } // namespace internal 3447 } // namespace internal
3420 } // namespace v8 3448 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/redundancy-elimination.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698