tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

IonAnalysis.h (8111B)


      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 <stddef.h>
     13 #include <stdint.h>
     14 
     15 #include "jit/IonTypes.h"
     16 #include "jit/JitAllocPolicy.h"
     17 #include "js/TypeDecls.h"
     18 #include "js/Utility.h"
     19 #include "js/Vector.h"
     20 
     21 namespace js {
     22 
     23 class JS_PUBLIC_API GenericPrinter;
     24 class PlainObject;
     25 
     26 namespace jit {
     27 
     28 class MBasicBlock;
     29 class MCompare;
     30 class MDefinition;
     31 class MIRGenerator;
     32 class MIRGraph;
     33 class MTest;
     34 
     35 [[nodiscard]] bool PruneUnusedBranches(const MIRGenerator* mir,
     36                                       MIRGraph& graph);
     37 
     38 [[nodiscard]] bool FoldTests(MIRGraph& graph);
     39 
     40 [[nodiscard]] bool FoldEmptyBlocks(MIRGraph& graph, bool* changed);
     41 
     42 [[nodiscard]] bool SplitCriticalEdges(MIRGraph& graph);
     43 
     44 [[nodiscard]] bool OptimizeIteratorIndices(const MIRGenerator* mir,
     45                                           MIRGraph& graph);
     46 
     47 bool IsUint32Type(const MDefinition* def);
     48 
     49 enum Observability { ConservativeObservability, AggressiveObservability };
     50 
     51 [[nodiscard]] bool EliminatePhis(const MIRGenerator* mir, MIRGraph& graph,
     52                                 Observability observe);
     53 
     54 size_t MarkLoopBlocks(MIRGraph& graph, const MBasicBlock* header, bool* canOsr);
     55 
     56 void UnmarkLoopBlocks(MIRGraph& graph, const MBasicBlock* header);
     57 
     58 [[nodiscard]] bool MakeLoopsContiguous(MIRGraph& graph);
     59 
     60 [[nodiscard]] bool EliminateTriviallyDeadResumePointOperands(
     61    const MIRGenerator* mir, MIRGraph& graph);
     62 
     63 [[nodiscard]] bool EliminateDeadResumePointOperands(const MIRGenerator* mir,
     64                                                    MIRGraph& graph);
     65 
     66 [[nodiscard]] bool EliminateDeadCode(const MIRGenerator* mir, MIRGraph& graph);
     67 
     68 [[nodiscard]] bool FoldLoadsWithUnbox(const MIRGenerator* mir, MIRGraph& graph);
     69 
     70 [[nodiscard]] bool ApplyTypeInformation(const MIRGenerator* mir,
     71                                        MIRGraph& graph);
     72 
     73 void RenumberBlocks(MIRGraph& graph);
     74 
     75 [[nodiscard]] bool AccountForCFGChanges(const MIRGenerator* mir,
     76                                        MIRGraph& graph,
     77                                        bool updateAliasAnalysis,
     78                                        bool underValueNumberer = false);
     79 
     80 [[nodiscard]] bool RemoveUnmarkedBlocks(const MIRGenerator* mir,
     81                                        MIRGraph& graph,
     82                                        uint32_t numMarkedBlocks);
     83 
     84 [[nodiscard]] bool BuildPhiReverseMapping(MIRGraph& graph);
     85 
     86 void AssertBasicGraphCoherency(MIRGraph& graph, bool force = false);
     87 
     88 void AssertGraphCoherency(MIRGraph& graph, bool force = false);
     89 
     90 void AssertExtendedGraphCoherency(MIRGraph& graph,
     91                                  bool underValueNumberer = false,
     92                                  bool force = false);
     93 
     94 [[nodiscard]] bool EliminateRedundantChecks(MIRGraph& graph);
     95 
     96 [[nodiscard]] bool EliminateRedundantShapeGuards(MIRGraph& graph);
     97 
     98 [[nodiscard]] bool EliminateRedundantGCBarriers(MIRGraph& graph);
     99 
    100 [[nodiscard]] bool AddKeepAliveInstructions(MIRGraph& graph);
    101 
    102 [[nodiscard]] bool MarkLoadsUsedAsPropertyKeys(MIRGraph& graph);
    103 
    104 [[nodiscard]] bool TrackWasmRefTypes(MIRGraph& graph);
    105 
    106 // Simple linear sum of the form 'n' or 'x + n'.
    107 struct SimpleLinearSum {
    108  MDefinition* term;
    109  int32_t constant;
    110 
    111  SimpleLinearSum(MDefinition* term, int32_t constant)
    112      : term(term), constant(constant) {}
    113 };
    114 
    115 // Math done in a Linear sum can either be in a modulo space, in which case
    116 // overflow are wrapped around, or they can be computed in the integer-space in
    117 // which case we have to check that no overflow can happen when summing
    118 // constants.
    119 //
    120 // When the caller ignores which space it is, the definition would be used to
    121 // deduce it.
    122 enum class MathSpace { Modulo, Infinite, Unknown };
    123 
    124 SimpleLinearSum ExtractLinearSum(MDefinition* ins,
    125                                 MathSpace space = MathSpace::Unknown,
    126                                 int32_t recursionDepth = 0);
    127 
    128 [[nodiscard]] bool ExtractLinearInequality(const MTest* test,
    129                                           BranchDirection direction,
    130                                           SimpleLinearSum* plhs,
    131                                           MDefinition** prhs,
    132                                           bool* plessEqual);
    133 
    134 struct LinearTerm {
    135  MDefinition* term;
    136  int32_t scale;
    137 
    138  LinearTerm(MDefinition* term, int32_t scale) : term(term), scale(scale) {}
    139 };
    140 
    141 // General linear sum of the form 'x1*n1 + x2*n2 + ... + n'
    142 class LinearSum {
    143 public:
    144  explicit LinearSum(TempAllocator& alloc) : terms_(alloc), constant_(0) {}
    145 
    146  LinearSum(const LinearSum& other)
    147      : terms_(other.terms_.allocPolicy()), constant_(other.constant_) {
    148    AutoEnterOOMUnsafeRegion oomUnsafe;
    149    if (!terms_.appendAll(other.terms_)) {
    150      oomUnsafe.crash("LinearSum::LinearSum");
    151    }
    152  }
    153 
    154  // These return false on an integer overflow, and afterwards the sum must
    155  // not be used.
    156  [[nodiscard]] bool multiply(int32_t scale);
    157  [[nodiscard]] bool add(const LinearSum& other, int32_t scale = 1);
    158  [[nodiscard]] bool add(SimpleLinearSum other, int32_t scale = 1);
    159  [[nodiscard]] bool add(MDefinition* term, int32_t scale);
    160  [[nodiscard]] bool add(int32_t constant);
    161 
    162  // Unlike the above function, on failure this leaves the sum unchanged and
    163  // it can still be used.
    164  [[nodiscard]] bool divide(uint32_t scale);
    165 
    166  int32_t constant() const { return constant_; }
    167  size_t numTerms() const { return terms_.length(); }
    168  LinearTerm term(size_t i) const { return terms_[i]; }
    169  void replaceTerm(size_t i, MDefinition* def) { terms_[i].term = def; }
    170 
    171  void dump(GenericPrinter& out) const;
    172  void dump() const;
    173 
    174 private:
    175  Vector<LinearTerm, 2, JitAllocPolicy> terms_;
    176  int32_t constant_;
    177 };
    178 
    179 // Convert all components of a linear sum (except the constant)
    180 // and add any new instructions to the end of block.
    181 MDefinition* ConvertLinearSum(TempAllocator& alloc, MBasicBlock* block,
    182                              const LinearSum& sum, BailoutKind bailoutKind);
    183 
    184 bool DeadIfUnused(const MDefinition* def);
    185 bool DeadIfUnusedAllowEffectful(const MDefinition* def);
    186 
    187 bool IsDiscardable(const MDefinition* def);
    188 bool IsDiscardableAllowEffectful(const MDefinition* def);
    189 
    190 class CompileInfo;
    191 
    192 // Debug printing.  When `showDetails` is `true`, extra details are shown.
    193 // Also, in that case, these routines will show an integer base-26 hashed
    194 // version of pointers.  This helps avoid ambiguities resulting from use of IDs
    195 // for MBasicBlocks and MDefinitions.  Be aware the hashed pointers are not
    196 // guaranteed to be unique, although collisions are very unlikely.
    197 
    198 // Dump `p`, hashed, to `out`.
    199 void DumpHashedPointer(GenericPrinter& out, const void* p);
    200 
    201 // Dump the ID and possibly the pointer hash of `def`, to `out`.
    202 void DumpMIRDefinitionID(GenericPrinter& out, const MDefinition* def,
    203                         bool showDetails = false);
    204 // Dump an MDefinition to `out`.
    205 void DumpMIRDefinition(GenericPrinter& out, const MDefinition* def,
    206                       bool showDetails = false);
    207 
    208 // Dump the ID and possibly the pointer hash of `block`, to `out`.
    209 void DumpMIRBlockID(GenericPrinter& out, const MBasicBlock* block,
    210                    bool showDetails = false);
    211 // Dump an MBasicBlock to `out`.
    212 void DumpMIRBlock(GenericPrinter& out, MBasicBlock* block,
    213                  bool showDetails = false);
    214 
    215 // Dump an entire MIRGraph to `out`.
    216 void DumpMIRGraph(GenericPrinter& out, MIRGraph& graph,
    217                  bool showDetails = false);
    218 
    219 // Legacy entry point for DumpMIRGraph.
    220 void DumpMIRExpressions(GenericPrinter& out, MIRGraph& graph,
    221                        const CompileInfo& info, const char* phase,
    222                        bool showDetails = false);
    223 }  // namespace jit
    224 }  // namespace js
    225 
    226 #endif /* jit_IonAnalysis_h */