1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_IonAnalysis_h 8 #define jit_IonAnalysis_h 9 10 // This file declares various analysis passes that operate on MIR. 11 12 #include "jit/JitAllocPolicy.h" 13 14 namespace js { 15 16 class PlainObject; 17 18 namespace jit { 19 20 class MBasicBlock; 21 class MCompare; 22 class MDefinition; 23 class MIRGenerator; 24 class MIRGraph; 25 class MTest; 26 27 MOZ_MUST_USE bool PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph); 28 29 MOZ_MUST_USE bool FoldTests(MIRGraph& graph); 30 31 MOZ_MUST_USE bool FoldEmptyBlocks(MIRGraph& graph); 32 33 MOZ_MUST_USE bool SplitCriticalEdges(MIRGraph& graph); 34 35 bool IsUint32Type(const MDefinition* def); 36 37 enum Observability { ConservativeObservability, AggressiveObservability }; 38 39 MOZ_MUST_USE bool EliminatePhis(MIRGenerator* mir, MIRGraph& graph, 40 Observability observe); 41 42 size_t MarkLoopBlocks(MIRGraph& graph, MBasicBlock* header, bool* canOsr); 43 44 void UnmarkLoopBlocks(MIRGraph& graph, MBasicBlock* header); 45 46 MOZ_MUST_USE bool MakeLoopsContiguous(MIRGraph& graph); 47 48 MOZ_MUST_USE bool EliminateDeadResumePointOperands(MIRGenerator* mir, 49 MIRGraph& graph); 50 51 MOZ_MUST_USE bool EliminateDeadCode(MIRGenerator* mir, MIRGraph& graph); 52 53 MOZ_MUST_USE bool FoldLoadsWithUnbox(MIRGenerator* mir, MIRGraph& graph); 54 55 MOZ_MUST_USE bool ApplyTypeInformation(MIRGenerator* mir, MIRGraph& graph); 56 57 void RenumberBlocks(MIRGraph& graph); 58 59 MOZ_MUST_USE bool AccountForCFGChanges(MIRGenerator* mir, MIRGraph& graph, 60 bool updateAliasAnalysis, 61 bool underValueNumberer = false); 62 63 MOZ_MUST_USE bool RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, 64 uint32_t numMarkedBlocks); 65 66 void ClearDominatorTree(MIRGraph& graph); 67 68 MOZ_MUST_USE bool BuildDominatorTree(MIRGraph& graph); 69 70 MOZ_MUST_USE bool BuildPhiReverseMapping(MIRGraph& graph); 71 72 void AssertBasicGraphCoherency(MIRGraph& graph, bool force = false); 73 74 void AssertGraphCoherency(MIRGraph& graph, bool force = false); 75 76 void AssertExtendedGraphCoherency(MIRGraph& graph, 77 bool underValueNumberer = false, 78 bool force = false); 79 80 MOZ_MUST_USE bool EliminateRedundantChecks(MIRGraph& graph); 81 82 MOZ_MUST_USE bool AddKeepAliveInstructions(MIRGraph& graph); 83 84 // Simple linear sum of the form 'n' or 'x + n'. 85 struct SimpleLinearSum { 86 MDefinition* term; 87 int32_t constant; 88 SimpleLinearSumSimpleLinearSum89 SimpleLinearSum(MDefinition* term, int32_t constant) 90 : term(term), constant(constant) {} 91 }; 92 93 // Math done in a Linear sum can either be in a modulo space, in which case 94 // overflow are wrapped around, or they can be computed in the integer-space in 95 // which case we have to check that no overflow can happen when summing 96 // constants. 97 // 98 // When the caller ignores which space it is, the definition would be used to 99 // deduce it. 100 enum class MathSpace { Modulo, Infinite, Unknown }; 101 102 SimpleLinearSum ExtractLinearSum(MDefinition* ins, 103 MathSpace space = MathSpace::Unknown); 104 105 MOZ_MUST_USE bool ExtractLinearInequality(MTest* test, 106 BranchDirection direction, 107 SimpleLinearSum* plhs, 108 MDefinition** prhs, bool* plessEqual); 109 110 struct LinearTerm { 111 MDefinition* term; 112 int32_t scale; 113 LinearTermLinearTerm114 LinearTerm(MDefinition* term, int32_t scale) : term(term), scale(scale) {} 115 }; 116 117 // General linear sum of the form 'x1*n1 + x2*n2 + ... + n' 118 class LinearSum { 119 public: LinearSum(TempAllocator & alloc)120 explicit LinearSum(TempAllocator& alloc) : terms_(alloc), constant_(0) {} 121 LinearSum(const LinearSum & other)122 LinearSum(const LinearSum& other) 123 : terms_(other.terms_.allocPolicy()), constant_(other.constant_) { 124 AutoEnterOOMUnsafeRegion oomUnsafe; 125 if (!terms_.appendAll(other.terms_)) { 126 oomUnsafe.crash("LinearSum::LinearSum"); 127 } 128 } 129 130 // These return false on an integer overflow, and afterwards the sum must 131 // not be used. 132 MOZ_MUST_USE bool multiply(int32_t scale); 133 MOZ_MUST_USE bool add(const LinearSum& other, int32_t scale = 1); 134 MOZ_MUST_USE bool add(SimpleLinearSum other, int32_t scale = 1); 135 MOZ_MUST_USE bool add(MDefinition* term, int32_t scale); 136 MOZ_MUST_USE bool add(int32_t constant); 137 138 // Unlike the above function, on failure this leaves the sum unchanged and 139 // it can still be used. 140 MOZ_MUST_USE bool divide(uint32_t scale); 141 constant()142 int32_t constant() const { return constant_; } numTerms()143 size_t numTerms() const { return terms_.length(); } term(size_t i)144 LinearTerm term(size_t i) const { return terms_[i]; } replaceTerm(size_t i,MDefinition * def)145 void replaceTerm(size_t i, MDefinition* def) { terms_[i].term = def; } 146 147 void dump(GenericPrinter& out) const; 148 void dump() const; 149 150 private: 151 Vector<LinearTerm, 2, JitAllocPolicy> terms_; 152 int32_t constant_; 153 }; 154 155 // Convert all components of a linear sum (except, optionally, the constant) 156 // and add any new instructions to the end of block. 157 MDefinition* ConvertLinearSum(TempAllocator& alloc, MBasicBlock* block, 158 const LinearSum& sum, 159 bool convertConstant = false); 160 161 // Convert the test 'sum >= 0' to a comparison, adding any necessary 162 // instructions to the end of block. 163 MCompare* ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, 164 const LinearSum& sum); 165 166 MOZ_MUST_USE bool AnalyzeNewScriptDefiniteProperties( 167 JSContext* cx, DPAConstraintInfo& constraintInfo, HandleFunction fun, 168 ObjectGroup* group, Handle<PlainObject*> baseobj, 169 Vector<TypeNewScriptInitializer>* initializerList); 170 171 MOZ_MUST_USE bool AnalyzeArgumentsUsage(JSContext* cx, JSScript* script); 172 173 bool DeadIfUnused(const MDefinition* def); 174 175 bool IsDiscardable(const MDefinition* def); 176 177 class CompileInfo; 178 void DumpMIRExpressions(MIRGraph& graph, const CompileInfo& info, 179 const char* phase); 180 181 } // namespace jit 182 } // namespace js 183 184 #endif /* jit_IonAnalysis_h */ 185