js/src/jit/ValueNumbering.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:41bce5b43e40
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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_ValueNumbering_h
8 #define jit_ValueNumbering_h
9
10 #include "jit/MIR.h"
11
12 namespace js {
13 namespace jit {
14
15 class ValueNumberer
16 {
17 protected:
18 struct ValueHasher
19 {
20 typedef MDefinition * Lookup;
21 typedef MDefinition * Key;
22 static HashNumber hash(const Lookup &ins) {
23 return ins->valueHash();
24 }
25
26 static bool match(const Key &k, const Lookup &l) {
27 // If one of the instructions depends on a store, and the
28 // other instruction does not depend on the same store,
29 // the instructions are not congruent.
30 if (k->dependency() != l->dependency())
31 return false;
32 return k->congruentTo(l);
33 }
34 };
35
36 typedef HashMap<MDefinition *,
37 uint32_t,
38 ValueHasher,
39 IonAllocPolicy> ValueMap;
40
41 struct DominatingValue
42 {
43 MDefinition *def;
44 uint32_t validUntil;
45 };
46
47 typedef HashMap<uint32_t,
48 DominatingValue,
49 DefaultHasher<uint32_t>,
50 IonAllocPolicy> InstructionMap;
51
52 protected:
53 TempAllocator &alloc() const;
54 uint32_t lookupValue(MDefinition *ins);
55 MDefinition *findDominatingDef(InstructionMap &defs, MDefinition *ins, size_t index);
56
57 MDefinition *simplify(MDefinition *def, bool useValueNumbers);
58 MControlInstruction *simplifyControlInstruction(MControlInstruction *def);
59 bool eliminateRedundancies();
60
61 bool computeValueNumbers();
62
63 inline bool isMarked(MDefinition *def) {
64 return pessimisticPass_ || def->isInWorklist();
65 }
66
67 void markDefinition(MDefinition *def);
68 void unmarkDefinition(MDefinition *def);
69
70 void markConsumers(MDefinition *def);
71 void markBlock(MBasicBlock *block);
72 void setClass(MDefinition *toSet, MDefinition *representative);
73
74 public:
75 static MDefinition *findSplit(MDefinition *);
76 void breakClass(MDefinition*);
77
78 protected:
79 MIRGenerator *mir;
80 MIRGraph &graph_;
81 ValueMap values;
82 bool pessimisticPass_;
83 size_t count_;
84
85 public:
86 ValueNumberer(MIRGenerator *mir, MIRGraph &graph, bool optimistic);
87 bool analyze();
88 bool clear();
89 };
90
91 class ValueNumberData : public TempObject {
92
93 friend void ValueNumberer::breakClass(MDefinition*);
94 friend MDefinition *ValueNumberer::findSplit(MDefinition*);
95 uint32_t number;
96 MDefinition *classNext;
97 MDefinition *classPrev;
98
99 public:
100 ValueNumberData() : number(0), classNext(nullptr), classPrev(nullptr) {}
101
102 void setValueNumber(uint32_t number_) {
103 number = number_;
104 }
105
106 uint32_t valueNumber() {
107 return number;
108 }
109 // Set the class of this to the given representative value.
110 void setClass(MDefinition *thisDef, MDefinition *rep) {
111 JS_ASSERT(thisDef->valueNumberData() == this);
112 // If we are attempting to insert ourself, then nothing needs to be done.
113 // However, if the definition to be inserted already has the correct value number,
114 // it still needs to be inserted, since the value number needs to be updated lazily.
115 // this updating tactic can leave the world in a state where thisDef is not in the
116 // equivalence class of rep, but it has the same value number. Defs in this state
117 // need to be re-processed.
118 if (this == rep->valueNumberData())
119 return;
120
121 if (classNext)
122 classNext->valueNumberData()->classPrev = classPrev;
123 if (classPrev)
124 classPrev->valueNumberData()->classNext = classNext;
125
126
127 classPrev = rep;
128 classNext = rep->valueNumberData()->classNext;
129
130 if (rep->valueNumberData()->classNext)
131 rep->valueNumberData()->classNext->valueNumberData()->classPrev = thisDef;
132 rep->valueNumberData()->classNext = thisDef;
133 }
134 };
135 } // namespace jit
136 } // namespace js
137
138 #endif /* jit_ValueNumbering_h */

mercurial