Commit b2f909cf authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Turn array index dehoisting into a proper HPhase.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/18562009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15627 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a5397dce
// Copyright 2013 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.
#include "hydrogen-dehoist.h"
namespace v8 {
namespace internal {
static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) {
HValue* index = array_operation->GetKey()->ActualValue();
if (!index->representation().IsSmiOrInteger32()) return;
if (!index->IsAdd() && !index->IsSub()) return;
HConstant* constant;
HValue* subexpression;
HBinaryOperation* binary_operation = HBinaryOperation::cast(index);
if (binary_operation->left()->IsConstant()) {
subexpression = binary_operation->right();
constant = HConstant::cast(binary_operation->left());
} else if (binary_operation->right()->IsConstant()) {
subexpression = binary_operation->left();
constant = HConstant::cast(binary_operation->right());
} else {
return;
}
if (!constant->HasInteger32Value()) return;
int32_t sign = binary_operation->IsSub() ? -1 : 1;
int32_t value = constant->Integer32Value() * sign;
// We limit offset values to 30 bits because we want to avoid the risk of
// overflows when the offset is added to the object header size.
if (value >= 1 << 30 || value < 0) return;
array_operation->SetKey(subexpression);
if (binary_operation->HasNoUses()) {
binary_operation->DeleteAndReplaceWith(NULL);
}
array_operation->SetIndexOffset(static_cast<uint32_t>(value));
array_operation->SetDehoisted(true);
}
void HDehoistIndexComputationsPhase::Run() {
const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
for (int i = 0; i < blocks->length(); ++i) {
for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
HInstruction* instr = it.Current();
if (instr->IsLoadKeyed()) {
DehoistArrayIndex(HLoadKeyed::cast(instr));
} else if (instr->IsStoreKeyed()) {
DehoistArrayIndex(HStoreKeyed::cast(instr));
}
}
}
}
} } // namespace v8::internal
// Copyright 2013 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.
#ifndef V8_HYDROGEN_DEHOIST_H_
#define V8_HYDROGEN_DEHOIST_H_
#include "hydrogen.h"
namespace v8 {
namespace internal {
class HDehoistIndexComputationsPhase : public HPhase {
public:
explicit HDehoistIndexComputationsPhase(HGraph* graph)
: HPhase("H_Dehoist index computations", graph) { }
void Run();
private:
DISALLOW_COPY_AND_ASSIGN(HDehoistIndexComputationsPhase);
};
} } // namespace v8::internal
#endif // V8_HYDROGEN_DEHOIST_H_
......@@ -36,6 +36,7 @@
#include "hydrogen-bce.h"
#include "hydrogen-canonicalize.h"
#include "hydrogen-dce.h"
#include "hydrogen-dehoist.h"
#include "hydrogen-environment-liveness.h"
#include "hydrogen-escape-analysis.h"
#include "hydrogen-infer-representation.h"
......@@ -3078,7 +3079,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
Run<HBoundsCheckEliminationPhase>();
}
if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations();
if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
RestoreActualValues();
......@@ -3131,77 +3132,6 @@ void HGraph::SetupInformativeDefinitions() {
}
static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) {
HValue* index = array_operation->GetKey()->ActualValue();
if (!index->representation().IsSmiOrInteger32()) return;
HConstant* constant;
HValue* subexpression;
int32_t sign;
if (index->IsAdd()) {
sign = 1;
HAdd* add = HAdd::cast(index);
if (add->left()->IsConstant()) {
subexpression = add->right();
constant = HConstant::cast(add->left());
} else if (add->right()->IsConstant()) {
subexpression = add->left();
constant = HConstant::cast(add->right());
} else {
return;
}
} else if (index->IsSub()) {
sign = -1;
HSub* sub = HSub::cast(index);
if (sub->left()->IsConstant()) {
subexpression = sub->right();
constant = HConstant::cast(sub->left());
} else if (sub->right()->IsConstant()) {
subexpression = sub->left();
constant = HConstant::cast(sub->right());
} else {
return;
}
} else {
return;
}
if (!constant->HasInteger32Value()) return;
int32_t value = constant->Integer32Value() * sign;
// We limit offset values to 30 bits because we want to avoid the risk of
// overflows when the offset is added to the object header size.
if (value >= 1 << 30 || value < 0) return;
array_operation->SetKey(subexpression);
if (index->HasNoUses()) {
index->DeleteAndReplaceWith(NULL);
}
ASSERT(value >= 0);
array_operation->SetIndexOffset(static_cast<uint32_t>(value));
array_operation->SetDehoisted(true);
}
void HGraph::DehoistSimpleArrayIndexComputations() {
HPhase phase("H_Dehoist index computations", this);
for (int i = 0; i < blocks()->length(); ++i) {
for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
HInstruction* instr = it.Current();
ArrayInstructionInterface* array_instruction = NULL;
if (instr->IsLoadKeyed()) {
HLoadKeyed* op = HLoadKeyed::cast(instr);
array_instruction = static_cast<ArrayInstructionInterface*>(op);
} else if (instr->IsStoreKeyed()) {
HStoreKeyed* op = HStoreKeyed::cast(instr);
array_instruction = static_cast<ArrayInstructionInterface*>(op);
} else {
continue;
}
DehoistArrayIndex(array_instruction);
}
}
}
void HGraph::RestoreActualValues() {
HPhase phase("H_Restore actual values", this);
......
......@@ -341,6 +341,8 @@
'../../src/hydrogen-canonicalize.h',
'../../src/hydrogen-dce.cc',
'../../src/hydrogen-dce.h',
'../../src/hydrogen-dehoist.cc',
'../../src/hydrogen-dehoist.h',
'../../src/hydrogen-environment-liveness.cc',
'../../src/hydrogen-environment-liveness.h',
'../../src/hydrogen-escape-analysis.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment