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/. */
7 #ifndef jit_ValueNumbering_h
8 #define jit_ValueNumbering_h
10 #include "jit/JitAllocPolicy.h"
11 #include "js/HashTable.h"
12 #include "js/Vector.h"
25 // Value numbering data.
27 // Hash policy for ValueSet.
29 using Lookup
= const MDefinition
*;
30 using Key
= MDefinition
*;
31 static HashNumber
hash(Lookup ins
);
32 static bool match(Key k
, Lookup l
);
33 static void rekey(Key
& k
, Key newKey
);
36 typedef HashSet
<MDefinition
*, ValueHasher
, JitAllocPolicy
> ValueSet
;
38 ValueSet set_
; // Set of visible values
41 explicit VisibleValues(TempAllocator
& alloc
);
43 using Ptr
= ValueSet::Ptr
;
44 using AddPtr
= ValueSet::AddPtr
;
46 Ptr
findLeader(const MDefinition
* def
) const;
47 AddPtr
findLeaderForAdd(MDefinition
* def
);
48 [[nodiscard
]] bool add(AddPtr p
, MDefinition
* def
);
49 void overwrite(AddPtr p
, MDefinition
* def
);
50 void forget(const MDefinition
* def
);
53 bool has(const MDefinition
* def
) const;
57 typedef Vector
<MBasicBlock
*, 4, JitAllocPolicy
> BlockWorklist
;
58 typedef Vector
<MDefinition
*, 4, JitAllocPolicy
> DefWorklist
;
60 MIRGenerator
* const mir_
;
62 VisibleValues values_
; // Numbered values
63 DefWorklist deadDefs_
; // Worklist for deleting values
64 BlockWorklist remainingBlocks_
; // Blocks remaining with fewer preds
65 MDefinition
* nextDef_
; // The next definition; don't discard
66 size_t totalNumVisited_
; // The number of blocks visited
67 bool rerun_
; // Should we run another GVN iteration?
68 bool blocksRemoved_
; // Have any blocks been removed?
69 bool updateAliasAnalysis_
; // Do we care about AliasAnalysis?
70 bool dependenciesBroken_
; // Have we broken AliasAnalysis?
71 bool hasOSRFixups_
; // Have we created any OSR fixup blocks?
73 enum ImplicitUseOption
{ DontSetImplicitUse
, SetImplicitUse
};
74 enum class AllowEffectful
: bool { No
, Yes
};
76 [[nodiscard
]] bool handleUseReleased(MDefinition
* def
,
77 ImplicitUseOption implicitUseOption
);
78 [[nodiscard
]] bool discardDefsRecursively(
79 MDefinition
* def
, AllowEffectful allowEffectful
= AllowEffectful::No
);
80 [[nodiscard
]] bool releaseResumePointOperands(MResumePoint
* resume
);
81 [[nodiscard
]] bool releaseAndRemovePhiOperands(MPhi
* phi
);
82 [[nodiscard
]] bool releaseOperands(MDefinition
* def
);
83 [[nodiscard
]] bool discardDef(
84 MDefinition
* def
, AllowEffectful allowEffectful
= AllowEffectful::No
);
85 [[nodiscard
]] bool processDeadDefs();
87 [[nodiscard
]] bool fixupOSROnlyLoop(MBasicBlock
* block
);
88 [[nodiscard
]] bool removePredecessorAndDoDCE(MBasicBlock
* block
,
91 [[nodiscard
]] bool removePredecessorAndCleanUp(MBasicBlock
* block
,
94 MDefinition
* simplified(MDefinition
* def
) const;
95 MDefinition
* leader(MDefinition
* def
);
96 bool hasLeader(const MPhi
* phi
, const MBasicBlock
* phiBlock
) const;
97 bool loopHasOptimizablePhi(MBasicBlock
* header
) const;
99 [[nodiscard
]] bool visitDefinition(MDefinition
* def
);
100 [[nodiscard
]] bool visitControlInstruction(MBasicBlock
* block
);
101 [[nodiscard
]] bool visitUnreachableBlock(MBasicBlock
* block
);
102 [[nodiscard
]] bool visitBlock(MBasicBlock
* block
);
103 [[nodiscard
]] bool visitDominatorTree(MBasicBlock
* root
);
104 [[nodiscard
]] bool visitGraph();
106 [[nodiscard
]] bool insertOSRFixups();
107 [[nodiscard
]] bool cleanupOSRFixups();
110 ValueNumberer(MIRGenerator
* mir
, MIRGraph
& graph
);
112 enum UpdateAliasAnalysisFlag
{ DontUpdateAliasAnalysis
, UpdateAliasAnalysis
};
114 // Optimize the graph, performing expression simplification and
115 // canonicalization, eliminating statically fully-redundant expressions,
116 // deleting dead instructions, and removing unreachable blocks.
117 [[nodiscard
]] bool run(UpdateAliasAnalysisFlag updateAliasAnalysis
);
123 #endif /* jit_ValueNumbering_h */