1c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-range-analysis.h" 6c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 7c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgnamespace v8 { 8c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgnamespace internal { 9c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 10c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 1110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgclass Pending { 1210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org public: 1310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Pending(HBasicBlock* block, int last_changed_range) 1410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org : block_(block), last_changed_range_(last_changed_range) {} 1510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 1610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HBasicBlock* block() const { return block_; } 1710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int last_changed_range() const { return last_changed_range_; } 1810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 1910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org private: 2010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HBasicBlock* block_; 2110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int last_changed_range_; 2210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org}; 2310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 2410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 25c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid HRangeAnalysisPhase::TraceRange(const char* msg, ...) { 26c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (FLAG_trace_range) { 27c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org va_list arguments; 28c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org va_start(arguments, msg); 295de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::VPrint(msg, arguments); 30c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org va_end(arguments); 31c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 32c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 33c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 34c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 3510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.orgvoid HRangeAnalysisPhase::Run() { 3610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HBasicBlock* block(graph()->entry_block()); 3710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ZoneList<Pending> stack(graph()->blocks()->length(), zone()); 3810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org while (block != NULL) { 3910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org TraceRange("Analyzing block B%d\n", block->block_id()); 40c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 4110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Infer range based on control flow. 4210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (block->predecessors()->length() == 1) { 4310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HBasicBlock* pred = block->predecessors()->first(); 4410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (pred->end()->IsCompareNumericAndBranch()) { 4510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()), 4610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org block); 4710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 48c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 49c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 5010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Process phi instructions. 5110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (int i = 0; i < block->phis()->length(); ++i) { 5210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org HPhi* phi = block->phis()->at(i); 5310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org InferRange(phi); 5410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 55c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 5610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Go through all instructions of the current block. 5710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 58bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HValue* value = it.Current(); 59bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org InferRange(value); 60bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 61bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Compute the bailout-on-minus-zero flag. 62bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (value->IsChange()) { 63bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HChange* instr = HChange::cast(value); 64bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Propagate flags for negative zero checks upwards from conversions 65bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // int32-to-tagged and int32-to-double. 66bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Representation from = instr->value()->representation(); 67e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(from.Equals(instr->from())); 68bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (from.IsSmiOrInteger32()) { 69e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->to().IsTagged() || 70bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->to().IsDouble() || 71bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->to().IsSmiOrInteger32()); 72bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org PropagateMinusZeroChecks(instr->value()); 73bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 74bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsCompareMinusZeroAndBranch()) { 75bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HCompareMinusZeroAndBranch* instr = 76bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HCompareMinusZeroAndBranch::cast(value); 77bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->value()->representation().IsSmiOrInteger32()) { 78bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org PropagateMinusZeroChecks(instr->value()); 79bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 80bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 8110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 82c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 8310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Continue analysis in all dominated blocks. 8410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org const ZoneList<HBasicBlock*>* dominated_blocks(block->dominated_blocks()); 8510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (!dominated_blocks->is_empty()) { 8610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Continue with first dominated block, and push the 8710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // remaining blocks on the stack (in reverse order). 8810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int last_changed_range = changed_ranges_.length(); 8910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (int i = dominated_blocks->length() - 1; i > 0; --i) { 9010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org stack.Add(Pending(dominated_blocks->at(i), last_changed_range), zone()); 9110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 9210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org block = dominated_blocks->at(0); 9310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } else if (!stack.is_empty()) { 9410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // Pop next pending block from stack. 9510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Pending pending = stack.RemoveLast(); 9610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org RollBackTo(pending.last_changed_range()); 9710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org block = pending.block(); 9810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } else { 9910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // All blocks done. 10010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org block = NULL; 10110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 102c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 1032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 1042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // The ranges are not valid anymore due to SSI vs. SSA! 1052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org PoisonRanges(); 1062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org} 1072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 1082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 1092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid HRangeAnalysisPhase::PoisonRanges() { 1102ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#ifdef DEBUG 1112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org for (int i = 0; i < graph()->blocks()->length(); ++i) { 1122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org HBasicBlock* block = graph()->blocks()->at(i); 1132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 1142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org HInstruction* instr = it.Current(); 1152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (instr->HasRange()) instr->PoisonRange(); 1162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 1172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 1182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#endif 119c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 120c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 121c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 122e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test, 123c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HBasicBlock* dest) { 124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 125c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (test->representation().IsSmiOrInteger32()) { 126c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Token::Value op = test->token(); 127c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (test->SecondSuccessor() == dest) { 128c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org op = Token::NegateCompareOp(op); 129c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 130c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Token::Value inverted_op = Token::ReverseCompareOp(op); 131c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org UpdateControlFlowRange(op, test->left(), test->right()); 132c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org UpdateControlFlowRange(inverted_op, test->right(), test->left()); 133c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 134c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 135c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 136c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 137c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org// We know that value [op] other. Use this information to update the range on 138c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org// value. 139c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid HRangeAnalysisPhase::UpdateControlFlowRange(Token::Value op, 140c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HValue* value, 141c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HValue* other) { 142c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range temp_range; 143c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range* range = other->range() != NULL ? other->range() : &temp_range; 144c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range* new_range = NULL; 145c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 146c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TraceRange("Control flow range infer %d %s %d\n", 147c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->id(), 148c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Token::Name(op), 149c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org other->id()); 150c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 151c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (op == Token::EQ || op == Token::EQ_STRICT) { 152c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // The same range has to apply for value. 153c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range = range->Copy(graph()->zone()); 154c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } else if (op == Token::LT || op == Token::LTE) { 155c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range = range->CopyClearLower(graph()->zone()); 156c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (op == Token::LT) { 157c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range->AddConstant(-1); 158c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 159c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } else if (op == Token::GT || op == Token::GTE) { 160c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range = range->CopyClearUpper(graph()->zone()); 161c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (op == Token::GT) { 162c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range->AddConstant(1); 163c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 164c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 165c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 166c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (new_range != NULL && !new_range->IsMostGeneric()) { 167c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org AddRange(value, new_range); 168c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 169c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 170c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 171c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 172c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid HRangeAnalysisPhase::InferRange(HValue* value) { 173e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!value->HasRange()); 174c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (!value->representation().IsNone()) { 175c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->ComputeInitialRange(graph()->zone()); 176c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range* range = value->range(); 177c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n", 178c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->id(), 179c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->Mnemonic(), 180c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org range->lower(), 181c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org range->upper()); 182c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 183c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 184c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 185c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 186c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid HRangeAnalysisPhase::RollBackTo(int index) { 187e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index <= changed_ranges_.length()); 18810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (int i = index; i < changed_ranges_.length(); ++i) { 189c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org changed_ranges_[i]->RemoveLastAddedRange(); 190c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 19110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org changed_ranges_.Rewind(index); 192c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 193c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 194c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 195c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid HRangeAnalysisPhase::AddRange(HValue* value, Range* range) { 196c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range* original_range = value->range(); 197c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->AddNewRange(range, graph()->zone()); 198c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org changed_ranges_.Add(value, zone()); 199c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Range* new_range = value->range(); 200c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TraceRange("Updated range of %d set to [%d,%d]\n", 201c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org value->id(), 202c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range->lower(), 203c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org new_range->upper()); 204c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (original_range != NULL) { 205c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TraceRange("Original range was [%d,%d]\n", 206c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org original_range->lower(), 207c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org original_range->upper()); 208c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 209c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TraceRange("New information was [%d,%d]\n", 210c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org range->lower(), 211c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org range->upper()); 212c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 213c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 214c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 215bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgvoid HRangeAnalysisPhase::PropagateMinusZeroChecks(HValue* value) { 216e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(worklist_.is_empty()); 217e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(in_worklist_.IsEmpty()); 218bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 219bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(value); 220bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org while (!worklist_.is_empty()) { 221bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org value = worklist_.RemoveLast(); 222bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 223bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (value->IsPhi()) { 224bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // For phis, we must propagate the check to all of its inputs. 225bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HPhi* phi = HPhi::cast(value); 226bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org for (int i = 0; i < phi->OperandCount(); ++i) { 227bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(phi->OperandAt(i)); 228bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 229bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsUnaryMathOperation()) { 230bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HUnaryMathOperation* instr = HUnaryMathOperation::cast(value); 231bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->representation().IsSmiOrInteger32() && 232bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org !instr->value()->representation().Equals(instr->representation())) { 233bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->value()->range() == NULL || 234bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->value()->range()->CanBeMinusZero()) { 235bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->SetFlag(HValue::kBailoutOnMinusZero); 236bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 237bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 238bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->RequiredInputRepresentation(0).IsSmiOrInteger32() && 239bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->representation().Equals( 240bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->RequiredInputRepresentation(0))) { 241bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->value()); 242bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 243bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsChange()) { 244bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HChange* instr = HChange::cast(value); 245bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (!instr->from().IsSmiOrInteger32() && 246bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org !instr->CanTruncateToInt32() && 247bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org (instr->value()->range() == NULL || 248bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->value()->range()->CanBeMinusZero())) { 249bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->SetFlag(HValue::kBailoutOnMinusZero); 250bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 251bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsForceRepresentation()) { 252bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HForceRepresentation* instr = HForceRepresentation::cast(value); 253bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->value()); 254bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsMod()) { 255bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMod* instr = HMod::cast(value); 256bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { 257bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->SetFlag(HValue::kBailoutOnMinusZero); 258bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->left()); 259bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 260bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsDiv() || value->IsMul()) { 261bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HBinaryOperation* instr = HBinaryOperation::cast(value); 262bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { 263bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->SetFlag(HValue::kBailoutOnMinusZero); 264bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 265bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->right()); 266bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->left()); 267bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsMathFloorOfDiv()) { 268bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMathFloorOfDiv* instr = HMathFloorOfDiv::cast(value); 269bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org instr->SetFlag(HValue::kBailoutOnMinusZero); 270bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsAdd() || value->IsSub()) { 271bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HBinaryOperation* instr = HBinaryOperation::cast(value); 272bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (instr->range() == NULL || instr->range()->CanBeMinusZero()) { 273bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // Propagate to the left argument. If the left argument cannot be -0, 274bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // then the result of the add/sub operation cannot be either. 275bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->left()); 276bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 277bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } else if (value->IsMathMinMax()) { 278bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org HMathMinMax* instr = HMathMinMax::cast(value); 279bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->right()); 280bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org AddToWorklist(instr->left()); 281bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 282bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 283bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 284bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org in_worklist_.Clear(); 285e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(in_worklist_.IsEmpty()); 286e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(worklist_.is_empty()); 287bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 288bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 289bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 290c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} } // namespace v8::internal 291