Line data Source code
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 : #include "jit/AliasAnalysisShared.h"
8 :
9 : #include "jit/MIR.h"
10 :
11 : namespace js {
12 : namespace jit {
13 :
14 : void
15 10 : AliasAnalysisShared::spewDependencyList()
16 : {
17 : #ifdef JS_JITSPEW
18 10 : if (JitSpewEnabled(JitSpew_AliasSummaries)) {
19 0 : Fprinter &print = JitSpewPrinter();
20 0 : JitSpewHeader(JitSpew_AliasSummaries);
21 0 : print.printf("Dependency list for other passes:\n");
22 :
23 0 : for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
24 0 : for (MInstructionIterator def(block->begin()), end(block->begin(block->lastIns()));
25 : def != end;
26 : ++def)
27 : {
28 0 : if (!def->dependency())
29 0 : continue;
30 0 : if (!def->getAliasSet().isLoad())
31 0 : continue;
32 :
33 0 : JitSpewHeader(JitSpew_AliasSummaries);
34 0 : print.printf(" ");
35 0 : MDefinition::PrintOpcodeName(print, def->op());
36 0 : print.printf("%d marked depending on ", def->id());
37 0 : MDefinition::PrintOpcodeName(print, def->dependency()->op());
38 0 : print.printf("%d\n", def->dependency()->id());
39 : }
40 : }
41 : }
42 : #endif
43 10 : }
44 :
45 : // Unwrap any slot or element to its corresponding object.
46 : static inline const MDefinition*
47 571 : MaybeUnwrap(const MDefinition* object)
48 : {
49 :
50 613 : while (object->isSlots() || object->isElements() || object->isConvertElementsToDoubles()) {
51 42 : MOZ_ASSERT(object->numOperands() == 1);
52 42 : object = object->getOperand(0);
53 : }
54 :
55 529 : if (object->isTypedArrayElements())
56 0 : return nullptr;
57 529 : if (object->isTypedObjectElements())
58 0 : return nullptr;
59 529 : if (object->isConstantElements())
60 0 : return nullptr;
61 :
62 529 : return object;
63 : }
64 :
65 : // Get the object of any load/store. Returns nullptr if not tied to
66 : // an object.
67 : static inline const MDefinition*
68 826 : GetObject(const MDefinition* ins)
69 : {
70 826 : if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
71 0 : return nullptr;
72 :
73 : // Note: only return the object if that objects owns that property.
74 : // I.e. the poperty isn't on the prototype chain.
75 826 : const MDefinition* object = nullptr;
76 826 : switch (ins->op()) {
77 : case MDefinition::Op_InitializedLength:
78 : case MDefinition::Op_LoadElement:
79 : case MDefinition::Op_LoadUnboxedScalar:
80 : case MDefinition::Op_LoadUnboxedObjectOrNull:
81 : case MDefinition::Op_LoadUnboxedString:
82 : case MDefinition::Op_StoreElement:
83 : case MDefinition::Op_StoreUnboxedObjectOrNull:
84 : case MDefinition::Op_StoreUnboxedString:
85 : case MDefinition::Op_StoreUnboxedScalar:
86 : case MDefinition::Op_SetInitializedLength:
87 : case MDefinition::Op_ArrayLength:
88 : case MDefinition::Op_SetArrayLength:
89 : case MDefinition::Op_StoreElementHole:
90 : case MDefinition::Op_FallibleStoreElement:
91 : case MDefinition::Op_TypedObjectDescr:
92 : case MDefinition::Op_Slots:
93 : case MDefinition::Op_Elements:
94 : case MDefinition::Op_MaybeCopyElementsForWrite:
95 : case MDefinition::Op_MaybeToDoubleElement:
96 : case MDefinition::Op_UnboxedArrayLength:
97 : case MDefinition::Op_UnboxedArrayInitializedLength:
98 : case MDefinition::Op_IncrementUnboxedArrayInitializedLength:
99 : case MDefinition::Op_SetUnboxedArrayInitializedLength:
100 : case MDefinition::Op_TypedArrayLength:
101 : case MDefinition::Op_SetTypedObjectOffset:
102 : case MDefinition::Op_SetDisjointTypedElements:
103 : case MDefinition::Op_ArrayPopShift:
104 : case MDefinition::Op_ArrayPush:
105 : case MDefinition::Op_ArraySlice:
106 : case MDefinition::Op_LoadTypedArrayElementHole:
107 : case MDefinition::Op_StoreTypedArrayElementHole:
108 : case MDefinition::Op_LoadFixedSlot:
109 : case MDefinition::Op_LoadFixedSlotAndUnbox:
110 : case MDefinition::Op_StoreFixedSlot:
111 : case MDefinition::Op_GetPropertyPolymorphic:
112 : case MDefinition::Op_SetPropertyPolymorphic:
113 : case MDefinition::Op_GuardShape:
114 : case MDefinition::Op_GuardReceiverPolymorphic:
115 : case MDefinition::Op_GuardObjectGroup:
116 : case MDefinition::Op_GuardObjectIdentity:
117 : case MDefinition::Op_GuardClass:
118 : case MDefinition::Op_GuardUnboxedExpando:
119 : case MDefinition::Op_LoadUnboxedExpando:
120 : case MDefinition::Op_LoadSlot:
121 : case MDefinition::Op_StoreSlot:
122 : case MDefinition::Op_InArray:
123 : case MDefinition::Op_LoadElementHole:
124 : case MDefinition::Op_TypedArrayElements:
125 : case MDefinition::Op_TypedObjectElements:
126 : case MDefinition::Op_CopyLexicalEnvironmentObject:
127 529 : object = ins->getOperand(0);
128 529 : break;
129 : case MDefinition::Op_GetPropertyCache:
130 : case MDefinition::Op_LoadTypedArrayElementStatic:
131 : case MDefinition::Op_StoreTypedArrayElementStatic:
132 : case MDefinition::Op_GetDOMProperty:
133 : case MDefinition::Op_GetDOMMember:
134 : case MDefinition::Op_Call:
135 : case MDefinition::Op_Compare:
136 : case MDefinition::Op_GetArgumentsObjectArg:
137 : case MDefinition::Op_SetArgumentsObjectArg:
138 : case MDefinition::Op_GetFrameArgument:
139 : case MDefinition::Op_SetFrameArgument:
140 : case MDefinition::Op_CompareExchangeTypedArrayElement:
141 : case MDefinition::Op_AtomicExchangeTypedArrayElement:
142 : case MDefinition::Op_AtomicTypedArrayElementBinop:
143 : case MDefinition::Op_AsmJSLoadHeap:
144 : case MDefinition::Op_AsmJSStoreHeap:
145 : case MDefinition::Op_WasmLoadTls:
146 : case MDefinition::Op_WasmLoad:
147 : case MDefinition::Op_WasmStore:
148 : case MDefinition::Op_AsmJSCompareExchangeHeap:
149 : case MDefinition::Op_AsmJSAtomicBinopHeap:
150 : case MDefinition::Op_WasmLoadGlobalVar:
151 : case MDefinition::Op_WasmStoreGlobalVar:
152 : case MDefinition::Op_ArrayJoin:
153 158 : return nullptr;
154 : default:
155 : #ifdef DEBUG
156 : // Crash when the default aliasSet is overriden, but when not added in the list above.
157 139 : if (!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any)
158 0 : MOZ_CRASH("Overridden getAliasSet without updating AliasAnalysisShared GetObject");
159 : #endif
160 :
161 139 : return nullptr;
162 : }
163 :
164 529 : MOZ_ASSERT(!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any);
165 529 : object = MaybeUnwrap(object);
166 529 : MOZ_ASSERT_IF(object, object->type() == MIRType::Object);
167 529 : return object;
168 : }
169 :
170 : // Generic comparing if a load aliases a store using TI information.
171 : MDefinition::AliasType
172 413 : AliasAnalysisShared::genericMightAlias(const MDefinition* load, const MDefinition* store)
173 : {
174 413 : const MDefinition* loadObject = GetObject(load);
175 413 : const MDefinition* storeObject = GetObject(store);
176 413 : if (!loadObject || !storeObject)
177 288 : return MDefinition::AliasType::MayAlias;
178 :
179 125 : if (!loadObject->resultTypeSet() || !storeObject->resultTypeSet())
180 119 : return MDefinition::AliasType::MayAlias;
181 :
182 6 : if (loadObject->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet()))
183 2 : return MDefinition::AliasType::MayAlias;
184 :
185 4 : return MDefinition::AliasType::NoAlias;
186 : }
187 :
188 :
189 : } // namespace jit
190 : } // namespace js
|