blob: 49c6e898eb4a80a8c5bcce4776f900f91b4211cf [file] [log] [blame]
/* -*- 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;
bool
PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph);
bool
FoldTests(MIRGraph& graph);
bool
SplitCriticalEdges(MIRGraph& graph);
enum Observability {
ConservativeObservability,
AggressiveObservability
};
bool
EliminatePhis(MIRGenerator* mir, MIRGraph& graph, Observability observe);
size_t
MarkLoopBlocks(MIRGraph& graph, MBasicBlock* header, bool* canOsr);
void
UnmarkLoopBlocks(MIRGraph& graph, MBasicBlock* header);
bool
MakeLoopsContiguous(MIRGraph& graph);
bool
EliminateDeadResumePointOperands(MIRGenerator* mir, MIRGraph& graph);
bool
EliminateDeadCode(MIRGenerator* mir, MIRGraph& graph);
bool
ApplyTypeInformation(MIRGenerator* mir, MIRGraph& graph);
bool
MakeMRegExpHoistable(MIRGraph& graph);
bool
RenumberBlocks(MIRGraph& graph);
bool
AccountForCFGChanges(MIRGenerator* mir, MIRGraph& graph, bool updateAliasAnalysis);
bool
RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, uint32_t numMarkedBlocks);
void
ClearDominatorTree(MIRGraph& graph);
bool
BuildDominatorTree(MIRGraph& graph);
bool
BuildPhiReverseMapping(MIRGraph& graph);
void
AssertBasicGraphCoherency(MIRGraph& graph);
void
AssertGraphCoherency(MIRGraph& graph);
void
AssertExtendedGraphCoherency(MIRGraph& graph);
bool
EliminateRedundantChecks(MIRGraph& graph);
void
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)
{}
};
SimpleLinearSum
ExtractLinearSum(MDefinition* ins);
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.
bool multiply(int32_t scale);
bool add(const LinearSum& other, int32_t scale = 1);
bool add(SimpleLinearSum other, int32_t scale = 1);
bool add(MDefinition* term, int32_t scale);
bool add(int32_t constant);
// Unlike the above function, on failure this leaves the sum unchanged and
// it can still be used.
bool divide(int32_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);
bool
AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun,
ObjectGroup* group, HandlePlainObject baseobj,
Vector<TypeNewScript::Initializer>* initializerList);
bool
AnalyzeArgumentsUsage(JSContext* cx, JSScript* script);
bool
DeadIfUnused(const MDefinition* def);
bool
IsDiscardable(const MDefinition* def);
} // namespace jit
} // namespace js
#endif /* jit_IonAnalysis_h */