Reviewers: Sven Panne, Description: Optimize ~~(expr) in optimized code.
~~ is commonly used to truncate a value to int32 (ToInt32). This change avoid actually emitting the bitwise operations, and just truncates the subexpression of ~~. BUG=v8:2037 TEST=test/mjsunit/compiler/optimize-bitnot.js Please review this at https://chromiumcodereview.appspot.com/10123007/ SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/ Affected files: M src/arm/lithium-arm.cc M src/hydrogen-instructions.h M src/hydrogen-instructions.cc M src/ia32/lithium-ia32.cc M src/mips/lithium-mips.cc M src/x64/lithium-x64.cc A test/mjsunit/compiler/optimize-bitnot.js Index: src/arm/lithium-arm.cc =================================================================== --- src/arm/lithium-arm.cc (revision 11385) +++ src/arm/lithium-arm.cc (working copy) @@ -1295,6 +1295,7 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); + if (instr->HasNoUses()) return NULL; LOperand* value = UseRegisterAtStart(instr->value()); return DefineAsRegister(new(zone()) LBitNotI(value)); } Index: src/hydrogen-instructions.cc =================================================================== --- src/hydrogen-instructions.cc (revision 11385) +++ src/hydrogen-instructions.cc (working copy) @@ -870,6 +870,17 @@ } +HValue* HBitNot::Canonicalize() { + // Optimize ~~x, a common pattern used for ToInt32(x). + if (value()->IsBitNot()) { + HValue* result = HBitNot::cast(value())->value(); + ASSERT(result->representation().IsInteger32()); + return result; + } + return this; +} + + HValue* HAdd::Canonicalize() { if (!representation().IsInteger32()) return this; if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); Index: src/hydrogen-instructions.h =================================================================== --- src/hydrogen-instructions.h (revision 11385) +++ src/hydrogen-instructions.h (working copy) @@ -1918,6 +1918,8 @@ } virtual HType CalculateInferredType(); + virtual HValue* Canonicalize(); + DECLARE_CONCRETE_INSTRUCTION(BitNot) protected: Index: src/ia32/lithium-ia32.cc =================================================================== --- src/ia32/lithium-ia32.cc (revision 11385) +++ src/ia32/lithium-ia32.cc (working copy) @@ -1330,6 +1330,7 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); + if (instr->HasNoUses()) return NULL; LOperand* input = UseRegisterAtStart(instr->value()); LBitNotI* result = new(zone()) LBitNotI(input); return DefineSameAsFirst(result); Index: src/mips/lithium-mips.cc =================================================================== --- src/mips/lithium-mips.cc (revision 11385) +++ src/mips/lithium-mips.cc (working copy) @@ -1296,6 +1296,7 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); + if (instr->HasNoUses()) return NULL; LOperand* value = UseRegisterAtStart(instr->value()); return DefineAsRegister(new(zone()) LBitNotI(value)); } Index: src/x64/lithium-x64.cc =================================================================== --- src/x64/lithium-x64.cc (revision 11385) +++ src/x64/lithium-x64.cc (working copy) @@ -1285,6 +1285,7 @@ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); + if (instr->HasNoUses()) return NULL; LOperand* input = UseRegisterAtStart(instr->value()); LBitNotI* result = new(zone()) LBitNotI(input); return DefineSameAsFirst(result); Index: test/mjsunit/compiler/optimize-bitnot.js =================================================================== --- test/mjsunit/compiler/optimize-bitnot.js (revision 0) +++ test/mjsunit/compiler/optimize-bitnot.js (revision 0) @@ -0,0 +1,46 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +function f(x) { + return ~~x; +} + +f(42); +f(42); +%OptimizeFunctionOnNextCall(f); +assertEquals(42, f(42)); +assertEquals(42, f(42.5)); +assertEquals(1/0, 1/f(-0)); +assertEquals(-1, f(0xffffffff)); +assertEquals(0, f(undefined)); +assertEquals(0, f("abc")); + + + + Property changes on: test/mjsunit/compiler/optimize-bitnot.js ___________________________________________________________________ Added: svn:eol-style + LF -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
