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

Side by Side Diff: src/hydrogen.cc

Issue 90643003: Experimental implementation: Exposing SIMD instructions into JavaScript Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5385 matching lines...) Expand 10 before | Expand all | Expand 10 after
5396 } 5396 }
5397 map->LookupDescriptor(*holder_, *name_, &lookup_); 5397 map->LookupDescriptor(*holder_, *name_, &lookup_);
5398 if (lookup_.IsFound()) return LoadResult(map); 5398 if (lookup_.IsFound()) return LoadResult(map);
5399 } 5399 }
5400 lookup_.NotFound(); 5400 lookup_.NotFound();
5401 return true; 5401 return true;
5402 } 5402 }
5403 5403
5404 5404
5405 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() { 5405 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() {
5406 if (!CanInlinePropertyAccess(*map_)) return IsStringLength(); 5406 if (!CanInlinePropertyAccess(*map_)) {
5407 return IsStringLength() || IsFloat32x4OrInt32x4PropertyCallback();
5408 }
5407 if (IsJSObjectFieldAccessor()) return true; 5409 if (IsJSObjectFieldAccessor()) return true;
5408 if (!LookupDescriptor()) return false; 5410 if (!LookupDescriptor()) return false;
5409 if (lookup_.IsFound()) return true; 5411 if (lookup_.IsFound()) return true;
5410 return LookupInPrototypes(); 5412 return LookupInPrototypes();
5411 } 5413 }
5412 5414
5413 5415
5414 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic( 5416 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
5415 SmallMapList* types) { 5417 SmallMapList* types) {
5416 ASSERT(map_.is_identical_to(types->first())); 5418 ASSERT(map_.is_identical_to(types->first()));
5417 if (!CanLoadMonomorphic()) return false; 5419 if (!CanLoadMonomorphic()) return false;
5418 if (types->length() > kMaxLoadPolymorphism) return false; 5420 if (types->length() > kMaxLoadPolymorphism) return false;
5419 5421
5420 if (IsStringLength()) { 5422 if (IsStringLength()) {
5421 for (int i = 1; i < types->length(); ++i) { 5423 for (int i = 1; i < types->length(); ++i) {
5422 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; 5424 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
5423 } 5425 }
5424 return true; 5426 return true;
5425 } 5427 }
5426 5428
5429 if (IsFloat32x4OrInt32x4PropertyCallback()) {
5430 for (int i = 1; i < types->length(); ++i) {
5431 if (types->at(i)->instance_type() == types->first()->instance_type()) {
5432 return false;
5433 }
5434 }
5435 return true;
5436 }
5437
5427 if (IsArrayLength()) { 5438 if (IsArrayLength()) {
5428 bool is_fast = IsFastElementsKind(map_->elements_kind()); 5439 bool is_fast = IsFastElementsKind(map_->elements_kind());
5429 for (int i = 1; i < types->length(); ++i) { 5440 for (int i = 1; i < types->length(); ++i) {
5430 Handle<Map> test_map = types->at(i); 5441 Handle<Map> test_map = types->at(i);
5431 if (test_map->instance_type() != JS_ARRAY_TYPE) return false; 5442 if (test_map->instance_type() != JS_ARRAY_TYPE) return false;
5432 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) { 5443 if (IsFastElementsKind(test_map->elements_kind()) != is_fast) {
5433 return false; 5444 return false;
5434 } 5445 }
5435 } 5446 }
5436 return true; 5447 return true;
5437 } 5448 }
5438 5449
5439 if (IsJSObjectFieldAccessor()) { 5450 if (IsJSObjectFieldAccessor()) {
5440 InstanceType instance_type = map_->instance_type(); 5451 InstanceType instance_type = map_->instance_type();
5441 for (int i = 1; i < types->length(); ++i) { 5452 for (int i = 1; i < types->length(); ++i) {
5442 if (types->at(i)->instance_type() != instance_type) return false; 5453 if (types->at(i)->instance_type() != instance_type) return false;
5443 } 5454 }
5444 return true; 5455 return true;
5445 } 5456 }
5446 5457
5447 for (int i = 1; i < types->length(); ++i) { 5458 for (int i = 1; i < types->length(); ++i) {
5448 PropertyAccessInfo test_info(isolate(), types->at(i), name_); 5459 PropertyAccessInfo test_info(isolate(), types->at(i), name_);
5449 if (!test_info.IsCompatibleForLoad(this)) return false; 5460 if (!test_info.IsCompatibleForLoad(this)) return false;
5450 } 5461 }
5451 5462
5452 return true; 5463 return true;
5453 } 5464 }
5454 5465
5455 5466
5467 static BuiltinFunctionId NameToId(Isolate* isolate, Handle<String> name,
5468 InstanceType type) {
5469 BuiltinFunctionId id;
5470 if (name->Equals(isolate->heap()->signMask())) {
5471 id = type == FLOAT32x4_TYPE ? kFloat32x4SignMask : kInt32x4SignMask;
5472 } else if (name->Equals(isolate->heap()->x())) {
5473 id = type == FLOAT32x4_TYPE ? kFloat32x4X : kInt32x4X;
5474 } else if (name->Equals(isolate->heap()->y())) {
5475 id = type == FLOAT32x4_TYPE ? kFloat32x4Y : kInt32x4Y;
5476 } else if (name->Equals(isolate->heap()->z())) {
5477 id = type == FLOAT32x4_TYPE ? kFloat32x4Z : kInt32x4Z;
5478 } else if (name->Equals(isolate->heap()->w())) {
5479 id = type == FLOAT32x4_TYPE ? kFloat32x4W : kInt32x4W;
5480 } else if (name->Equals(isolate->heap()->flagX())) {
5481 ASSERT(type == INT32x4_TYPE);
5482 id = kInt32x4FlagX;
5483 } else if (name->Equals(isolate->heap()->flagY())) {
5484 ASSERT(type == INT32x4_TYPE);
5485 id = kInt32x4FlagY;
5486 } else if (name->Equals(isolate->heap()->flagZ())) {
5487 ASSERT(type == INT32x4_TYPE);
5488 id = kInt32x4FlagZ;
5489 } else if (name->Equals(isolate->heap()->flagW())) {
5490 ASSERT(type == INT32x4_TYPE);
5491 id = kInt32x4FlagW;
5492 } else {
5493 UNREACHABLE();
5494 id = kFloat32x4OrInt32x4Unreachable;
5495 }
5496
5497 return id;
5498 }
5499
5500
5501 static bool IsSIMDProperty(Handle<String> name, uint8_t* mask) {
5502 SmartArrayPointer<char> cstring = name->ToCString();
5503 int i = 0;
5504 while (i <= 3) {
5505 int shift = 0;
5506 switch (cstring[i]) {
5507 case 'W':
5508 shift++;
5509 case 'Z':
5510 shift++;
5511 case 'Y':
5512 shift++;
5513 case 'X':
5514 break;
5515 default:
5516 return false;
5517 }
5518 *mask |= (shift << 2*i);
5519 i++;
5520 }
5521
5522 return true;
5523 }
5524
5525
5456 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic( 5526 HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic(
5457 PropertyAccessInfo* info, 5527 PropertyAccessInfo* info,
5458 HValue* object, 5528 HValue* object,
5459 HInstruction* checked_object, 5529 HInstruction* checked_object,
5460 BailoutId ast_id, 5530 BailoutId ast_id,
5461 BailoutId return_id, 5531 BailoutId return_id,
5462 bool can_inline_accessor) { 5532 bool can_inline_accessor) {
5463 5533
5464 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 5534 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
5465 if (info->GetJSObjectFieldAccess(&access)) { 5535 if (info->GetJSObjectFieldAccess(&access)) {
5466 return New<HLoadNamedField>(checked_object, access); 5536 return New<HLoadNamedField>(checked_object, access);
5467 } 5537 }
5468 5538
5469 HValue* checked_holder = checked_object; 5539 HValue* checked_holder = checked_object;
5470 if (info->has_holder()) { 5540 if (info->has_holder()) {
5471 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 5541 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
5472 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 5542 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
5473 } 5543 }
5474 5544
5475 if (!info->lookup()->IsFound()) return graph()->GetConstantUndefined(); 5545 if (!info->lookup()->IsFound()) return graph()->GetConstantUndefined();
5476 5546
5477 if (info->lookup()->IsField()) { 5547 if (info->lookup()->IsField()) {
5548 if (info->map()->constructor()->IsJSFunction()) {
5549 JSFunction* constructor = JSFunction::cast(info->map()->constructor());
5550 String* class_name =
5551 String::cast(constructor->shared()->instance_class_name());
5552 uint8_t mask = 0;
5553 if (class_name->Equals(isolate()->heap()->simd()) &&
5554 IsSIMDProperty(info->name(), &mask) &&
5555 CpuFeatures::IsSupported(SSE2)) {
5556 return New<HConstant>(mask);
5557 }
5558 }
5559
5478 return BuildLoadNamedField(checked_holder, info->access()); 5560 return BuildLoadNamedField(checked_holder, info->access());
5479 } 5561 }
5480 5562
5481 if (info->lookup()->IsPropertyCallbacks()) { 5563 if (info->lookup()->IsPropertyCallbacks()) {
5482 Push(checked_object); 5564 Push(checked_object);
5483 if (FLAG_inline_accessors && 5565 if (FLAG_inline_accessors &&
5484 can_inline_accessor && 5566 can_inline_accessor &&
5485 TryInlineGetter(info->accessor(), ast_id, return_id)) { 5567 TryInlineGetter(info->accessor(), ast_id, return_id)) {
5486 return NULL; 5568 return NULL;
5487 } 5569 }
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
6575 6657
6576 6658
6577 static bool AreStringTypes(SmallMapList* types) { 6659 static bool AreStringTypes(SmallMapList* types) {
6578 for (int i = 0; i < types->length(); i++) { 6660 for (int i = 0; i < types->length(); i++) {
6579 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; 6661 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
6580 } 6662 }
6581 return true; 6663 return true;
6582 } 6664 }
6583 6665
6584 6666
6667 static bool AreInt32x4Types(SmallMapList* types) {
6668 if (types == NULL || types->length() == 0) return false;
6669 for (int i = 0; i < types->length(); i++) {
6670 if (types->at(i)->instance_type() != INT32x4_TYPE) return false;
6671 }
6672 return true;
6673 }
6674
6675
6676 static bool AreFloat32x4Types(SmallMapList* types) {
6677 if (types == NULL || types->length() == 0) return false;
6678 for (int i = 0; i < types->length(); i++) {
6679 if (types->at(i)->instance_type() != FLOAT32x4_TYPE) return false;
6680 }
6681 return true;
6682 }
6683
6684
6585 void HOptimizedGraphBuilder::BuildLoad(Property* expr, 6685 void HOptimizedGraphBuilder::BuildLoad(Property* expr,
6586 BailoutId ast_id) { 6686 BailoutId ast_id) {
6587 HInstruction* instr = NULL; 6687 HInstruction* instr = NULL;
6588 if (expr->IsStringAccess()) { 6688 if (expr->IsStringAccess()) {
6589 HValue* index = Pop(); 6689 HValue* index = Pop();
6590 HValue* string = Pop(); 6690 HValue* string = Pop();
6591 HInstruction* char_code = BuildStringCharCodeAt(string, index); 6691 HInstruction* char_code = BuildStringCharCodeAt(string, index);
6592 AddInstruction(char_code); 6692 AddInstruction(char_code);
6593 instr = NewUncasted<HStringCharFromCode>(char_code); 6693 instr = NewUncasted<HStringCharFromCode>(char_code);
6594 6694
(...skipping 10 matching lines...) Expand all
6605 ComputeReceiverTypes(expr, object, &types); 6705 ComputeReceiverTypes(expr, object, &types);
6606 ASSERT(types != NULL); 6706 ASSERT(types != NULL);
6607 6707
6608 if (types->length() > 0) { 6708 if (types->length() > 0) {
6609 PropertyAccessInfo info(isolate(), types->first(), name); 6709 PropertyAccessInfo info(isolate(), types->first(), name);
6610 if (!info.CanLoadAsMonomorphic(types)) { 6710 if (!info.CanLoadAsMonomorphic(types)) {
6611 return HandlePolymorphicLoadNamedField( 6711 return HandlePolymorphicLoadNamedField(
6612 ast_id, expr->LoadId(), object, types, name); 6712 ast_id, expr->LoadId(), object, types, name);
6613 } 6713 }
6614 6714
6615 BuildCheckHeapObject(object);
6616 HInstruction* checked_object;
6617 if (AreStringTypes(types)) { 6715 if (AreStringTypes(types)) {
6618 checked_object = 6716 BuildCheckHeapObject(object);
6717 HInstruction* checked_object =
6619 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 6718 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
6719 instr = BuildLoadMonomorphic(
6720 &info, object, checked_object, ast_id, expr->LoadId());
6721 } else if (AreFloat32x4Types(types) && CpuFeatures::IsSupported(SSE2)) {
6722 Handle<JSFunction> function(
6723 isolate()->native_context()->float32x4_function());
6724 HInstruction* constant_function = Add<HConstant>(function);
6725 HObjectAccess map_access = HObjectAccess::ForPrototypeOrInitialMap();
6726 HInstruction* map = Add<HLoadNamedField>(constant_function, map_access);
6727 HObjectAccess prototype_access = HObjectAccess::ForMapPrototype();
6728 HInstruction* prototype = Add<HLoadNamedField>(map, prototype_access);
6729 Handle<Map> initial_function_prototype_map(
6730 isolate()->native_context()->float32x4_function_prototype_map());
6731 BuildCheckMap(prototype, initial_function_prototype_map);
6732 BuiltinFunctionId id = NameToId(isolate(), name, FLOAT32x4_TYPE);
6733 instr = NewUncasted<HUnarySIMDOperation>(object, id);
6734 } else if (AreInt32x4Types(types) && CpuFeatures::IsSupported(SSE2)) {
6735 Handle<JSFunction> function(
6736 isolate()->native_context()->int32x4_function());
6737 HInstruction* constant_function = Add<HConstant>(function);
6738 HObjectAccess map_access = HObjectAccess::ForPrototypeOrInitialMap();
6739 HInstruction* map = Add<HLoadNamedField>(constant_function, map_access);
6740 HObjectAccess prototype_access = HObjectAccess::ForMapPrototype();
6741 HInstruction* prototype = Add<HLoadNamedField>(map, prototype_access);
6742 Handle<Map> initial_function_prototype_map(
6743 isolate()->native_context()->int32x4_function_prototype_map());
6744 BuildCheckMap(prototype, initial_function_prototype_map);
6745 BuiltinFunctionId id = NameToId(isolate(), name, INT32x4_TYPE);
6746 instr = NewUncasted<HUnarySIMDOperation>(object, id);
6620 } else { 6747 } else {
6621 checked_object = Add<HCheckMaps>(object, types); 6748 BuildCheckHeapObject(object);
6749 HInstruction* checked_object = Add<HCheckMaps>(object, types);
6750 instr = BuildLoadMonomorphic(
6751 &info, object, checked_object, ast_id, expr->LoadId());
6622 } 6752 }
6623 instr = BuildLoadMonomorphic(
6624 &info, object, checked_object, ast_id, expr->LoadId());
6625 if (instr == NULL) return; 6753 if (instr == NULL) return;
6626 if (instr->IsLinked()) return ast_context()->ReturnValue(instr); 6754 if (instr->IsLinked()) return ast_context()->ReturnValue(instr);
6627 } else { 6755 } else {
6628 instr = BuildLoadNamedGeneric(object, name, expr); 6756 instr = BuildLoadNamedGeneric(object, name, expr);
6629 } 6757 }
6630 6758
6631 } else { 6759 } else {
6632 HValue* key = Pop(); 6760 HValue* key = Pop();
6633 HValue* obj = Pop(); 6761 HValue* obj = Pop();
6634 6762
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
7376 if (expr->arguments()->length() == 2) { 7504 if (expr->arguments()->length() == 2) {
7377 HValue* right = Pop(); 7505 HValue* right = Pop();
7378 HValue* left = Pop(); 7506 HValue* left = Pop();
7379 Drop(1); // Receiver. 7507 Drop(1); // Receiver.
7380 HInstruction* op = HMul::NewImul(zone(), context(), left, right); 7508 HInstruction* op = HMul::NewImul(zone(), context(), left, right);
7381 if (drop_extra) Drop(1); // Optionally drop the function. 7509 if (drop_extra) Drop(1); // Optionally drop the function.
7382 ast_context()->ReturnInstruction(op, expr->id()); 7510 ast_context()->ReturnInstruction(op, expr->id());
7383 return true; 7511 return true;
7384 } 7512 }
7385 break; 7513 break;
7514 case kFloat32x4Zero:
7515 if (expr->arguments()->length() == 0) {
7516 if (!CpuFeatures::IsSupported(SSE2)) return false;
7517 Drop(1); // Receiver.
7518 HInstruction* op = NewUncasted<HNullarySIMDOperation>(id);
7519 if (drop_extra) Drop(1); // Optionally drop the function.
7520 ast_context()->ReturnInstruction(op, expr->id());
7521 return true;
7522 }
7523 break;
7524 case kSIMDAbs:
7525 case kSIMDNeg:
7526 case kSIMDNegU32:
7527 case kSIMDReciprocal:
7528 case kSIMDReciprocalSqrt:
7529 case kSIMDSqrt:
7530 case kSIMDBitsToFloat32x4:
7531 case kSIMDToFloat32x4:
7532 case kSIMDBitsToInt32x4:
7533 case kSIMDToInt32x4:
7534 case kFloat32x4Splat:
7535 case kInt32x4Splat:
7536 if (expr->arguments()->length() == 1) {
7537 if (!CpuFeatures::IsSupported(SSE2)) return false;
7538 HValue* argument = Pop();
7539 Drop(1); // Receiver.
7540 HInstruction* op = NewUncasted<HUnarySIMDOperation>(argument, id);
7541 if (drop_extra) Drop(1); // Optionally drop the function.
7542 ast_context()->ReturnInstruction(op, expr->id());
7543 return true;
7544 }
7545 break;
7546 case kSIMDAdd:
7547 case kSIMDSub:
7548 case kSIMDMul:
7549 case kSIMDDiv:
7550 case kSIMDMin:
7551 case kSIMDMax:
7552 case kSIMDScale:
7553 case kSIMDAnd:
7554 case kSIMDOr:
7555 case kSIMDXor:
7556 case kSIMDAddU32:
7557 case kSIMDSubU32:
7558 case kSIMDMulU32:
7559 case kSIMDShuffle:
7560 case kSIMDShuffleU32:
7561 case kSIMDLessThan:
7562 case kSIMDLessThanOrEqual:
7563 case kSIMDEqual:
7564 case kSIMDNotEqual:
7565 case kSIMDGreaterThanOrEqual:
7566 case kSIMDGreaterThan:
7567 case kSIMDWithX:
7568 case kSIMDWithY:
7569 case kSIMDWithZ:
7570 case kSIMDWithW:
7571 case kSIMDWithXu32:
7572 case kSIMDWithYu32:
7573 case kSIMDWithZu32:
7574 case kSIMDWithWu32:
7575 case kSIMDWithFlagX:
7576 case kSIMDWithFlagY:
7577 case kSIMDWithFlagZ:
7578 case kSIMDWithFlagW:
7579 if (expr->arguments()->length() == 2) {
7580 if (!CpuFeatures::IsSupported(SSE2)) return false;
7581 HValue* right = Pop();
7582 HValue* left = Pop();
7583 Drop(1); // Receiver.
7584 HInstruction* op = NewUncasted<HBinarySIMDOperation>(left, right, id);
7585 if (drop_extra) Drop(1); // Optionally drop the function.
7586 ast_context()->ReturnInstruction(op, expr->id());
7587 return true;
7588 }
7589 break;
7590 case kSIMDSelect:
7591 case kSIMDShuffleMix:
7592 case kSIMDClamp:
7593 if (expr->arguments()->length() == 3) {
7594 if (!CpuFeatures::IsSupported(SSE2)) return false;
7595 HValue* right = Pop();
7596 HValue* left = Pop();
7597 HValue* value = Pop();
7598 Drop(1); // Receiver.
7599 HInstruction* op =
7600 NewUncasted<HTernarySIMDOperation>(value, left, right, id);
7601 if (drop_extra) Drop(1); // Optionally drop the function.
7602 ast_context()->ReturnInstruction(op, expr->id());
7603 return true;
7604 }
7605 break;
7606 case kFloat32x4Constructor:
7607 case kInt32x4Constructor:
7608 case kInt32x4Bool:
7609 if (expr->arguments()->length() == 4) {
7610 if (!CpuFeatures::IsSupported(SSE2)) return false;
7611 HValue* w = Pop();
7612 HValue* z = Pop();
7613 HValue* y = Pop();
7614 HValue* x = Pop();
7615 Drop(1); // Receiver.
7616 HInstruction* op =
7617 NewUncasted<HQuarternarySIMDOperation>(x, y, z, w, id);
7618 if (drop_extra) Drop(1); // Optionally drop the function.
7619 ast_context()->ReturnInstruction(op, expr->id());
7620 return true;
7621 }
7622 break;
7386 default: 7623 default:
7387 // Not supported for inlining yet. 7624 // Not supported for inlining yet.
7388 break; 7625 break;
7389 } 7626 }
7390 return false; 7627 return false;
7391 } 7628 }
7392 7629
7393 7630
7394 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 7631 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
7395 Call* expr, 7632 Call* expr,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
7500 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 7737 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7501 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7738 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7502 HValue* right = Pop(); 7739 HValue* right = Pop();
7503 HValue* left = Pop(); 7740 HValue* left = Pop();
7504 Drop(1); // Receiver. 7741 Drop(1); // Receiver.
7505 HInstruction* result = HMul::NewImul(zone(), context(), left, right); 7742 HInstruction* result = HMul::NewImul(zone(), context(), left, right);
7506 ast_context()->ReturnInstruction(result, expr->id()); 7743 ast_context()->ReturnInstruction(result, expr->id());
7507 return true; 7744 return true;
7508 } 7745 }
7509 break; 7746 break;
7747 case kFloat32x4Zero:
7748 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
7749 if (!CpuFeatures::IsSupported(SSE2)) return false;
7750 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7751 Drop(1); // Receiver.
7752 HInstruction* op = NewUncasted<HNullarySIMDOperation>(id);
7753 ast_context()->ReturnInstruction(op, expr->id());
7754 return true;
7755 }
7756 break;
7757 case kSIMDAbs:
7758 case kSIMDNeg:
7759 case kSIMDNegU32:
7760 case kSIMDReciprocal:
7761 case kSIMDReciprocalSqrt:
7762 case kSIMDSqrt:
7763 case kSIMDBitsToFloat32x4:
7764 case kSIMDToFloat32x4:
7765 case kSIMDBitsToInt32x4:
7766 case kSIMDToInt32x4:
7767 case kFloat32x4Splat:
7768 case kInt32x4Splat:
7769 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
7770 if (!CpuFeatures::IsSupported(SSE2)) return false;
7771 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7772 HValue* argument = Pop();
7773 Drop(1); // Receiver.
7774 HInstruction* op = NewUncasted<HUnarySIMDOperation>(argument, id);
7775 ast_context()->ReturnInstruction(op, expr->id());
7776 return true;
7777 }
7778 break;
7779 case kSIMDAdd:
7780 case kSIMDSub:
7781 case kSIMDMul:
7782 case kSIMDDiv:
7783 case kSIMDMin:
7784 case kSIMDMax:
7785 case kSIMDScale:
7786 case kSIMDAnd:
7787 case kSIMDOr:
7788 case kSIMDXor:
7789 case kSIMDAddU32:
7790 case kSIMDSubU32:
7791 case kSIMDMulU32:
7792 case kSIMDShuffle:
7793 case kSIMDShuffleU32:
7794 case kSIMDLessThan:
7795 case kSIMDLessThanOrEqual:
7796 case kSIMDEqual:
7797 case kSIMDNotEqual:
7798 case kSIMDGreaterThanOrEqual:
7799 case kSIMDGreaterThan:
7800 case kSIMDWithX:
7801 case kSIMDWithY:
7802 case kSIMDWithZ:
7803 case kSIMDWithW:
7804 case kSIMDWithXu32:
7805 case kSIMDWithYu32:
7806 case kSIMDWithZu32:
7807 case kSIMDWithWu32:
7808 case kSIMDWithFlagX:
7809 case kSIMDWithFlagY:
7810 case kSIMDWithFlagZ:
7811 case kSIMDWithFlagW:
7812 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7813 if (!CpuFeatures::IsSupported(SSE2)) return false;
7814 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7815 HValue* right = Pop();
7816 HValue* left = Pop();
7817 Drop(1); // Receiver.
7818 HInstruction* op = NewUncasted<HBinarySIMDOperation>(left, right, id);
7819 ast_context()->ReturnInstruction(op, expr->id());
7820 return true;
7821 }
7822 break;
7823 case kSIMDSelect:
7824 case kSIMDShuffleMix:
7825 case kSIMDClamp:
7826 if (argument_count == 4 && check_type == RECEIVER_MAP_CHECK) {
7827 if (!CpuFeatures::IsSupported(SSE2)) return false;
7828 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7829 HValue* right = Pop();
7830 HValue* left = Pop();
7831 HValue* value = Pop();
7832 Drop(1); // Receiver.
7833 HInstruction* op =
7834 NewUncasted<HTernarySIMDOperation>(value, left, right, id);
7835 ast_context()->ReturnInstruction(op, expr->id());
7836 return true;
7837 }
7838 break;
7839 case kInt32x4Bool:
7840 if (argument_count == 5 && check_type == RECEIVER_MAP_CHECK) {
7841 if (!CpuFeatures::IsSupported(SSE2)) return false;
7842 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7843 HValue* w = Pop();
7844 HValue* z = Pop();
7845 HValue* y = Pop();
7846 HValue* x = Pop();
7847 Drop(1); // Receiver.
7848 HValue* context = environment()->context();
7849 HInstruction* op =
7850 HQuarternarySIMDOperation::New(zone(), context, x, y, z, w, id);
7851 op->set_position(expr->position());
7852 ast_context()->ReturnInstruction(op, expr->id());
7853 return true;
7854 }
7855 break;
7856 case kFloat32x4ArrayGetAt:
7857 case kInt32x4ArrayGetAt:
7858 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
7859 if (!CpuFeatures::IsSupported(SSE2)) return false;
7860 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7861 HValue* key = Pop();
7862 HValue* typed32x4_array = Pop();
7863 ASSERT(typed32x4_array == receiver);
7864 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
7865 typed32x4_array, key, NULL,
7866 receiver_map->instance_type() == JS_ARRAY_TYPE,
7867 receiver_map->elements_kind(),
7868 false, // is_store.
7869 NEVER_RETURN_HOLE, // load_mode.
7870 STANDARD_STORE);
7871 ast_context()->ReturnValue(instr);
7872 return true;
7873 }
7874 break;
7875 case kFloat32x4ArraySetAt:
7876 case kInt32x4ArraySetAt:
7877 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7878 if (!CpuFeatures::IsSupported(SSE2)) return false;
7879 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7880 HValue* value = Pop();
7881 HValue* key = Pop();
7882 HValue* typed32x4_array = Pop();
7883 ASSERT(typed32x4_array == receiver);
7884 // TODO(haitao): add STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS.
7885 KeyedAccessStoreMode store_mode = STANDARD_STORE;
7886 BuildUncheckedMonomorphicElementAccess(
7887 typed32x4_array, key, value,
7888 receiver_map->instance_type() == JS_ARRAY_TYPE,
7889 receiver_map->elements_kind(),
7890 true, // is_store.
7891 NEVER_RETURN_HOLE, // load_mode.
7892 store_mode);
7893 Push(value);
7894 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
7895 ast_context()->ReturnValue(Pop());
7896 return true;
7897 }
7898 break;
7510 default: 7899 default:
7511 // Not yet supported for inlining. 7900 // Not yet supported for inlining.
7512 break; 7901 break;
7513 } 7902 }
7514 return false; 7903 return false;
7515 } 7904 }
7516 7905
7517 7906
7518 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 7907 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
7519 Expression* callee = expr->expression(); 7908 Expression* callee = expr->expression();
(...skipping 3128 matching lines...) Expand 10 before | Expand all | Expand 10 after
10648 Zone* zone) { 11037 Zone* zone) {
10649 if (range != NULL && !range->IsEmpty()) { 11038 if (range != NULL && !range->IsEmpty()) {
10650 PrintIndent(); 11039 PrintIndent();
10651 trace_.Add("%d %s", range->id(), type); 11040 trace_.Add("%d %s", range->id(), type);
10652 if (range->HasRegisterAssigned()) { 11041 if (range->HasRegisterAssigned()) {
10653 LOperand* op = range->CreateAssignedOperand(zone); 11042 LOperand* op = range->CreateAssignedOperand(zone);
10654 int assigned_reg = op->index(); 11043 int assigned_reg = op->index();
10655 if (op->IsDoubleRegister()) { 11044 if (op->IsDoubleRegister()) {
10656 trace_.Add(" \"%s\"", 11045 trace_.Add(" \"%s\"",
10657 DoubleRegister::AllocationIndexToString(assigned_reg)); 11046 DoubleRegister::AllocationIndexToString(assigned_reg));
11047 } else if (op->IsFloat32x4Register()) {
11048 trace_.Add(" \"%s\"",
11049 Float32x4Register::AllocationIndexToString(assigned_reg));
11050 } else if (op->IsInt32x4Register()) {
11051 trace_.Add(" \"%s\"",
11052 Int32x4Register::AllocationIndexToString(assigned_reg));
10658 } else { 11053 } else {
10659 ASSERT(op->IsRegister()); 11054 ASSERT(op->IsRegister());
10660 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); 11055 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg));
10661 } 11056 }
10662 } else if (range->IsSpilled()) { 11057 } else if (range->IsSpilled()) {
10663 LOperand* op = range->TopLevel()->GetSpillOperand(); 11058 LOperand* op = range->TopLevel()->GetSpillOperand();
10664 if (op->IsDoubleStackSlot()) { 11059 if (op->IsDoubleStackSlot()) {
10665 trace_.Add(" \"double_stack:%d\"", op->index()); 11060 trace_.Add(" \"double_stack:%d\"", op->index());
11061 } else if (op->IsFloat32x4StackSlot()) {
11062 trace_.Add(" \"float32x4_stack:%d\"", op->index());
11063 } else if (op->IsInt32x4StackSlot()) {
11064 trace_.Add(" \"int32x4_stack:%d\"", op->index());
10666 } else { 11065 } else {
10667 ASSERT(op->IsStackSlot()); 11066 ASSERT(op->IsStackSlot());
10668 trace_.Add(" \"stack:%d\"", op->index()); 11067 trace_.Add(" \"stack:%d\"", op->index());
10669 } 11068 }
10670 } 11069 }
10671 int parent_index = -1; 11070 int parent_index = -1;
10672 if (range->IsChild()) { 11071 if (range->IsChild()) {
10673 parent_index = range->parent()->id(); 11072 parent_index = range->parent()->id();
10674 } else { 11073 } else {
10675 parent_index = range->id(); 11074 parent_index = range->id();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
10785 if (ShouldProduceTraceOutput()) { 11184 if (ShouldProduceTraceOutput()) {
10786 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11185 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10787 } 11186 }
10788 11187
10789 #ifdef DEBUG 11188 #ifdef DEBUG
10790 graph_->Verify(false); // No full verify. 11189 graph_->Verify(false); // No full verify.
10791 #endif 11190 #endif
10792 } 11191 }
10793 11192
10794 } } // namespace v8::internal 11193 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698