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

Side by Side Diff: src/compiler/typer.cc

Issue 1019883002: [turbofan] Add explicit set for nodes with weakened types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months 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 | « no previous file | 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/base/flags.h" 5 #include "src/base/flags.h"
6 #include "src/bootstrapper.h" 6 #include "src/bootstrapper.h"
7 #include "src/compiler/graph-reducer.h" 7 #include "src/compiler/graph-reducer.h"
8 #include "src/compiler/js-operator.h" 8 #include "src/compiler/js-operator.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 205 }
206 206
207 207
208 Typer::~Typer() { 208 Typer::~Typer() {
209 graph_->RemoveDecorator(decorator_); 209 graph_->RemoveDecorator(decorator_);
210 } 210 }
211 211
212 212
213 class Typer::Visitor : public Reducer { 213 class Typer::Visitor : public Reducer {
214 public: 214 public:
215 explicit Visitor(Typer* typer) : typer_(typer) {} 215 explicit Visitor(Typer* typer)
216 : typer_(typer), weakened_nodes_(typer->zone()) {}
216 217
217 Reduction Reduce(Node* node) OVERRIDE { 218 Reduction Reduce(Node* node) OVERRIDE {
218 if (node->op()->ValueOutputCount() == 0) return NoChange(); 219 if (node->op()->ValueOutputCount() == 0) return NoChange();
219 switch (node->opcode()) { 220 switch (node->opcode()) {
220 #define DECLARE_CASE(x) \ 221 #define DECLARE_CASE(x) \
221 case IrOpcode::k##x: \ 222 case IrOpcode::k##x: \
222 return UpdateBounds(node, TypeBinaryOp(node, x##Typer)); 223 return UpdateBounds(node, TypeBinaryOp(node, x##Typer));
223 JS_SIMPLE_BINOP_LIST(DECLARE_CASE) 224 JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
224 #undef DECLARE_CASE 225 #undef DECLARE_CASE
225 226
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 } 274 }
274 UNREACHABLE(); 275 UNREACHABLE();
275 return Bounds(); 276 return Bounds();
276 } 277 }
277 278
278 Type* TypeConstant(Handle<Object> value); 279 Type* TypeConstant(Handle<Object> value);
279 280
280 private: 281 private:
281 Typer* typer_; 282 Typer* typer_;
282 MaybeHandle<Context> context_; 283 MaybeHandle<Context> context_;
284 ZoneSet<NodeId> weakened_nodes_;
283 285
284 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); 286 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
285 DECLARE_METHOD(Start) 287 DECLARE_METHOD(Start)
286 VALUE_OP_LIST(DECLARE_METHOD) 288 VALUE_OP_LIST(DECLARE_METHOD)
287 #undef DECLARE_METHOD 289 #undef DECLARE_METHOD
288 290
289 Bounds BoundsOrNone(Node* node) { 291 Bounds BoundsOrNone(Node* node) {
290 return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node) 292 return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node)
291 : Bounds(Type::None()); 293 : Bounds(Type::None());
292 } 294 }
293 295
294 Bounds Operand(Node* node, int i) { 296 Bounds Operand(Node* node, int i) {
295 Node* operand_node = NodeProperties::GetValueInput(node, i); 297 Node* operand_node = NodeProperties::GetValueInput(node, i);
296 return BoundsOrNone(operand_node); 298 return BoundsOrNone(operand_node);
297 } 299 }
298 300
299 Bounds WrapContextBoundsForInput(Node* node); 301 Bounds WrapContextBoundsForInput(Node* node);
300 Type* Weaken(Type* current_type, Type* previous_type); 302 Type* Weaken(Node* node, Type* current_type, Type* previous_type);
301 303
302 Zone* zone() { return typer_->zone(); } 304 Zone* zone() { return typer_->zone(); }
303 Isolate* isolate() { return typer_->isolate(); } 305 Isolate* isolate() { return typer_->isolate(); }
304 Graph* graph() { return typer_->graph(); } 306 Graph* graph() { return typer_->graph(); }
305 MaybeHandle<Context> context() { return typer_->context(); } 307 MaybeHandle<Context> context() { return typer_->context(); }
306 308
309 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
310 bool IsWeakened(NodeId node_id) {
311 return weakened_nodes_.find(node_id) != weakened_nodes_.end();
312 }
313
307 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); 314 typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
308 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); 315 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
309 316
310 Bounds TypeUnaryOp(Node* node, UnaryTyperFun); 317 Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
311 Bounds TypeBinaryOp(Node* node, BinaryTyperFun); 318 Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
312 319
313 enum ComparisonOutcomeFlags { 320 enum ComparisonOutcomeFlags {
314 kComparisonTrue = 1, 321 kComparisonTrue = 1,
315 kComparisonFalse = 2, 322 kComparisonFalse = 2,
316 kComparisonUndefined = 4 323 kComparisonUndefined = 4
(...skipping 27 matching lines...) Expand all
344 static Type* JSUnaryNotTyper(Type*, Typer*); 351 static Type* JSUnaryNotTyper(Type*, Typer*);
345 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); 352 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
346 static Type* JSCallFunctionTyper(Type*, Typer*); 353 static Type* JSCallFunctionTyper(Type*, Typer*);
347 354
348 Reduction UpdateBounds(Node* node, Bounds current) { 355 Reduction UpdateBounds(Node* node, Bounds current) {
349 if (NodeProperties::IsTyped(node)) { 356 if (NodeProperties::IsTyped(node)) {
350 // Widen the bounds of a previously typed node. 357 // Widen the bounds of a previously typed node.
351 Bounds previous = NodeProperties::GetBounds(node); 358 Bounds previous = NodeProperties::GetBounds(node);
352 if (node->opcode() == IrOpcode::kPhi) { 359 if (node->opcode() == IrOpcode::kPhi) {
353 // Speed up termination in the presence of range types: 360 // Speed up termination in the presence of range types:
354 current.upper = Weaken(current.upper, previous.upper); 361 current.upper = Weaken(node, current.upper, previous.upper);
355 current.lower = Weaken(current.lower, previous.lower); 362 current.lower = Weaken(node, current.lower, previous.lower);
356 } 363 }
357 364
358 // Types should not get less precise. 365 // Types should not get less precise.
359 DCHECK(previous.lower->Is(current.lower)); 366 DCHECK(previous.lower->Is(current.lower));
360 DCHECK(previous.upper->Is(current.upper)); 367 DCHECK(previous.upper->Is(current.upper));
361 368
362 NodeProperties::SetBounds(node, current); 369 NodeProperties::SetBounds(node, current);
363 if (!(previous.Narrows(current) && current.Narrows(previous))) { 370 if (!(previous.Narrows(current) && current.Narrows(previous))) {
364 // If something changed, revisit all uses. 371 // If something changed, revisit all uses.
365 return Changed(node); 372 return Changed(node);
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { 1288 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
1282 return Bounds::Unbounded(zone()); 1289 return Bounds::Unbounded(zone());
1283 } 1290 }
1284 1291
1285 1292
1286 // Returns a somewhat larger range if we previously assigned 1293 // Returns a somewhat larger range if we previously assigned
1287 // a (smaller) range to this node. This is used to speed up 1294 // a (smaller) range to this node. This is used to speed up
1288 // the fixpoint calculation in case there appears to be a loop 1295 // the fixpoint calculation in case there appears to be a loop
1289 // in the graph. In the current implementation, we are 1296 // in the graph. In the current implementation, we are
1290 // increasing the limits to the closest power of two. 1297 // increasing the limits to the closest power of two.
1291 Type* Typer::Visitor::Weaken(Type* current_type, Type* previous_type) { 1298 Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
1299 Type* previous_type) {
1292 static const double kWeakenMinLimits[] = { 1300 static const double kWeakenMinLimits[] = {
1293 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0, 1301 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1294 -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0, 1302 -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1295 -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0, 1303 -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1296 -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0, 1304 -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1297 -70368744177664.0, -140737488355328.0, -281474976710656.0, 1305 -70368744177664.0, -140737488355328.0, -281474976710656.0,
1298 -562949953421312.0}; 1306 -562949953421312.0};
1299 static const double kWeakenMaxLimits[] = { 1307 static const double kWeakenMaxLimits[] = {
1300 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, 1308 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1301 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, 1309 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1302 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, 1310 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1303 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, 1311 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1304 70368744177663.0, 140737488355327.0, 281474976710655.0, 1312 70368744177663.0, 140737488355327.0, 281474976710655.0,
1305 562949953421311.0}; 1313 562949953421311.0};
1306 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); 1314 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1307 1315
1308 // If the types have nothing to do with integers, return the types. 1316 // If the types have nothing to do with integers, return the types.
1309 if (!current_type->Maybe(typer_->integer) || 1317 if (!previous_type->Maybe(typer_->integer)) {
1310 !previous_type->Maybe(typer_->integer)) {
1311 return current_type; 1318 return current_type;
1312 } 1319 }
1320 DCHECK(current_type->Maybe(typer_->integer));
1313 1321
1314 Type::RangeType* previous = 1322 Type* current_integer =
1315 Type::Intersect(previous_type, typer_->integer, zone())->GetRange(); 1323 Type::Intersect(current_type, typer_->integer, zone());
1316 Type::RangeType* current = 1324 Type* previous_integer =
1317 Type::Intersect(current_type, typer_->integer, zone())->GetRange(); 1325 Type::Intersect(previous_type, typer_->integer, zone());
1318 if (current == nullptr || previous == nullptr) { 1326
1319 return current_type; 1327 // Once we start weakening a node, we should always weaken.
1328 if (!IsWeakened(node->id())) {
1329 // Only weaken if there is range involved; we should converge quickly
1330 // for all other types (the exception is a union of many constants,
1331 // but we currently do not increase the number of constants in unions).
1332 Type::RangeType* previous = previous_integer->GetRange();
1333 Type::RangeType* current = current_integer->GetRange();
1334 if (current == nullptr || previous == nullptr) {
1335 return current_type;
1336 }
1337 // Range is involved => we are weakening.
1338 SetWeakened(node->id());
1320 } 1339 }
1321 1340
1322 double current_min = current->Min(); 1341 double current_min = current_integer->Min();
1323 double new_min = current_min; 1342 double new_min = current_min;
1324 // Find the closest lower entry in the list of allowed 1343 // Find the closest lower entry in the list of allowed
1325 // minima (or negative infinity if there is no such entry). 1344 // minima (or negative infinity if there is no such entry).
1326 if (current_min != previous->Min()) { 1345 if (current_min != previous_integer->Min()) {
1327 new_min = typer_->integer->AsRange()->Min(); 1346 new_min = typer_->integer->AsRange()->Min();
1328 for (double const min : kWeakenMinLimits) { 1347 for (double const min : kWeakenMinLimits) {
1329 if (min <= current_min) { 1348 if (min <= current_min) {
1330 new_min = min; 1349 new_min = min;
1331 break; 1350 break;
1332 } 1351 }
1333 } 1352 }
1334 } 1353 }
1335 1354
1336 double current_max = current->Max(); 1355 double current_max = current_integer->Max();
1337 double new_max = current_max; 1356 double new_max = current_max;
1338 // Find the closest greater entry in the list of allowed 1357 // Find the closest greater entry in the list of allowed
1339 // maxima (or infinity if there is no such entry). 1358 // maxima (or infinity if there is no such entry).
1340 if (current_max != previous->Max()) { 1359 if (current_max != previous_integer->Max()) {
1341 new_max = typer_->integer->AsRange()->Max(); 1360 new_max = typer_->integer->AsRange()->Max();
1342 for (double const max : kWeakenMaxLimits) { 1361 for (double const max : kWeakenMaxLimits) {
1343 if (max >= current_max) { 1362 if (max >= current_max) {
1344 new_max = max; 1363 new_max = max;
1345 break; 1364 break;
1346 } 1365 }
1347 } 1366 }
1348 } 1367 }
1349 1368
1350 return Type::Union(current_type, 1369 return Type::Union(current_type,
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2237 TYPED_ARRAYS(TYPED_ARRAY_CASE)
2219 #undef TYPED_ARRAY_CASE 2238 #undef TYPED_ARRAY_CASE
2220 } 2239 }
2221 } 2240 }
2222 return Type::Constant(value, zone()); 2241 return Type::Constant(value, zone());
2223 } 2242 }
2224 2243
2225 } // namespace compiler 2244 } // namespace compiler
2226 } // namespace internal 2245 } // namespace internal
2227 } // namespace v8 2246 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698