From: mmassi@chromium.org Date: Mon, 10 Dec 2012 12:55:50 +0000 (+0000) Subject: Revert r13176. X-Git-Tag: upstream/4.7.83~15462 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b0ee64664b79219220d99e9035b4fff41c73985;p=platform%2Fupstream%2Fv8.git Revert r13176. BUG= Review URL: https://chromiumcodereview.appspot.com/11503011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13182 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 80685f0..161e654 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -348,13 +348,6 @@ class Representation { } const char* Mnemonic() const; - Representation KeyedAccessIndexRequirement() { - // This is intended to be used in RequiredInputRepresentation for keyed - // loads and stores to avoid inserting unneeded HChange instructions: - // keyed loads and stores can work on both int32 and tagged indexes. - return IsInteger32() ? Integer32() : Tagged(); - } - private: explicit Representation(Kind k) : kind_(k) { } @@ -2834,65 +2827,6 @@ class HWrapReceiver: public HTemplateInstruction<2> { }; -enum BoundsCheckKeyMode { - DONT_ALLOW_SMI_KEY, - ALLOW_SMI_KEY -}; - - -class HBoundsCheck: public HTemplateInstruction<2> { - public: - HBoundsCheck(HValue* index, HValue* length, - BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) - : key_mode_(key_mode) { - SetOperandAt(0, index); - SetOperandAt(1, length); - set_representation(Representation::Integer32()); - SetFlag(kUseGVN); - } - - virtual Representation RequiredInputRepresentation(int arg_index) { - if (key_mode_ == DONT_ALLOW_SMI_KEY || - !length()->representation().IsTagged()) { - return Representation::Integer32(); - } - // If the index is tagged and isn't constant, then allow the length - // to be tagged, since it is usually already tagged from loading it out of - // the length field of a JSArray. This allows for direct comparison without - // untagging. - if (index()->representation().IsTagged() && !index()->IsConstant()) { - return Representation::Tagged(); - } - // Also allow the length to be tagged if the index is constant, because - // it can be tagged to allow direct comparison. - if (index()->IsConstant() && - index()->representation().IsInteger32() && - arg_index == 1) { - return Representation::Tagged(); - } - return Representation::Integer32(); - } - virtual Representation observed_input_representation(int index) { - return Representation::Integer32(); - } - - virtual void PrintDataTo(StringStream* stream); - - HValue* index() { return OperandAt(0); } - HValue* length() { return OperandAt(1); } - - DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) - - static HValue* ExtractUncheckedIndex(HValue* index) { - return index->IsBoundsCheck() ? HBoundsCheck::cast(index)->index() : index; - } - - protected: - virtual bool DataEquals(HValue* other) { return true; } - BoundsCheckKeyMode key_mode_; -}; - - class HApplyArguments: public HTemplateInstruction<4> { public: HApplyArguments(HValue* function, @@ -2971,41 +2905,28 @@ class HArgumentsLength: public HUnaryOperation { }; -class HAccessArgumentsAt: public HTemplateInstruction<4> { +class HAccessArgumentsAt: public HTemplateInstruction<3> { public: - HAccessArgumentsAt(HValue* arguments, - HValue* length, - HValue* checked_index) { + HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { set_representation(Representation::Tagged()); SetFlag(kUseGVN); SetOperandAt(0, arguments); SetOperandAt(1, length); - SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); - SetOperandAt(3, checked_index); + SetOperandAt(2, index); } virtual void PrintDataTo(StringStream* stream); virtual Representation RequiredInputRepresentation(int index) { - switch (index) { - // The arguments elements is considered tagged. - case 0: return Representation::Tagged(); - case 1: return Representation::Integer32(); - case 2: return Representation::Integer32(); - // The checked index is a control flow dependency to avoid hoisting - // and therefore it has no representation requirements. - case 3: return Representation::None(); - default: { - UNREACHABLE(); - return Representation::None(); - } - } + // The arguments elements is considered tagged. + return index == 0 + ? Representation::Tagged() + : Representation::Integer32(); } HValue* arguments() { return OperandAt(0); } HValue* length() { return OperandAt(1); } HValue* index() { return OperandAt(2); } - HValue* checked_index() { return OperandAt(3); } DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) @@ -3013,6 +2934,61 @@ class HAccessArgumentsAt: public HTemplateInstruction<4> { }; +enum BoundsCheckKeyMode { + DONT_ALLOW_SMI_KEY, + ALLOW_SMI_KEY +}; + + +class HBoundsCheck: public HTemplateInstruction<2> { + public: + HBoundsCheck(HValue* index, HValue* length, + BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) + : key_mode_(key_mode) { + SetOperandAt(0, index); + SetOperandAt(1, length); + set_representation(Representation::Integer32()); + SetFlag(kUseGVN); + } + + virtual Representation RequiredInputRepresentation(int arg_index) { + if (key_mode_ == DONT_ALLOW_SMI_KEY || + !length()->representation().IsTagged()) { + return Representation::Integer32(); + } + // If the index is tagged and isn't constant, then allow the length + // to be tagged, since it is usually already tagged from loading it out of + // the length field of a JSArray. This allows for direct comparison without + // untagging. + if (index()->representation().IsTagged() && !index()->IsConstant()) { + return Representation::Tagged(); + } + // Also allow the length to be tagged if the index is constant, because + // it can be tagged to allow direct comparison. + if (index()->IsConstant() && + index()->representation().IsInteger32() && + arg_index == 1) { + return Representation::Tagged(); + } + return Representation::Integer32(); + } + virtual Representation observed_input_representation(int index) { + return Representation::Integer32(); + } + + virtual void PrintDataTo(StringStream* stream); + + HValue* index() { return OperandAt(0); } + HValue* length() { return OperandAt(1); } + + DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) + + protected: + virtual bool DataEquals(HValue* other) { return true; } + BoundsCheckKeyMode key_mode_; +}; + + class HBitwiseBinaryOperation: public HBinaryOperation { public: HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) @@ -4379,18 +4355,18 @@ class ArrayInstructionInterface { class HLoadKeyed - : public HTemplateInstruction<4>, public ArrayInstructionInterface { + : public HTemplateInstruction<3>, public ArrayInstructionInterface { public: HLoadKeyed(HValue* obj, - HValue* checked_key, + HValue* key, HValue* dependency, ElementsKind elements_kind) : bit_field_(0) { bit_field_ = ElementsKindField::encode(elements_kind); + SetOperandAt(0, obj); - SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); + SetOperandAt(1, key); SetOperandAt(2, dependency); - SetOperandAt(3, checked_key); if (!is_external()) { // I can detect the case between storing double (holey and fast) and @@ -4432,7 +4408,6 @@ class HLoadKeyed HValue* elements() { return OperandAt(0); } HValue* key() { return OperandAt(1); } HValue* dependency() { return OperandAt(2); } - HValue* checked_key() { return OperandAt(3); } uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } void SetIndexOffset(uint32_t index_offset) { bit_field_ = IndexOffsetField::update(bit_field_, index_offset); @@ -4455,9 +4430,7 @@ class HLoadKeyed return is_external() ? Representation::External() : Representation::Tagged(); } - if (index == 1) { - return OperandAt(1)->representation().KeyedAccessIndexRequirement(); - } + if (index == 1) return Representation::Integer32(); return Representation::None(); } @@ -4639,15 +4612,14 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> { class HStoreKeyed - : public HTemplateInstruction<4>, public ArrayInstructionInterface { + : public HTemplateInstruction<3>, public ArrayInstructionInterface { public: - HStoreKeyed(HValue* obj, HValue* checked_key, HValue* val, + HStoreKeyed(HValue* obj, HValue* key, HValue* val, ElementsKind elements_kind) : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { SetOperandAt(0, obj); - SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); + SetOperandAt(1, key); SetOperandAt(2, val); - SetOperandAt(3, checked_key); if (is_external()) { SetGVNFlag(kChangesSpecializedArrayElements); @@ -4673,9 +4645,7 @@ class HStoreKeyed return is_external() ? Representation::External() : Representation::Tagged(); } else if (index == 1) { - return OperandAt(1)->representation().KeyedAccessIndexRequirement(); - } else if (index == 3) { - return Representation::None(); + return Representation::Integer32(); } ASSERT_EQ(index, 2); @@ -4706,7 +4676,6 @@ class HStoreKeyed HValue* elements() { return OperandAt(0); } HValue* key() { return OperandAt(1); } HValue* value() { return OperandAt(2); } - HValue* checked_key() { return OperandAt(3); } bool value_is_smi() const { return IsFastSmiElementsKind(elements_kind_); } @@ -4849,13 +4818,12 @@ class HStringAdd: public HBinaryOperation { }; -class HStringCharCodeAt: public HTemplateInstruction<4> { +class HStringCharCodeAt: public HTemplateInstruction<3> { public: - HStringCharCodeAt(HValue* context, HValue* string, HValue* checked_index) { + HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { SetOperandAt(0, context); SetOperandAt(1, string); - SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); - SetOperandAt(3, checked_index); + SetOperandAt(2, index); set_representation(Representation::Integer32()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnMaps); @@ -4863,25 +4831,15 @@ class HStringCharCodeAt: public HTemplateInstruction<4> { } virtual Representation RequiredInputRepresentation(int index) { - switch (index) { - case 0: return Representation::Tagged(); - case 1: return Representation::Tagged(); - // The index is supposed to be Integer32. - case 2: return Representation::Integer32(); - // The checked index is a control flow dependency to avoid hoisting - // and therefore it has no representation requirements. - case 3: return Representation::None(); - default: { - UNREACHABLE(); - return Representation::None(); - } - } + // The index is supposed to be Integer32. + return index == 2 + ? Representation::Integer32() + : Representation::Tagged(); } HValue* context() { return OperandAt(0); } HValue* string() { return OperandAt(1); } HValue* index() { return OperandAt(2); } - HValue* checked_index() { return OperandAt(3); } DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 5d20992..d1e5b51 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -3326,8 +3326,8 @@ bool HGraph::Optimize(SmartArrayPointer* bailout_reason) { HStackCheckEliminator sce(this); sce.Process(); - if (FLAG_array_bounds_checks_elimination) EliminateRedundantBoundsChecks(); - if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations(); + EliminateRedundantBoundsChecks(); + DehoistSimpleArrayIndexComputations(); if (FLAG_dead_code_elimination) DeadCodeElimination(); return true; @@ -3484,7 +3484,7 @@ class BoundsCheckBbData: public ZoneObject { } if (!keep_new_check) { - new_check->DeleteAndReplaceWith(new_check->index()); + new_check->DeleteAndReplaceWith(NULL); } } @@ -3591,13 +3591,21 @@ class BoundsCheckTable : private ZoneHashMap { // Eliminates checks in bb and recursively in the dominated blocks. +// Also replace the results of check instructions with the original value, if +// the result is used. This is safe now, since we don't do code motion after +// this point. It enables better register allocation since the value produced +// by check instructions is really a copy of the original value. void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table) { BoundsCheckBbData* bb_data_list = NULL; for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { if (!i->IsBoundsCheck()) continue; + HBoundsCheck* check = HBoundsCheck::cast(i); + check->ReplaceAllUsesWith(check->index()); + + if (!FLAG_array_bounds_checks_elimination) continue; int32_t offset; BoundsCheckKey* key = @@ -3616,7 +3624,7 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, NULL); *data_p = bb_data_list; } else if (data->OffsetIsCovered(offset)) { - check->DeleteAndReplaceWith(check->index()); + check->DeleteAndReplaceWith(NULL); } else if (data->BasicBlock() == bb) { data->CoverCheck(check, offset); } else { @@ -3711,6 +3719,8 @@ static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { void HGraph::DehoistSimpleArrayIndexComputations() { + if (!FLAG_array_index_dehoisting) return; + HPhase phase("H_Dehoist index computations", this); for (int i = 0; i < blocks()->length(); ++i) { for (HInstruction* instr = blocks()->at(i)->first();