summaryrefslogtreecommitdiffstats
path: root/js/src/jit/IonAnalysis.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/IonAnalysis.h')
-rw-r--r--js/src/jit/IonAnalysis.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h
new file mode 100644
index 0000000000..cd9b087e3e
--- /dev/null
+++ b/js/src/jit/IonAnalysis.h
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * 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 <stddef.h>
+#include <stdint.h>
+
+#include "jit/IonTypes.h"
+#include "jit/JitAllocPolicy.h"
+#include "js/TypeDecls.h"
+#include "js/Utility.h"
+#include "js/Vector.h"
+
+namespace js {
+
+class JS_PUBLIC_API GenericPrinter;
+class PlainObject;
+
+namespace jit {
+
+class MBasicBlock;
+class MCompare;
+class MDefinition;
+class MIRGenerator;
+class MIRGraph;
+class MTest;
+
+[[nodiscard]] bool PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph);
+
+[[nodiscard]] bool FoldTests(MIRGraph& graph);
+
+[[nodiscard]] bool FoldEmptyBlocks(MIRGraph& graph);
+
+[[nodiscard]] bool SplitCriticalEdges(MIRGraph& graph);
+
+[[nodiscard]] bool OptimizeIteratorIndices(MIRGenerator* mir, MIRGraph& graph);
+
+bool IsUint32Type(const MDefinition* def);
+
+enum Observability { ConservativeObservability, AggressiveObservability };
+
+[[nodiscard]] bool EliminatePhis(MIRGenerator* mir, MIRGraph& graph,
+ Observability observe);
+
+size_t MarkLoopBlocks(MIRGraph& graph, MBasicBlock* header, bool* canOsr);
+
+void UnmarkLoopBlocks(MIRGraph& graph, MBasicBlock* header);
+
+[[nodiscard]] bool MakeLoopsContiguous(MIRGraph& graph);
+
+[[nodiscard]] bool EliminateTriviallyDeadResumePointOperands(MIRGenerator* mir,
+ MIRGraph& graph);
+
+[[nodiscard]] bool EliminateDeadResumePointOperands(MIRGenerator* mir,
+ MIRGraph& graph);
+
+[[nodiscard]] bool EliminateDeadCode(MIRGenerator* mir, MIRGraph& graph);
+
+[[nodiscard]] bool FoldLoadsWithUnbox(MIRGenerator* mir, MIRGraph& graph);
+
+[[nodiscard]] bool ApplyTypeInformation(MIRGenerator* mir, MIRGraph& graph);
+
+void RenumberBlocks(MIRGraph& graph);
+
+[[nodiscard]] bool AccountForCFGChanges(MIRGenerator* mir, MIRGraph& graph,
+ bool updateAliasAnalysis,
+ bool underValueNumberer = false);
+
+[[nodiscard]] bool RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph,
+ uint32_t numMarkedBlocks);
+
+void ClearDominatorTree(MIRGraph& graph);
+
+[[nodiscard]] bool BuildDominatorTree(MIRGraph& graph);
+
+[[nodiscard]] bool BuildPhiReverseMapping(MIRGraph& graph);
+
+void AssertBasicGraphCoherency(MIRGraph& graph, bool force = false);
+
+void AssertGraphCoherency(MIRGraph& graph, bool force = false);
+
+void AssertExtendedGraphCoherency(MIRGraph& graph,
+ bool underValueNumberer = false,
+ bool force = false);
+
+[[nodiscard]] bool EliminateRedundantChecks(MIRGraph& graph);
+
+[[nodiscard]] bool EliminateRedundantShapeGuards(MIRGraph& graph);
+
+[[nodiscard]] bool EliminateRedundantGCBarriers(MIRGraph& graph);
+
+[[nodiscard]] bool AddKeepAliveInstructions(MIRGraph& graph);
+
+// 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,
+ int32_t recursionDepth = 0);
+
+[[nodiscard]] 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.
+ [[nodiscard]] bool multiply(int32_t scale);
+ [[nodiscard]] bool add(const LinearSum& other, int32_t scale = 1);
+ [[nodiscard]] bool add(SimpleLinearSum other, int32_t scale = 1);
+ [[nodiscard]] bool add(MDefinition* term, int32_t scale);
+ [[nodiscard]] bool add(int32_t constant);
+
+ // Unlike the above function, on failure this leaves the sum unchanged and
+ // it can still be used.
+ [[nodiscard]] 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 the constant)
+// and add any new instructions to the end of block.
+MDefinition* ConvertLinearSum(TempAllocator& alloc, MBasicBlock* block,
+ const LinearSum& sum, BailoutKind bailoutKind);
+
+bool DeadIfUnused(const MDefinition* def);
+bool DeadIfUnusedAllowEffectful(const MDefinition* def);
+
+bool IsDiscardable(const MDefinition* def);
+bool IsDiscardableAllowEffectful(const MDefinition* def);
+
+class CompileInfo;
+void DumpMIRExpressions(GenericPrinter& out, MIRGraph& graph,
+ const CompileInfo& info, const char* phase);
+void DumpMIRDefinition(GenericPrinter& out, MDefinition* def);
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_IonAnalysis_h */