| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen-range-analysis.h" | 5 #include "src/hydrogen-range-analysis.h" |
| 6 | 6 |
| 7 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 | 9 |
| 10 | 10 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { | 57 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 58 HValue* value = it.Current(); | 58 HValue* value = it.Current(); |
| 59 InferRange(value); | 59 InferRange(value); |
| 60 | 60 |
| 61 // Compute the bailout-on-minus-zero flag. | 61 // Compute the bailout-on-minus-zero flag. |
| 62 if (value->IsChange()) { | 62 if (value->IsChange()) { |
| 63 HChange* instr = HChange::cast(value); | 63 HChange* instr = HChange::cast(value); |
| 64 // Propagate flags for negative zero checks upwards from conversions | 64 // Propagate flags for negative zero checks upwards from conversions |
| 65 // int32-to-tagged and int32-to-double. | 65 // int32-to-tagged and int32-to-double. |
| 66 Representation from = instr->value()->representation(); | 66 Representation from = instr->value()->representation(); |
| 67 ASSERT(from.Equals(instr->from())); | 67 DCHECK(from.Equals(instr->from())); |
| 68 if (from.IsSmiOrInteger32()) { | 68 if (from.IsSmiOrInteger32()) { |
| 69 ASSERT(instr->to().IsTagged() || | 69 DCHECK(instr->to().IsTagged() || |
| 70 instr->to().IsDouble() || | 70 instr->to().IsDouble() || |
| 71 instr->to().IsSmiOrInteger32()); | 71 instr->to().IsSmiOrInteger32()); |
| 72 PropagateMinusZeroChecks(instr->value()); | 72 PropagateMinusZeroChecks(instr->value()); |
| 73 } | 73 } |
| 74 } else if (value->IsCompareMinusZeroAndBranch()) { | 74 } else if (value->IsCompareMinusZeroAndBranch()) { |
| 75 HCompareMinusZeroAndBranch* instr = | 75 HCompareMinusZeroAndBranch* instr = |
| 76 HCompareMinusZeroAndBranch::cast(value); | 76 HCompareMinusZeroAndBranch::cast(value); |
| 77 if (instr->value()->representation().IsSmiOrInteger32()) { | 77 if (instr->value()->representation().IsSmiOrInteger32()) { |
| 78 PropagateMinusZeroChecks(instr->value()); | 78 PropagateMinusZeroChecks(instr->value()); |
| 79 } | 79 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 HInstruction* instr = it.Current(); | 114 HInstruction* instr = it.Current(); |
| 115 if (instr->HasRange()) instr->PoisonRange(); | 115 if (instr->HasRange()) instr->PoisonRange(); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 #endif | 118 #endif |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test, | 122 void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test, |
| 123 HBasicBlock* dest) { | 123 HBasicBlock* dest) { |
| 124 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); | 124 DCHECK((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); |
| 125 if (test->representation().IsSmiOrInteger32()) { | 125 if (test->representation().IsSmiOrInteger32()) { |
| 126 Token::Value op = test->token(); | 126 Token::Value op = test->token(); |
| 127 if (test->SecondSuccessor() == dest) { | 127 if (test->SecondSuccessor() == dest) { |
| 128 op = Token::NegateCompareOp(op); | 128 op = Token::NegateCompareOp(op); |
| 129 } | 129 } |
| 130 Token::Value inverted_op = Token::ReverseCompareOp(op); | 130 Token::Value inverted_op = Token::ReverseCompareOp(op); |
| 131 UpdateControlFlowRange(op, test->left(), test->right()); | 131 UpdateControlFlowRange(op, test->left(), test->right()); |
| 132 UpdateControlFlowRange(inverted_op, test->right(), test->left()); | 132 UpdateControlFlowRange(inverted_op, test->right(), test->left()); |
| 133 } | 133 } |
| 134 } | 134 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 | 165 |
| 166 if (new_range != NULL && !new_range->IsMostGeneric()) { | 166 if (new_range != NULL && !new_range->IsMostGeneric()) { |
| 167 AddRange(value, new_range); | 167 AddRange(value, new_range); |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 void HRangeAnalysisPhase::InferRange(HValue* value) { | 172 void HRangeAnalysisPhase::InferRange(HValue* value) { |
| 173 ASSERT(!value->HasRange()); | 173 DCHECK(!value->HasRange()); |
| 174 if (!value->representation().IsNone()) { | 174 if (!value->representation().IsNone()) { |
| 175 value->ComputeInitialRange(graph()->zone()); | 175 value->ComputeInitialRange(graph()->zone()); |
| 176 Range* range = value->range(); | 176 Range* range = value->range(); |
| 177 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n", | 177 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n", |
| 178 value->id(), | 178 value->id(), |
| 179 value->Mnemonic(), | 179 value->Mnemonic(), |
| 180 range->lower(), | 180 range->lower(), |
| 181 range->upper()); | 181 range->upper()); |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 void HRangeAnalysisPhase::RollBackTo(int index) { | 186 void HRangeAnalysisPhase::RollBackTo(int index) { |
| 187 ASSERT(index <= changed_ranges_.length()); | 187 DCHECK(index <= changed_ranges_.length()); |
| 188 for (int i = index; i < changed_ranges_.length(); ++i) { | 188 for (int i = index; i < changed_ranges_.length(); ++i) { |
| 189 changed_ranges_[i]->RemoveLastAddedRange(); | 189 changed_ranges_[i]->RemoveLastAddedRange(); |
| 190 } | 190 } |
| 191 changed_ranges_.Rewind(index); | 191 changed_ranges_.Rewind(index); |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) { | 195 void HRangeAnalysisPhase::AddRange(HValue* value, Range* range) { |
| 196 Range* original_range = value->range(); | 196 Range* original_range = value->range(); |
| 197 value->AddNewRange(range, graph()->zone()); | 197 value->AddNewRange(range, graph()->zone()); |
| 198 changed_ranges_.Add(value, zone()); | 198 changed_ranges_.Add(value, zone()); |
| 199 Range* new_range = value->range(); | 199 Range* new_range = value->range(); |
| 200 TraceRange("Updated range of %d set to [%d,%d]\n", | 200 TraceRange("Updated range of %d set to [%d,%d]\n", |
| 201 value->id(), | 201 value->id(), |
| 202 new_range->lower(), | 202 new_range->lower(), |
| 203 new_range->upper()); | 203 new_range->upper()); |
| 204 if (original_range != NULL) { | 204 if (original_range != NULL) { |
| 205 TraceRange("Original range was [%d,%d]\n", | 205 TraceRange("Original range was [%d,%d]\n", |
| 206 original_range->lower(), | 206 original_range->lower(), |
| 207 original_range->upper()); | 207 original_range->upper()); |
| 208 } | 208 } |
| 209 TraceRange("New information was [%d,%d]\n", | 209 TraceRange("New information was [%d,%d]\n", |
| 210 range->lower(), | 210 range->lower(), |
| 211 range->upper()); | 211 range->upper()); |
| 212 } | 212 } |
| 213 | 213 |
| 214 | 214 |
| 215 void HRangeAnalysisPhase::PropagateMinusZeroChecks(HValue* value) { | 215 void HRangeAnalysisPhase::PropagateMinusZeroChecks(HValue* value) { |
| 216 ASSERT(worklist_.is_empty()); | 216 DCHECK(worklist_.is_empty()); |
| 217 ASSERT(in_worklist_.IsEmpty()); | 217 DCHECK(in_worklist_.IsEmpty()); |
| 218 | 218 |
| 219 AddToWorklist(value); | 219 AddToWorklist(value); |
| 220 while (!worklist_.is_empty()) { | 220 while (!worklist_.is_empty()) { |
| 221 value = worklist_.RemoveLast(); | 221 value = worklist_.RemoveLast(); |
| 222 | 222 |
| 223 if (value->IsPhi()) { | 223 if (value->IsPhi()) { |
| 224 // For phis, we must propagate the check to all of its inputs. | 224 // For phis, we must propagate the check to all of its inputs. |
| 225 HPhi* phi = HPhi::cast(value); | 225 HPhi* phi = HPhi::cast(value); |
| 226 for (int i = 0; i < phi->OperandCount(); ++i) { | 226 for (int i = 0; i < phi->OperandCount(); ++i) { |
| 227 AddToWorklist(phi->OperandAt(i)); | 227 AddToWorklist(phi->OperandAt(i)); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 AddToWorklist(instr->left()); | 275 AddToWorklist(instr->left()); |
| 276 } | 276 } |
| 277 } else if (value->IsMathMinMax()) { | 277 } else if (value->IsMathMinMax()) { |
| 278 HMathMinMax* instr = HMathMinMax::cast(value); | 278 HMathMinMax* instr = HMathMinMax::cast(value); |
| 279 AddToWorklist(instr->right()); | 279 AddToWorklist(instr->right()); |
| 280 AddToWorklist(instr->left()); | 280 AddToWorklist(instr->left()); |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 | 283 |
| 284 in_worklist_.Clear(); | 284 in_worklist_.Clear(); |
| 285 ASSERT(in_worklist_.IsEmpty()); | 285 DCHECK(in_worklist_.IsEmpty()); |
| 286 ASSERT(worklist_.is_empty()); | 286 DCHECK(worklist_.is_empty()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 | 289 |
| 290 } } // namespace v8::internal | 290 } } // namespace v8::internal |
| OLD | NEW |