1bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 2bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Redistribution and use in source and binary forms, with or without 3bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// modification, are permitted provided that the following conditions are 4bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// met: 5bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// 6bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// * Redistributions of source code must retain the above copyright 7bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// notice, this list of conditions and the following disclaimer. 8bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// * Redistributions in binary form must reproduce the above 9bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// copyright notice, this list of conditions and the following 10bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// disclaimer in the documentation and/or other materials provided 11bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// with the distribution. 12bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// * Neither the name of Google Inc. nor the names of its 13bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// contributors may be used to endorse or promote products derived 14bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// from this software without specific prior written permission. 15bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// 16bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 28bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#include "hydrogen-bce.h" 29bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 30bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgnamespace v8 { 31bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgnamespace internal { 32bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 33bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// We try to "factor up" HBoundsCheck instructions towards the root of the 34bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// dominator tree. 35bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// For now we handle checks where the index is like "exp + int32value". 36bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// If in the dominator tree we check "exp + v1" and later (dominated) 37bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// "exp + v2", if v2 <= v1 we can safely remove the second check, and if 38bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// v2 > v1 we can use v2 in the 1st check and again remove the second. 39bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// To do so we keep a dictionary of all checks where the key if the pair 40bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// "exp, length". 41bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// The class BoundsCheckKey represents this key. 42bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgclass BoundsCheckKey : public ZoneObject { 43bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org public: 44bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* IndexBase() const { return index_base_; } 45bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* Length() const { return length_; } 46bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 47bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org uint32_t Hash() { 48bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return static_cast<uint32_t>(index_base_->Hashcode() ^ length_->Hashcode()); 49bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 50bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 51bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org static BoundsCheckKey* Create(Zone* zone, 52bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* check, 53bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t* offset) { 54bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!check->index()->representation().IsSmiOrInteger32()) return NULL; 55bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 56bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* index_base = NULL; 57bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HConstant* constant = NULL; 58bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool is_sub = false; 59bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 60bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (check->index()->IsAdd()) { 61bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HAdd* index = HAdd::cast(check->index()); 62bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (index->left()->IsConstant()) { 63bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org constant = HConstant::cast(index->left()); 64bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org index_base = index->right(); 65bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (index->right()->IsConstant()) { 66bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org constant = HConstant::cast(index->right()); 67bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org index_base = index->left(); 68bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 69bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (check->index()->IsSub()) { 70bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HSub* index = HSub::cast(check->index()); 71bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org is_sub = true; 72bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (index->left()->IsConstant()) { 73bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org constant = HConstant::cast(index->left()); 74bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org index_base = index->right(); 75bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (index->right()->IsConstant()) { 76bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org constant = HConstant::cast(index->right()); 77bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org index_base = index->left(); 78bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 79bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 80bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 81bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (constant != NULL && constant->HasInteger32Value()) { 82bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org *offset = is_sub ? - constant->Integer32Value() 83bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : constant->Integer32Value(); 84bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 85bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org *offset = 0; 86bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org index_base = check->index(); 87bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 88bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 89bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return new(zone) BoundsCheckKey(index_base, check->length()); 90bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 91bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 92bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org private: 93bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey(HValue* index_base, HValue* length) 94bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : index_base_(index_base), 95bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org length_(length) { } 96bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 97bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* index_base_; 98bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* length_; 99bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 100bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org DISALLOW_COPY_AND_ASSIGN(BoundsCheckKey); 101bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}; 102bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 103bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 104bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Data about each HBoundsCheck that can be eliminated or moved. 105bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// It is the "value" in the dictionary indexed by "base-index, length" 106bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// (the key is BoundsCheckKey). 107bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// We scan the code with a dominator tree traversal. 108bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Traversing the dominator tree we keep a stack (implemented as a singly 109bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// linked list) of "data" for each basic block that contains a relevant check 110bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// with the same key (the dictionary holds the head of the list). 111bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// We also keep all the "data" created for a given basic block in a list, and 112bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// use it to "clean up" the dictionary when backtracking in the dominator tree 113bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// traversal. 114bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Doing this each dictionary entry always directly points to the check that 115bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// is dominating the code being examined now. 116bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// We also track the current "offset" of the index expression and use it to 117bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// decide if any check is already "covered" (so it can be removed) or not. 118bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgclass BoundsCheckBbData: public ZoneObject { 119bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org public: 120bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey* Key() const { return key_; } 121bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t LowerOffset() const { return lower_offset_; } 122bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t UpperOffset() const { return upper_offset_; } 123bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBasicBlock* BasicBlock() const { return basic_block_; } 124bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* LowerCheck() const { return lower_check_; } 125bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* UpperCheck() const { return upper_check_; } 126bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* NextInBasicBlock() const { return next_in_bb_; } 127bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* FatherInDominatorTree() const { return father_in_dt_; } 128bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 129bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool OffsetIsCovered(int32_t offset) const { 130bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return offset >= LowerOffset() && offset <= UpperOffset(); 131bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 132bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 133bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool HasSingleCheck() { return lower_check_ == upper_check_; } 134bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 135bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // The goal of this method is to modify either upper_offset_ or 136bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // lower_offset_ so that also new_offset is covered (the covered 137bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // range grows). 138bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // 139bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // The precondition is that new_check follows UpperCheck() and 140bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // LowerCheck() in the same basic block, and that new_offset is not 141bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // covered (otherwise we could simply remove new_check). 142bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // 143bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // If HasSingleCheck() is true then new_check is added as "second check" 144bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // (either upper or lower; note that HasSingleCheck() becomes false). 145bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // Otherwise one of the current checks is modified so that it also covers 146bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // new_offset, and new_check is removed. 147bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // 148bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // If the check cannot be modified because the context is unknown it 149bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // returns false, otherwise it returns true. 150bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool CoverCheck(HBoundsCheck* new_check, 151bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t new_offset) { 152bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ASSERT(new_check->index()->representation().IsSmiOrInteger32()); 153bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool keep_new_check = false; 154bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 155bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (new_offset > upper_offset_) { 156bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_offset_ = new_offset; 157bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (HasSingleCheck()) { 158bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org keep_new_check = true; 159bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_check_ = new_check; 160bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 161bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool result = BuildOffsetAdd(upper_check_, 162bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org &added_upper_index_, 163bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org &added_upper_offset_, 164bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Key()->IndexBase(), 165bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_check->index()->representation(), 166bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_offset); 167bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!result) return false; 168bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_check_->ReplaceAllUsesWith(upper_check_->index()); 169bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_check_->SetOperandAt(0, added_upper_index_); 170bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 171bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (new_offset < lower_offset_) { 172bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_offset_ = new_offset; 173bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (HasSingleCheck()) { 174bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org keep_new_check = true; 175bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_check_ = new_check; 176bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 177bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool result = BuildOffsetAdd(lower_check_, 178bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org &added_lower_index_, 179bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org &added_lower_offset_, 180bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Key()->IndexBase(), 181bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_check->index()->representation(), 182bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_offset); 183bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!result) return false; 184bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_check_->ReplaceAllUsesWith(lower_check_->index()); 185bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_check_->SetOperandAt(0, added_lower_index_); 186bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 187bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 188bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ASSERT(false); 189bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 190bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 191bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!keep_new_check) { 192fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org new_check->block()->graph()->isolate()->counters()-> 193fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org bounds_checks_eliminated()->Increment(); 194bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_check->DeleteAndReplaceWith(new_check->ActualValue()); 195bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 196bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 197bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return true; 198bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 199bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 200bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org void RemoveZeroOperations() { 201bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org RemoveZeroAdd(&added_lower_index_, &added_lower_offset_); 202bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org RemoveZeroAdd(&added_upper_index_, &added_upper_offset_); 203bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 204bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 205bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData(BoundsCheckKey* key, 206bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t lower_offset, 207bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t upper_offset, 208bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBasicBlock* bb, 209bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* lower_check, 210bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* upper_check, 211bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* next_in_bb, 212bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* father_in_dt) 213bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : key_(key), 214bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_offset_(lower_offset), 215bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_offset_(upper_offset), 216bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org basic_block_(bb), 217bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org lower_check_(lower_check), 218bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org upper_check_(upper_check), 219bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org added_lower_index_(NULL), 220bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org added_lower_offset_(NULL), 221bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org added_upper_index_(NULL), 222bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org added_upper_offset_(NULL), 223bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org next_in_bb_(next_in_bb), 224bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org father_in_dt_(father_in_dt) { } 225bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 226bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org private: 227bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey* key_; 228bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t lower_offset_; 229bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t upper_offset_; 230bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBasicBlock* basic_block_; 231bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* lower_check_; 232bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* upper_check_; 233bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HInstruction* added_lower_index_; 234bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HConstant* added_lower_offset_; 235bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HInstruction* added_upper_index_; 236bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HConstant* added_upper_offset_; 237bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* next_in_bb_; 238bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* father_in_dt_; 239bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 240bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // Given an existing add instruction and a bounds check it tries to 241bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // find the current context (either of the add or of the check index). 242bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* IndexContext(HInstruction* add, HBoundsCheck* check) { 243bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (add != NULL && add->IsAdd()) { 244bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return HAdd::cast(add)->context(); 245bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 246bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (check->index()->IsBinaryOperation()) { 247bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return HBinaryOperation::cast(check->index())->context(); 248bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 249bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return NULL; 250bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 251bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 252bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // This function returns false if it cannot build the add because the 253bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // current context cannot be determined. 254bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bool BuildOffsetAdd(HBoundsCheck* check, 255bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HInstruction** add, 256bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HConstant** constant, 257bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* original_value, 258bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Representation representation, 259bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t new_offset) { 260bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HValue* index_context = IndexContext(*add, check); 261bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (index_context == NULL) return false; 262bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 263d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org Zone* zone = BasicBlock()->zone(); 264d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org HConstant* new_constant = HConstant::New(zone, index_context, 265d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org new_offset, representation); 266bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (*add == NULL) { 267bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_constant->InsertBefore(check); 268d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org (*add) = HAdd::New(zone, index_context, original_value, new_constant); 269bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (*add)->AssumeRepresentation(representation); 270bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (*add)->InsertBefore(check); 271bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 272bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_constant->InsertBefore(*add); 273bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (*constant)->DeleteAndReplaceWith(new_constant); 274bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 275bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org *constant = new_constant; 276bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return true; 277bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 278bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 279bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org void RemoveZeroAdd(HInstruction** add, HConstant** constant) { 280bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (*add != NULL && (*add)->IsAdd() && (*constant)->Integer32Value() == 0) { 281bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (*add)->DeleteAndReplaceWith(HAdd::cast(*add)->left()); 282bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org (*constant)->DeleteAndReplaceWith(NULL); 283bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 284bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 285bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 286bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org DISALLOW_COPY_AND_ASSIGN(BoundsCheckBbData); 287bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}; 288bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 289bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 290bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic bool BoundsCheckKeyMatch(void* key1, void* key2) { 291bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); 292bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); 293bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); 294bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 295bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 296bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 297bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgBoundsCheckTable::BoundsCheckTable(Zone* zone) 298bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, 299bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ZoneAllocationPolicy(zone)) { } 300bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 301bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 302bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgBoundsCheckBbData** BoundsCheckTable::LookupOrInsert(BoundsCheckKey* key, 303bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Zone* zone) { 304bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return reinterpret_cast<BoundsCheckBbData**>( 305bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); 306bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 307bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 308bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 309bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgvoid BoundsCheckTable::Insert(BoundsCheckKey* key, 310bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* data, 311bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Zone* zone) { 312bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; 313bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 314bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 315bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 316bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgvoid BoundsCheckTable::Delete(BoundsCheckKey* key) { 317bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Remove(key, key->Hash()); 318bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 319bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 320bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 321c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.orgclass HBoundsCheckEliminationState { 322c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org public: 323c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBasicBlock* block_; 324c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org BoundsCheckBbData* bb_data_list_; 325c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org int index_; 326c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org}; 327c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 328c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 329bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Eliminates checks in bb and recursively in the dominated blocks. 330bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Also replace the results of check instructions with the original value, if 331bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// the result is used. This is safe now, since we don't do code motion after 332bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// this point. It enables better register allocation since the value produced 333bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// by check instructions is really a copy of the original value. 334bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgvoid HBoundsCheckEliminationPhase::EliminateRedundantBoundsChecks( 335c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBasicBlock* entry) { 336c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org // Allocate the stack. 337c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBoundsCheckEliminationState* stack = 338c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org zone()->NewArray<HBoundsCheckEliminationState>(graph()->blocks()->length()); 339c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 340c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org // Explicitly push the entry block. 341c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[0].block_ = entry; 342c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[0].bb_data_list_ = PreProcessBlock(entry); 343c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[0].index_ = 0; 344c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org int stack_depth = 1; 345c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 346c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org // Implement depth-first traversal with a stack. 347c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org while (stack_depth > 0) { 348c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org int current = stack_depth - 1; 349c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBoundsCheckEliminationState* state = &stack[current]; 350c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org const ZoneList<HBasicBlock*>* children = state->block_->dominated_blocks(); 351c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 352c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org if (state->index_ < children->length()) { 353c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org // Recursively visit children blocks. 354c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBasicBlock* child = children->at(state->index_++); 355c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org int next = stack_depth++; 356c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[next].block_ = child; 357c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[next].bb_data_list_ = PreProcessBlock(child); 358c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack[next].index_ = 0; 359c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org } else { 360c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org // Finished with all children; post process the block. 361c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org PostProcessBlock(state->block_, state->bb_data_list_); 362c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org stack_depth--; 363c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org } 364c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org } 365c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org} 366c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 367c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 368c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.orgBoundsCheckBbData* HBoundsCheckEliminationPhase::PreProcessBlock( 369bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBasicBlock* bb) { 370bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* bb_data_list = NULL; 371bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 372bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org for (HInstructionIterator it(bb); !it.Done(); it.Advance()) { 373bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HInstruction* i = it.Current(); 374bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!i->IsBoundsCheck()) continue; 375bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 376bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org HBoundsCheck* check = HBoundsCheck::cast(i); 377bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t offset; 378bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey* key = 379bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckKey::Create(zone(), check, &offset); 380bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (key == NULL) continue; 381bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData** data_p = table_.LookupOrInsert(key, zone()); 382bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org BoundsCheckBbData* data = *data_p; 383bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (data == NULL) { 384bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb_data_list = new(zone()) BoundsCheckBbData(key, 385bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org offset, 386bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org offset, 387bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb, 388bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org check, 389bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org check, 390bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb_data_list, 391bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org NULL); 392bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org *data_p = bb_data_list; 393bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (data->OffsetIsCovered(offset)) { 394fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org bb->graph()->isolate()->counters()-> 395fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org bounds_checks_eliminated()->Increment(); 396bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org check->DeleteAndReplaceWith(check->ActualValue()); 397bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (data->BasicBlock() != bb || 398bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org !data->CoverCheck(check, offset)) { 399bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // If the check is in the current BB we try to modify it by calling 400bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // "CoverCheck", but if also that fails we record the current offsets 401bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // in a new data instance because from now on they are covered. 402bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t new_lower_offset = offset < data->LowerOffset() 403bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ? offset 404bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : data->LowerOffset(); 405bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org int32_t new_upper_offset = offset > data->UpperOffset() 406bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ? offset 407bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org : data->UpperOffset(); 408bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb_data_list = new(zone()) BoundsCheckBbData(key, 409bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_lower_offset, 410bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org new_upper_offset, 411bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb, 412bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org data->LowerCheck(), 413bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org data->UpperCheck(), 414bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org bb_data_list, 415bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org data); 416bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org table_.Insert(key, bb_data_list, zone()); 417bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 418bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 419bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 420c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org return bb_data_list; 421c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org} 422c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org 423bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 424c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.orgvoid HBoundsCheckEliminationPhase::PostProcessBlock( 425c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org HBasicBlock* block, BoundsCheckBbData* data) { 426c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org while (data != NULL) { 427bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org data->RemoveZeroOperations(); 428bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (data->FatherInDominatorTree()) { 429bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org table_.Insert(data->Key(), data->FatherInDominatorTree(), zone()); 430bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else { 431bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org table_.Delete(data->Key()); 432bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 433c7528a8f3c24df07dd43ff79a22d71517f686b6cdanno@chromium.org data = data->NextInBasicBlock(); 434bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 435bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 436bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 437bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} } // namespace v8::internal 438