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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 100483006: [arm] Drop useless branches in full and lithium codegen. (Closed) 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/arm/full-codegen-arm.cc ('k') | src/arm/macro-assembler-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 __ cmp(right, Operand::Zero()); 1407 __ cmp(right, Operand::Zero());
1408 } 1408 }
1409 __ b(pl, &positive); 1409 __ b(pl, &positive);
1410 __ cmp(left, Operand::Zero()); 1410 __ cmp(left, Operand::Zero());
1411 DeoptimizeIf(eq, instr->environment()); 1411 DeoptimizeIf(eq, instr->environment());
1412 __ bind(&positive); 1412 __ bind(&positive);
1413 } 1413 }
1414 1414
1415 // Check for (kMinInt / -1). 1415 // Check for (kMinInt / -1).
1416 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1416 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1417 Label left_not_min_int;
1418 __ cmp(left, Operand(kMinInt)); 1417 __ cmp(left, Operand(kMinInt));
1419 __ b(ne, &left_not_min_int); 1418 __ cmp(right, Operand(-1), eq);
Sven Panne 2013/12/12 13:43:23 Is conditional non-execution of 2 instructions rea
Rodolph Perfetta 2013/12/13 11:31:14 conditional execution of two "simple" instructions
1420 __ cmp(right, Operand(-1));
1421 DeoptimizeIf(eq, instr->environment()); 1419 DeoptimizeIf(eq, instr->environment());
1422 __ bind(&left_not_min_int);
1423 } 1420 }
1424 1421
1425 if (CpuFeatures::IsSupported(SUDIV)) { 1422 if (CpuFeatures::IsSupported(SUDIV)) {
1426 CpuFeatureScope scope(masm(), SUDIV); 1423 CpuFeatureScope scope(masm(), SUDIV);
1427 __ sdiv(result, left, right); 1424 __ sdiv(result, left, right);
1428 1425
1429 if (!instr->hydrogen()->CheckFlag( 1426 if (!instr->hydrogen()->CheckFlag(
1430 HInstruction::kAllUsesTruncatingToInt32)) { 1427 HInstruction::kAllUsesTruncatingToInt32)) {
1431 // Compute remainder and deopt if it's not zero. 1428 // Compute remainder and deopt if it's not zero.
1432 const Register remainder = scratch0(); 1429 const Register remainder = scratch0();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 } else { 1508 } else {
1512 CpuFeatureScope scope(masm(), SUDIV); 1509 CpuFeatureScope scope(masm(), SUDIV);
1513 const Register right = ToRegister(instr->right()); 1510 const Register right = ToRegister(instr->right());
1514 1511
1515 // Check for x / 0. 1512 // Check for x / 0.
1516 __ cmp(right, Operand::Zero()); 1513 __ cmp(right, Operand::Zero());
1517 DeoptimizeIf(eq, instr->environment()); 1514 DeoptimizeIf(eq, instr->environment());
1518 1515
1519 // Check for (kMinInt / -1). 1516 // Check for (kMinInt / -1).
1520 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1517 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1521 Label left_not_min_int;
1522 __ cmp(left, Operand(kMinInt)); 1518 __ cmp(left, Operand(kMinInt));
1523 __ b(ne, &left_not_min_int); 1519 __ cmp(right, Operand(-1), eq);
Sven Panne 2013/12/12 13:43:23 Same here...
1524 __ cmp(right, Operand(-1));
1525 DeoptimizeIf(eq, instr->environment()); 1520 DeoptimizeIf(eq, instr->environment());
1526 __ bind(&left_not_min_int);
1527 } 1521 }
1528 1522
1529 // Check for (0 / -x) that will produce negative zero. 1523 // Check for (0 / -x) that will produce negative zero.
1530 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1524 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1531 __ cmp(right, Operand::Zero()); 1525 __ cmp(right, Operand::Zero());
1532 __ cmp(left, Operand::Zero(), mi); 1526 __ cmp(left, Operand::Zero(), mi);
1533 // "right" can't be null because the code would have already been 1527 // "right" can't be null because the code would have already been
1534 // deoptimized. The Z flag is set only if (right < 0) and (left == 0). 1528 // deoptimized. The Z flag is set only if (right < 0) and (left == 0).
1535 // In this case we need to deoptimize to produce a -0. 1529 // In this case we need to deoptimize to produce a -0.
1536 DeoptimizeIf(eq, instr->environment()); 1530 DeoptimizeIf(eq, instr->environment());
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1885 if (!instr->hydrogen()->value()->IsHeapObject()) { 1879 if (!instr->hydrogen()->value()->IsHeapObject()) {
1886 // If the object is a smi return the object. 1880 // If the object is a smi return the object.
1887 __ SmiTst(input); 1881 __ SmiTst(input);
1888 __ Move(result, input, eq); 1882 __ Move(result, input, eq);
1889 __ b(eq, &done); 1883 __ b(eq, &done);
1890 } 1884 }
1891 1885
1892 // If the object is not a value type, return the object. 1886 // If the object is not a value type, return the object.
1893 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); 1887 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1894 __ Move(result, input, ne); 1888 __ Move(result, input, ne);
1895 __ b(ne, &done); 1889 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset), eq);
1896 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));
1897 1890
1898 __ bind(&done); 1891 __ bind(&done);
1899 } 1892 }
1900 1893
1901 1894
1902 void LCodeGen::DoDateField(LDateField* instr) { 1895 void LCodeGen::DoDateField(LDateField* instr) {
1903 Register object = ToRegister(instr->date()); 1896 Register object = ToRegister(instr->date());
1904 Register result = ToRegister(instr->result()); 1897 Register result = ToRegister(instr->result());
1905 Register scratch = ToRegister(instr->temp()); 1898 Register scratch = ToRegister(instr->temp());
1906 Smi* index = instr->index(); 1899 Smi* index = instr->index();
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after
3440 3433
3441 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 3434 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
3442 Register elem = ToRegister(instr->elements()); 3435 Register elem = ToRegister(instr->elements());
3443 Register result = ToRegister(instr->result()); 3436 Register result = ToRegister(instr->result());
3444 3437
3445 Label done; 3438 Label done;
3446 3439
3447 // If no arguments adaptor frame the number of arguments is fixed. 3440 // If no arguments adaptor frame the number of arguments is fixed.
3448 __ cmp(fp, elem); 3441 __ cmp(fp, elem);
3449 __ mov(result, Operand(scope()->num_parameters())); 3442 __ mov(result, Operand(scope()->num_parameters()));
3450 __ b(eq, &done);
3451 3443
3452 // Arguments adaptor frame present. Get argument length from there. 3444 // Arguments adaptor frame present. Get argument length from there.
3453 __ ldr(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3445 __ ldr(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset), ne);
Sven Panne 2013/12/12 13:43:23 ... and here (3 instructions now)
Rodolph Perfetta 2013/12/13 11:31:14 Here the answer would depend on the surrounding co
Benedikt Meurer 2014/01/02 06:49:28 Reverted this one.
3454 __ ldr(result, 3446 __ ldr(result,
3455 MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3447 MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset), ne);
3456 __ SmiUntag(result); 3448 __ SmiUntag(result, LeaveCC, ne);
3457
3458 // Argument length is in result register.
3459 __ bind(&done);
3460 } 3449 }
3461 3450
3462 3451
3463 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3452 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3464 Register receiver = ToRegister(instr->receiver()); 3453 Register receiver = ToRegister(instr->receiver());
3465 Register function = ToRegister(instr->function()); 3454 Register function = ToRegister(instr->function());
3466 Register result = ToRegister(instr->result()); 3455 Register result = ToRegister(instr->result());
3467 Register scratch = scratch0(); 3456 Register scratch = scratch0();
3468 3457
3469 // If the receiver is null or undefined, we have to pass the global 3458 // If the receiver is null or undefined, we have to pass the global
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 3860
3872 3861
3873 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3862 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3874 DwVfpRegister input = ToDoubleRegister(instr->value()); 3863 DwVfpRegister input = ToDoubleRegister(instr->value());
3875 DwVfpRegister result = ToDoubleRegister(instr->result()); 3864 DwVfpRegister result = ToDoubleRegister(instr->result());
3876 DwVfpRegister temp = double_scratch0(); 3865 DwVfpRegister temp = double_scratch0();
3877 3866
3878 // Note that according to ECMA-262 15.8.2.13: 3867 // Note that according to ECMA-262 15.8.2.13:
3879 // Math.pow(-Infinity, 0.5) == Infinity 3868 // Math.pow(-Infinity, 0.5) == Infinity
3880 // Math.sqrt(-Infinity) == NaN 3869 // Math.sqrt(-Infinity) == NaN
3881 Label done;
3882 __ vmov(temp, -V8_INFINITY, scratch0()); 3870 __ vmov(temp, -V8_INFINITY, scratch0());
3883 __ VFPCompareAndSetFlags(input, temp); 3871 __ VFPCompareAndSetFlags(input, temp);
3884 __ vneg(result, temp, eq); 3872 __ vneg(result, temp, eq);
3885 __ b(&done, eq);
3886 3873
3887 // Add +0 to convert -0 to +0. 3874 // Add +0 to convert -0 to +0.
3888 __ vadd(result, input, kDoubleRegZero); 3875 __ vadd(result, input, kDoubleRegZero, ne);
Sven Panne 2013/12/12 13:43:23 ... and here.
Rodolph Perfetta 2013/12/13 11:31:14 vadd and especially vsqrt are complex instructions
Benedikt Meurer 2014/01/02 06:49:28 Done.
3889 __ vsqrt(result, result); 3876 __ vsqrt(result, result, ne);
3890 __ bind(&done);
3891 } 3877 }
3892 3878
3893 3879
3894 void LCodeGen::DoPower(LPower* instr) { 3880 void LCodeGen::DoPower(LPower* instr) {
3895 Representation exponent_type = instr->hydrogen()->right()->representation(); 3881 Representation exponent_type = instr->hydrogen()->right()->representation();
3896 // Having marked this as a call, we can use any registers. 3882 // Having marked this as a call, we can use any registers.
3897 // Just make sure that the input/output registers are the expected ones. 3883 // Just make sure that the input/output registers are the expected ones.
3898 ASSERT(!instr->right()->IsDoubleRegister() || 3884 ASSERT(!instr->right()->IsDoubleRegister() ||
3899 ToDoubleRegister(instr->right()).is(d1)); 3885 ToDoubleRegister(instr->right()).is(d1));
3900 ASSERT(!instr->right()->IsRegister() || 3886 ASSERT(!instr->right()->IsRegister() ||
(...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after
5580 EmitBranch(instr, eq); 5566 EmitBranch(instr, eq);
5581 } 5567 }
5582 5568
5583 5569
5584 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 5570 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
5585 ASSERT(!temp1.is(temp2)); 5571 ASSERT(!temp1.is(temp2));
5586 // Get the frame pointer for the calling frame. 5572 // Get the frame pointer for the calling frame.
5587 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 5573 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
5588 5574
5589 // Skip the arguments adaptor frame if it exists. 5575 // Skip the arguments adaptor frame if it exists.
5590 Label check_frame_marker;
5591 __ ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset)); 5576 __ ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
5592 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 5577 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
5593 __ b(ne, &check_frame_marker); 5578 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset), eq);
5594 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
5595 5579
5596 // Check the marker in the calling frame. 5580 // Check the marker in the calling frame.
5597 __ bind(&check_frame_marker);
5598 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5581 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5599 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5582 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5600 } 5583 }
5601 5584
5602 5585
5603 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 5586 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
5604 if (info()->IsStub()) return; 5587 if (info()->IsStub()) return;
5605 // Ensure that we have enough space after the previous lazy-bailout 5588 // Ensure that we have enough space after the previous lazy-bailout
5606 // instruction for patching the code here. 5589 // instruction for patching the code here.
5607 int current_pc = masm()->pc_offset(); 5590 int current_pc = masm()->pc_offset();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5807 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5825 __ ldr(result, FieldMemOperand(scratch, 5808 __ ldr(result, FieldMemOperand(scratch,
5826 FixedArray::kHeaderSize - kPointerSize)); 5809 FixedArray::kHeaderSize - kPointerSize));
5827 __ bind(&done); 5810 __ bind(&done);
5828 } 5811 }
5829 5812
5830 5813
5831 #undef __ 5814 #undef __
5832 5815
5833 } } // namespace v8::internal 5816 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698