diff options
Diffstat (limited to 'js/src/jit/IonAnalysis.h')
-rw-r--r-- | js/src/jit/IonAnalysis.h | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h new file mode 100644 index 0000000000..1ce8edc804 --- /dev/null +++ b/js/src/jit/IonAnalysis.h @@ -0,0 +1,218 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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 jit_IonAnalysis_h +#define jit_IonAnalysis_h + +// This file declares various analysis passes that operate on MIR. + +#include "jit/JitAllocPolicy.h" +#include "jit/MIR.h" + +namespace js { +namespace jit { + +class MIRGenerator; +class MIRGraph; + +MOZ_MUST_USE bool +PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph); + +MOZ_MUST_USE bool +FoldTests(MIRGraph& graph); + +MOZ_MUST_USE bool +SplitCriticalEdges(MIRGraph& graph); + +bool +IsUint32Type(const MDefinition* def); + +enum Observability { + ConservativeObservability, + AggressiveObservability +}; + +MOZ_MUST_USE bool +EliminatePhis(MIRGenerator* mir, MIRGraph& graph, Observability observe); + +size_t +MarkLoopBlocks(MIRGraph& graph, MBasicBlock* header, bool* canOsr); + +void +UnmarkLoopBlocks(MIRGraph& graph, MBasicBlock* header); + +MOZ_MUST_USE bool +MakeLoopsContiguous(MIRGraph& graph); + +MOZ_MUST_USE bool +EliminateDeadResumePointOperands(MIRGenerator* mir, MIRGraph& graph); + +MOZ_MUST_USE bool +EliminateDeadCode(MIRGenerator* mir, MIRGraph& graph); + +MOZ_MUST_USE bool +ApplyTypeInformation(MIRGenerator* mir, MIRGraph& graph); + +MOZ_MUST_USE bool +MakeMRegExpHoistable(MIRGenerator* mir, MIRGraph& graph); + +void +RenumberBlocks(MIRGraph& graph); + +MOZ_MUST_USE bool +AccountForCFGChanges(MIRGenerator* mir, MIRGraph& graph, bool updateAliasAnalysis, + bool underValueNumberer = false); + +MOZ_MUST_USE bool +RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, uint32_t numMarkedBlocks); + +MOZ_MUST_USE bool +CreateMIRRootList(IonBuilder& builder); + +void +ClearDominatorTree(MIRGraph& graph); + +MOZ_MUST_USE bool +BuildDominatorTree(MIRGraph& graph); + +MOZ_MUST_USE bool +BuildPhiReverseMapping(MIRGraph& graph); + +void +AssertBasicGraphCoherency(MIRGraph& graph); + +void +AssertGraphCoherency(MIRGraph& graph); + +void +AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer = false); + +MOZ_MUST_USE bool +EliminateRedundantChecks(MIRGraph& graph); + +MOZ_MUST_USE bool +AddKeepAliveInstructions(MIRGraph& graph); + +class MDefinition; + +// Simple linear sum of the form 'n' or 'x + n'. +struct SimpleLinearSum +{ + MDefinition* term; + int32_t constant; + + SimpleLinearSum(MDefinition* term, int32_t constant) + : term(term), constant(constant) + {} +}; + +// Math done in a Linear sum can either be in a modulo space, in which case +// overflow are wrapped around, or they can be computed in the integer-space in +// which case we have to check that no overflow can happen when summing +// constants. +// +// When the caller ignores which space it is, the definition would be used to +// deduce it. +enum class MathSpace { + Modulo, + Infinite, + Unknown +}; + +SimpleLinearSum +ExtractLinearSum(MDefinition* ins, MathSpace space = MathSpace::Unknown); + +MOZ_MUST_USE bool +ExtractLinearInequality(MTest* test, BranchDirection direction, + SimpleLinearSum* plhs, MDefinition** prhs, bool* plessEqual); + +struct LinearTerm +{ + MDefinition* term; + int32_t scale; + + LinearTerm(MDefinition* term, int32_t scale) + : term(term), scale(scale) + { + } +}; + +// General linear sum of the form 'x1*n1 + x2*n2 + ... + n' +class LinearSum +{ + public: + explicit LinearSum(TempAllocator& alloc) + : terms_(alloc), + constant_(0) + { + } + + LinearSum(const LinearSum& other) + : terms_(other.terms_.allocPolicy()), + constant_(other.constant_) + { + AutoEnterOOMUnsafeRegion oomUnsafe; + if (!terms_.appendAll(other.terms_)) + oomUnsafe.crash("LinearSum::LinearSum"); + } + + // These return false on an integer overflow, and afterwards the sum must + // not be used. + MOZ_MUST_USE bool multiply(int32_t scale); + MOZ_MUST_USE bool add(const LinearSum& other, int32_t scale = 1); + MOZ_MUST_USE bool add(SimpleLinearSum other, int32_t scale = 1); + MOZ_MUST_USE bool add(MDefinition* term, int32_t scale); + MOZ_MUST_USE bool add(int32_t constant); + + // Unlike the above function, on failure this leaves the sum unchanged and + // it can still be used. + MOZ_MUST_USE bool divide(uint32_t scale); + + int32_t constant() const { return constant_; } + size_t numTerms() const { return terms_.length(); } + LinearTerm term(size_t i) const { return terms_[i]; } + void replaceTerm(size_t i, MDefinition* def) { terms_[i].term = def; } + + void dump(GenericPrinter& out) const; + void dump() const; + + private: + Vector<LinearTerm, 2, JitAllocPolicy> terms_; + int32_t constant_; +}; + +// Convert all components of a linear sum (except, optionally, the constant) +// and add any new instructions to the end of block. +MDefinition* +ConvertLinearSum(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum, + bool convertConstant = false); + +// Convert the test 'sum >= 0' to a comparison, adding any necessary +// instructions to the end of block. +MCompare* +ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum); + +MOZ_MUST_USE bool +AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun, + ObjectGroup* group, HandlePlainObject baseobj, + Vector<TypeNewScript::Initializer>* initializerList); + +MOZ_MUST_USE bool +AnalyzeArgumentsUsage(JSContext* cx, JSScript* script); + +bool +DeadIfUnused(const MDefinition* def); + +bool +IsDiscardable(const MDefinition* def); + +void +DumpMIRExpressions(MIRGraph& graph); + +} // namespace jit +} // namespace js + +#endif /* jit_IonAnalysis_h */ |