| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 0bca49d40ae69d1d5232f388d9ac51ad66ee3273..159e32d840d54673dc223368d4c0db629def9387 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -37,6 +37,7 @@
|
| #include "hydrogen-escape-analysis.h"
|
| #include "hydrogen-infer-representation.h"
|
| #include "hydrogen-gvn.h"
|
| +#include "hydrogen-range-analysis.h"
|
| #include "lithium-allocator.h"
|
| #include "parser.h"
|
| #include "scopeinfo.h"
|
| @@ -2567,169 +2568,6 @@ void HGraph::InferTypes(ZoneList<HValue*>* worklist) {
|
| }
|
|
|
|
|
| -class HRangeAnalysis BASE_EMBEDDED {
|
| - public:
|
| - explicit HRangeAnalysis(HGraph* graph) :
|
| - graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { }
|
| -
|
| - void Analyze();
|
| -
|
| - private:
|
| - void TraceRange(const char* msg, ...);
|
| - void Analyze(HBasicBlock* block);
|
| - void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest);
|
| - void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other);
|
| - void InferRange(HValue* value);
|
| - void RollBackTo(int index);
|
| - void AddRange(HValue* value, Range* range);
|
| -
|
| - HGraph* graph_;
|
| - Zone* zone_;
|
| - ZoneList<HValue*> changed_ranges_;
|
| -};
|
| -
|
| -
|
| -void HRangeAnalysis::TraceRange(const char* msg, ...) {
|
| - if (FLAG_trace_range) {
|
| - va_list arguments;
|
| - va_start(arguments, msg);
|
| - OS::VPrint(msg, arguments);
|
| - va_end(arguments);
|
| - }
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::Analyze() {
|
| - HPhase phase("H_Range analysis", graph_);
|
| - Analyze(graph_->entry_block());
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::Analyze(HBasicBlock* block) {
|
| - TraceRange("Analyzing block B%d\n", block->block_id());
|
| -
|
| - int last_changed_range = changed_ranges_.length() - 1;
|
| -
|
| - // Infer range based on control flow.
|
| - if (block->predecessors()->length() == 1) {
|
| - HBasicBlock* pred = block->predecessors()->first();
|
| - if (pred->end()->IsCompareIDAndBranch()) {
|
| - InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block);
|
| - }
|
| - }
|
| -
|
| - // Process phi instructions.
|
| - for (int i = 0; i < block->phis()->length(); ++i) {
|
| - HPhi* phi = block->phis()->at(i);
|
| - InferRange(phi);
|
| - }
|
| -
|
| - // Go through all instructions of the current block.
|
| - for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
|
| - InferRange(it.Current());
|
| - }
|
| -
|
| - // Continue analysis in all dominated blocks.
|
| - for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
|
| - Analyze(block->dominated_blocks()->at(i));
|
| - }
|
| -
|
| - RollBackTo(last_changed_range);
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test,
|
| - HBasicBlock* dest) {
|
| - ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
|
| - if (test->representation().IsSmiOrInteger32()) {
|
| - Token::Value op = test->token();
|
| - if (test->SecondSuccessor() == dest) {
|
| - op = Token::NegateCompareOp(op);
|
| - }
|
| - Token::Value inverted_op = Token::ReverseCompareOp(op);
|
| - UpdateControlFlowRange(op, test->left(), test->right());
|
| - UpdateControlFlowRange(inverted_op, test->right(), test->left());
|
| - }
|
| -}
|
| -
|
| -
|
| -// We know that value [op] other. Use this information to update the range on
|
| -// value.
|
| -void HRangeAnalysis::UpdateControlFlowRange(Token::Value op,
|
| - HValue* value,
|
| - HValue* other) {
|
| - Range temp_range;
|
| - Range* range = other->range() != NULL ? other->range() : &temp_range;
|
| - Range* new_range = NULL;
|
| -
|
| - TraceRange("Control flow range infer %d %s %d\n",
|
| - value->id(),
|
| - Token::Name(op),
|
| - other->id());
|
| -
|
| - if (op == Token::EQ || op == Token::EQ_STRICT) {
|
| - // The same range has to apply for value.
|
| - new_range = range->Copy(zone_);
|
| - } else if (op == Token::LT || op == Token::LTE) {
|
| - new_range = range->CopyClearLower(zone_);
|
| - if (op == Token::LT) {
|
| - new_range->AddConstant(-1);
|
| - }
|
| - } else if (op == Token::GT || op == Token::GTE) {
|
| - new_range = range->CopyClearUpper(zone_);
|
| - if (op == Token::GT) {
|
| - new_range->AddConstant(1);
|
| - }
|
| - }
|
| -
|
| - if (new_range != NULL && !new_range->IsMostGeneric()) {
|
| - AddRange(value, new_range);
|
| - }
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::InferRange(HValue* value) {
|
| - ASSERT(!value->HasRange());
|
| - if (!value->representation().IsNone()) {
|
| - value->ComputeInitialRange(zone_);
|
| - Range* range = value->range();
|
| - TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n",
|
| - value->id(),
|
| - value->Mnemonic(),
|
| - range->lower(),
|
| - range->upper());
|
| - }
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::RollBackTo(int index) {
|
| - for (int i = index + 1; i < changed_ranges_.length(); ++i) {
|
| - changed_ranges_[i]->RemoveLastAddedRange();
|
| - }
|
| - changed_ranges_.Rewind(index + 1);
|
| -}
|
| -
|
| -
|
| -void HRangeAnalysis::AddRange(HValue* value, Range* range) {
|
| - Range* original_range = value->range();
|
| - value->AddNewRange(range, zone_);
|
| - changed_ranges_.Add(value, zone_);
|
| - Range* new_range = value->range();
|
| - TraceRange("Updated range of %d set to [%d,%d]\n",
|
| - value->id(),
|
| - new_range->lower(),
|
| - new_range->upper());
|
| - if (original_range != NULL) {
|
| - TraceRange("Original range was [%d,%d]\n",
|
| - original_range->lower(),
|
| - original_range->upper());
|
| - }
|
| - TraceRange("New information was [%d,%d]\n",
|
| - range->lower(),
|
| - range->upper());
|
| -}
|
| -
|
| -
|
| class HStackCheckEliminator BASE_EMBEDDED {
|
| public:
|
| explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { }
|
| @@ -3822,10 +3660,8 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
|
|
| if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
|
|
|
| - if (FLAG_use_range) {
|
| - HRangeAnalysis range_analysis(this);
|
| - range_analysis.Analyze();
|
| - }
|
| + if (FLAG_use_range) Run<HRangeAnalysisPhase>();
|
| +
|
| ComputeMinusZeroChecks();
|
|
|
| // Eliminate redundant stack checks on backwards branches.
|
|
|