author | David Anderson <danderson@mozilla.com> |
Wed, 27 Jun 2012 13:05:57 -0700 | |
changeset 106476 | 62c180773b87fd633d8013f7d77e0e3633d3b0df |
parent 106475 | 839a7e46762087aca46c2c016fc32c9898b79441 |
child 106477 | c47c09bf5775598666faa7e975525ef539d731bd |
push id | 23447 |
push user | danderson@mozilla.com |
push date | Tue, 11 Sep 2012 17:34:27 +0000 |
treeherder | mozilla-central@fdfaef738a00 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 16.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/Makefile.in | file | annotate | diff | comparison | revisions | |
js/src/ion/EdgeCaseAnalysis.cpp | file | annotate | diff | comparison | revisions | |
js/src/ion/EdgeCaseAnalysis.h | file | annotate | diff | comparison | revisions | |
js/src/ion/Ion.cpp | file | annotate | diff | comparison | revisions | |
js/src/ion/Ion.h | file | annotate | diff | comparison | revisions | |
js/src/ion/MIR.cpp | file | annotate | diff | comparison | revisions | |
js/src/ion/MIR.h | file | annotate | diff | comparison | revisions | |
js/src/ion/RangeAnalysis.cpp | file | annotate | diff | comparison | revisions | |
js/src/ion/RangeAnalysis.h | file | annotate | diff | comparison | revisions | |
js/src/shell/js.cpp | file | annotate | diff | comparison | revisions |
--- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -272,17 +272,17 @@ CPPSRCS += MIR.cpp \ LICM.cpp \ LinearScan.cpp \ LIR.cpp \ Lowering.cpp \ Lowering-shared.cpp \ MCallOptimize.cpp \ MIRGraph.cpp \ MoveResolver.cpp \ - EdgeCaseAnalysis.cpp \ + RangeAnalysis.cpp \ Snapshots.cpp \ Safepoints.cpp \ TypeOracle.cpp \ TypePolicy.cpp \ ValueNumbering.cpp \ VMFunctions.cpp \ AliasAnalysis.cpp \ $(NULL)
deleted file mode 100644 --- a/js/src/ion/EdgeCaseAnalysis.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=4 sw=4 et tw=79: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> - -#include "Ion.h" -#include "IonSpewer.h" -#include "EdgeCaseAnalysis.h" -#include "MIR.h" -#include "MIRGraph.h" - -using namespace js; -using namespace js::ion; - -EdgeCaseAnalysis::EdgeCaseAnalysis(MIRGraph &graph) - : graph(graph) -{ -} - -bool -EdgeCaseAnalysis::analyzeLate() -{ - for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) { - for (MDefinitionIterator iter(*block); iter; iter++) - iter->analyzeEdgeCasesForward(); - } - - for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) { - for (MInstructionReverseIterator riter(block->rbegin()); riter != block->rend(); riter++) - riter->analyzeEdgeCasesBackward(); - } - - return true; -} - -bool -EdgeCaseAnalysis::analyzeEarly() -{ - - for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) { - for (MInstructionReverseIterator riter(block->rbegin()); riter != block->rend(); riter++) - riter->analyzeTruncateBackward(); - } - - return true; -} - -bool -EdgeCaseAnalysis::AllUsesTruncate(MInstruction *m) -{ - for (MUseIterator use = m->usesBegin(); use != m->usesEnd(); use++) { - if (use->node()->isResumePoint()) - return false; - - MDefinition *def = use->node()->toDefinition(); - if (def->isTruncateToInt32()) - continue; - if (def->isBitAnd()) - continue; - if (def->isBitOr()) - continue; - if (def->isBitXor()) - continue; - if (def->isLsh()) - continue; - if (def->isRsh()) - continue; - if (def->isBitNot()) - continue; - if (def->isAdd() && def->toAdd()->isTruncated()) - continue; - if (def->isSub() && def->toSub()->isTruncated()) - continue; - // cannot use divide, since |truncate(int32(x/y) + int32(a/b)) != truncate(x/y+a/b)| - return false; - } - return true; -}
deleted file mode 100644 --- a/js/src/ion/EdgeCaseAnalysis.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=4 sw=4 et tw=79: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef jsion_ion_edge_case_analysis_h__ -#define jsion_ion_edge_case_analysis_h__ - -namespace js { -namespace ion { - -class MIRGraph; - -class EdgeCaseAnalysis -{ - MIRGraph &graph; - - public: - EdgeCaseAnalysis(MIRGraph &graph); - bool analyzeEarly(); - bool analyzeLate(); - static bool AllUsesTruncate(MInstruction *m); -}; - - -} // namespace ion -} // namespace js - -#endif // jsion_ion_edge_case_analysis_h__ -
--- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -43,17 +43,17 @@ #include "IonAnalysis.h" #include "IonBuilder.h" #include "IonSpewer.h" #include "LIR.h" #include "AliasAnalysis.h" #include "GreedyAllocator.h" #include "LICM.h" #include "ValueNumbering.h" -#include "EdgeCaseAnalysis.h" +#include "RangeAnalysis.h" #include "LinearScan.h" #include "jscompartment.h" #include "IonCompartment.h" #include "CodeGenerator.h" #if defined(JS_CPU_X86) # include "x86/Lowering-x86.h" #elif defined(JS_CPU_X64) @@ -756,21 +756,21 @@ TestCompiler(IonBuilder &builder, MIRGra if (js_IonOptions.licm || js_IonOptions.gvn) { AliasAnalysis analysis(graph); if (!analysis.analyze()) return false; IonSpewPass("Alias analysis"); AssertGraphCoherency(graph); } - if (js_IonOptions.edgeCaseAnalysis) { - EdgeCaseAnalysis edgeCaseAnalysis(graph); - if (!edgeCaseAnalysis.analyzeEarly()) + if (js_IonOptions.rangeAnalysis) { + RangeAnalysis rangeAnalysis(graph); + if (!rangeAnalysis.analyzeEarly()) return false; - IonSpewPass("Edge Case Analysis (Early)"); + IonSpewPass("Range Analysis (Early)"); AssertGraphCoherency(graph); } if (js_IonOptions.gvn) { ValueNumberer gvn(graph, js_IonOptions.gvnIsOptimistic); if (!gvn.analyze()) return false; IonSpewPass("GVN"); @@ -785,21 +785,21 @@ TestCompiler(IonBuilder &builder, MIRGra if (js_IonOptions.licm) { LICM licm(graph); if (!licm.analyze()) return false; IonSpewPass("LICM"); AssertGraphCoherency(graph); } - if (js_IonOptions.edgeCaseAnalysis) { - EdgeCaseAnalysis edgeCaseAnalysis(graph); - if (!edgeCaseAnalysis.analyzeLate()) + if (js_IonOptions.rangeAnalysis) { + RangeAnalysis rangeAnalysis(graph); + if (!rangeAnalysis.analyzeLate()) return false; - IonSpewPass("Edge Case Analysis (Late)"); + IonSpewPass("Range Analysis (Late)"); AssertGraphCoherency(graph); } LIRGraph lir(graph); LIRGenerator lirgen(&builder, graph, lir); if (!lirgen.generate()) return false; IonSpewPass("Generate LIR");
--- a/js/src/ion/Ion.h +++ b/js/src/ion/Ion.h @@ -86,20 +86,20 @@ struct IonOptions // Default: true bool lsra; // Toggles whether inlining is performed. // // Default: true bool inlining; - // Toggles whether Edge Case Analysis is used. + // Toggles whether Range Analysis is used. // // Default: true - bool edgeCaseAnalysis; + bool rangeAnalysis; // How many invocations or loop iterations are needed before functions // are compiled. // // Default: 10,240 uint32 usesBeforeCompile; // How many invocations or loop iterations are needed before functions @@ -147,17 +147,17 @@ struct IonOptions IonOptions() : gvn(true), gvnIsOptimistic(true), licm(true), osr(true), limitScriptSize(true), lsra(true), inlining(true), - edgeCaseAnalysis(true), + rangeAnalysis(true), usesBeforeCompile(10240), usesBeforeCompileNoJaeger(40), usesBeforeInlining(usesBeforeCompile), maxStackArgs(4096), smallFunctionMaxBytecodeLength(100), smallFunctionUsesBeforeInlining(usesBeforeInlining / 4) { } };
--- a/js/src/ion/MIR.cpp +++ b/js/src/ion/MIR.cpp @@ -38,17 +38,17 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "IonBuilder.h" #include "LICM.h" // For LinearSum #include "MIR.h" #include "MIRGraph.h" -#include "EdgeCaseAnalysis.h" +#include "RangeAnalysis.h" #include "jsnum.h" #include "jstypedarrayinlines.h" // For ClampIntForUint8Array using namespace js; using namespace js::ion; void MDefinition::PrintOpcodeName(FILE *fp, MDefinition::Opcode op) @@ -181,23 +181,23 @@ MDefinition::congruentIfOperandsEqual(MD MDefinition * MDefinition::foldsTo(bool useValueNumbers) { // In the default case, there are no constants to fold. return this; } void -MDefinition::analyzeEdgeCasesForward() +MDefinition::analyzeRangeForward() { return; } void -MDefinition::analyzeEdgeCasesBackward() +MDefinition::analyzeRangeBackward() { return; } void MDefinition::analyzeTruncateBackward() { return; } @@ -690,17 +690,17 @@ MDiv::foldsTo(bool useValueNumbers) // x / 1 -> x if (IsConstant(lhs(), 0) || IsConstant(rhs(), 1)) return lhs(); return this; } void -MDiv::analyzeEdgeCasesForward() +MDiv::analyzeRangeForward() { // This is only meaningful when doing integer division. if (specialization_ != MIRType_Int32) return; // Try removing divide by zero check if (rhs()->isConstant() && !rhs()->toConstant()->value().isInt32(0)) canBeDivideByZero_ = false; @@ -722,35 +722,35 @@ MDiv::analyzeEdgeCasesForward() if (rhs()->isConstant()) { const js::Value &val = rhs()->toConstant()->value(); if (val.isInt32() && val.toInt32() >= 0) canBeNegativeZero_ = false; } } void -MDiv::analyzeEdgeCasesBackward() +MDiv::analyzeRangeBackward() { if (canBeNegativeZero_) canBeNegativeZero_ = NeedNegativeZeroCheck(this); } void MDiv::analyzeTruncateBackward() { if (!isTruncated()) - setTruncated(js::ion::EdgeCaseAnalysis::AllUsesTruncate(this)); + setTruncated(js::ion::RangeAnalysis::AllUsesTruncate(this)); } bool MDiv::updateForReplacement(MDefinition *ins_) { JS_ASSERT(ins_->isDiv()); MDiv *ins = ins_->toDiv(); - // Since EdgeCaseAnalysis is not being run before GVN, its information does + // Since RangeAnalysis is not being run before GVN, its information does // not need to be merged here. if (isTruncated()) setTruncated(ins->isTruncated()); return true; } static inline MDefinition * TryFold(MDefinition *original, MDefinition *replacement) @@ -808,34 +808,34 @@ MMod::foldsTo(bool useValueNumbers) return this; } void MAdd::analyzeTruncateBackward() { if (!isTruncated()) - setTruncated(js::ion::EdgeCaseAnalysis::AllUsesTruncate(this)); + setTruncated(js::ion::RangeAnalysis::AllUsesTruncate(this)); } bool MAdd::updateForReplacement(MDefinition *ins_) { JS_ASSERT(ins_->isAdd()); MAdd *ins = ins_->toAdd(); if (isTruncated()) setTruncated(ins->isTruncated()); return true; } void MSub::analyzeTruncateBackward() { if (!isTruncated()) - setTruncated(js::ion::EdgeCaseAnalysis::AllUsesTruncate(this)); + setTruncated(js::ion::RangeAnalysis::AllUsesTruncate(this)); } bool MSub::updateForReplacement(MDefinition *ins_) { JS_ASSERT(ins_->isSub()); MSub *ins = ins_->toSub(); if (isTruncated()) @@ -855,17 +855,17 @@ MMul::foldsTo(bool useValueNumbers) if (lhs()->congruentTo(rhs())) canBeNegativeZero_ = false; return this; } void -MMul::analyzeEdgeCasesForward() +MMul::analyzeRangeForward() { // Try to remove the check for negative zero // This only makes sense when using the integer multiplication if (specialization() != MIRType_Int32) return; // If lhs is > 0, no need for negative zero check. if (lhs()->isConstant()) { @@ -879,17 +879,17 @@ MMul::analyzeEdgeCasesForward() const js::Value &val = rhs()->toConstant()->value(); if (val.isInt32() && val.toInt32() > 0) canBeNegativeZero_ = false; } } void -MMul::analyzeEdgeCasesBackward() +MMul::analyzeRangeBackward() { if (canBeNegativeZero_) canBeNegativeZero_ = NeedNegativeZeroCheck(this); } bool MMul::updateForReplacement(MDefinition *ins) { @@ -1159,17 +1159,17 @@ MToInt32::foldsTo(bool useValueNumbers) { MDefinition *input = getOperand(0); if (input->type() == MIRType_Int32) return input; return this; } void -MToInt32::analyzeEdgeCasesBackward() +MToInt32::analyzeRangeBackward() { canBeNegativeZero_ = NeedNegativeZeroCheck(this); } MDefinition * MTruncateToInt32::foldsTo(bool useValueNumbers) { MDefinition *input = getOperand(0);
--- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -323,18 +323,18 @@ class MDefinition : public MNode virtual void printOpcode(FILE *fp); virtual HashNumber valueHash() const; virtual bool congruentTo(MDefinition* const &ins) const { return false; } bool congruentIfOperandsEqual(MDefinition * const &ins) const; virtual MDefinition *foldsTo(bool useValueNumbers); - virtual void analyzeEdgeCasesForward(); - virtual void analyzeEdgeCasesBackward(); + virtual void analyzeRangeForward(); + virtual void analyzeRangeBackward(); virtual void analyzeTruncateBackward(); MNode::Kind kind() const { return MNode::Definition; } uint32 id() const { JS_ASSERT(block_); @@ -1625,17 +1625,17 @@ class MToInt32 : public MUnaryInstructio MDefinition *input() const { return getOperand(0); } MDefinition *foldsTo(bool useValueNumbers); // this only has backwards information flow. - void analyzeEdgeCasesBackward(); + void analyzeRangeBackward(); bool canBeNegativeZero() { return canBeNegativeZero_; } bool congruentTo(MDefinition *const &ins) const { return congruentIfOperandsEqual(ins); } @@ -2213,18 +2213,18 @@ class MMul : public MBinaryArithInstruct public: INSTRUCTION_HEADER(Mul); static MMul *New(MDefinition *left, MDefinition *right) { return new MMul(left, right); } MDefinition *foldsTo(bool useValueNumbers); - void analyzeEdgeCasesForward(); - void analyzeEdgeCasesBackward(); + void analyzeRangeForward(); + void analyzeRangeBackward(); double getIdentity() { return 1; } bool canOverflow() { return canOverflow_; } @@ -2258,18 +2258,18 @@ class MDiv : public MBinaryArithInstruct public: INSTRUCTION_HEADER(Div); static MDiv *New(MDefinition *left, MDefinition *right) { return new MDiv(left, right); } MDefinition *foldsTo(bool useValueNumbers); - void analyzeEdgeCasesForward(); - void analyzeEdgeCasesBackward(); + void analyzeRangeForward(); + void analyzeRangeBackward(); void analyzeTruncateBackward(); double getIdentity() { JS_NOT_REACHED("not used"); return 1; } bool isTruncated() const {
new file mode 100644 --- /dev/null +++ b/js/src/ion/RangeAnalysis.cpp @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=4 sw=4 et tw=79: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <stdio.h> + +#include "Ion.h" +#include "IonSpewer.h" +#include "RangeAnalysis.h" +#include "MIR.h" +#include "MIRGraph.h" + +using namespace js; +using namespace js::ion; + +RangeAnalysis::RangeAnalysis(MIRGraph &graph) + : graph(graph) +{ +} + +bool +RangeAnalysis::analyzeLate() +{ + for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) { + for (MDefinitionIterator iter(*block); iter; iter++) + iter->analyzeRangeForward(); + } + + for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) { + for (MInstructionReverseIterator riter(block->rbegin()); riter != block->rend(); riter++) + riter->analyzeRangeBackward(); + } + + return true; +} + +bool +RangeAnalysis::analyzeEarly() +{ + + for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) { + for (MInstructionReverseIterator riter(block->rbegin()); riter != block->rend(); riter++) + riter->analyzeTruncateBackward(); + } + + return true; +} + +bool +RangeAnalysis::AllUsesTruncate(MInstruction *m) +{ + for (MUseIterator use = m->usesBegin(); use != m->usesEnd(); use++) { + if (use->node()->isResumePoint()) + return false; + + MDefinition *def = use->node()->toDefinition(); + if (def->isTruncateToInt32()) + continue; + if (def->isBitAnd()) + continue; + if (def->isBitOr()) + continue; + if (def->isBitXor()) + continue; + if (def->isLsh()) + continue; + if (def->isRsh()) + continue; + if (def->isBitNot()) + continue; + if (def->isAdd() && def->toAdd()->isTruncated()) + continue; + if (def->isSub() && def->toSub()->isTruncated()) + continue; + // cannot use divide, since |truncate(int32(x/y) + int32(a/b)) != truncate(x/y+a/b)| + return false; + } + return true; +}
new file mode 100644 --- /dev/null +++ b/js/src/ion/RangeAnalysis.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=4 sw=4 et tw=79: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jsion_ion_range_analysis_h__ +#define jsion_ion_range_analysis_h__ + +namespace js { +namespace ion { + +class MIRGraph; + +class RangeAnalysis +{ + MIRGraph &graph; + + public: + RangeAnalysis(MIRGraph &graph); + bool analyzeEarly(); + bool analyzeLate(); + static bool AllUsesTruncate(MInstruction *m); +}; + + +} // namespace ion +} // namespace js + +#endif // jsion_ion_range_analysis_h__ +
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4706,23 +4706,23 @@ ProcessArgs(JSContext *cx, JSObject *obj if (strcmp(str, "on") == 0) ion::js_IonOptions.licm = true; else if (strcmp(str, "off") == 0) ion::js_IonOptions.licm = false; else return OptionFailure("ion-licm", str); } - if (const char *str = op->getStringOption("ion-edgecase-analysis")) { + if (const char *str = op->getStringOption("ion-range-analysis")) { if (strcmp(str, "on") == 0) - ion::js_IonOptions.edgeCaseAnalysis = true; + ion::js_IonOptions.rangeAnalysis = true; else if (strcmp(str, "off") == 0) - ion::js_IonOptions.edgeCaseAnalysis = false; + ion::js_IonOptions.rangeAnalysis = false; else - return OptionFailure("ion-edgecase-analysis", str); + return OptionFailure("ion-range-analysis", str); } if (const char *str = op->getStringOption("ion-inlining")) { if (strcmp(str, "on") == 0) ion::js_IonOptions.inlining = true; else if (strcmp(str, "off") == 0) ion::js_IonOptions.inlining = false; else @@ -4966,18 +4966,18 @@ main(int argc, char **argv, char **envp) || !op.addBoolOption('\0', "no-ion", "Disable IonMonkey") || !op.addStringOption('\0', "ion-gvn", "[mode]", "Specify Ion global value numbering:\n" " off: disable GVN\n" " pessimistic: (default) use pessimistic GVN\n" " optimistic: use optimistic GVN") || !op.addStringOption('\0', "ion-licm", "on/off", "Loop invariant code motion (default: on, off to disable)") - || !op.addStringOption('\0', "ion-edgecase-analysis", "on/off", - "Find edge cases where Ion can avoid bailouts (default: on, off to disable)") + || !op.addStringOption('\0', "ion-range-analysis", "on/off", + "Range Analysis (default: on, off to disable)") || !op.addStringOption('\0', "ion-inlining", "on/off", "Inline methods where possible (default: on, off to disable)") || !op.addStringOption('\0', "ion-osr", "on/off", "On-Stack Replacement (default: on, off to disable)") || !op.addStringOption('\0', "ion-limit-script-size", "on/off", "Don't compile very large scripts (default: on, off to disable)") || !op.addStringOption('\0', "ion-regalloc", "[mode]", "Specify Ion register allocation:\n"