Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/optimizer/FearPointAnalysis.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
#include <stddef.h>
23
#include <stdint.h>
24
#include "optimizer/FearPointAnalysis.hpp"
25
#include "env/StackMemoryRegion.hpp"
26
#include "codegen/CodeGenerator.hpp"
27
#include "compile/Compilation.hpp"
28
#include "control/Options.hpp"
29
#include "control/Options_inlines.hpp"
30
#include "env/TRMemory.hpp"
31
#include "il/Node.hpp"
32
#include "il/Node_inlines.hpp"
33
#include "infra/Assert.hpp"
34
#include "infra/BitVector.hpp"
35
#include "infra/Checklist.hpp"
36
37
bool TR_FearPointAnalysis::virtualGuardsKillFear()
38
{
39
static bool kill = (feGetEnv("TR_FPAnalaysisGuardsDoNotKillFear") == NULL);
40
return kill;
41
}
42
43
int32_t TR_FearPointAnalysis::getNumberOfBits() { return 1; }
44
45
bool TR_FearPointAnalysis::supportsGenAndKillSets() { return true; }
46
47
TR_DataFlowAnalysis::Kind TR_FearPointAnalysis::getKind() { return FearPointAnalysis; }
48
49
TR_FearPointAnalysis *TR_FearPointAnalysis::asFearPointAnalysis() { return this; }
50
51
void TR_FearPointAnalysis::analyzeNode(TR::Node *node, vcount_t visitCount, TR_BlockStructure *block, TR_SingleBitContainer *bv)
52
{
53
}
54
55
void TR_FearPointAnalysis::analyzeTreeTopsInBlockStructure(TR_BlockStructure *block)
56
{
57
}
58
59
/**
60
* Conduct fear analysis for an set of fear generating nodes, provided
61
* as a bit vector of their global indices.
62
*
63
* The default behaviour will initially search trees for children nodes generating
64
* fear and then propagate this upwards. When topLevelFearOnly is enabled, this phase
65
* is skipped and it is assumed that the set of fear generating nodes are all treetop nodes.
66
*/
67
TR_FearPointAnalysis::TR_FearPointAnalysis(
68
TR::Compilation *comp,
69
TR::Optimizer *optimizer,
70
TR_Structure *rootStructure,
71
TR_BitVector &fearGeneratingNodes,
72
bool topLevelFearOnly,
73
bool trace) :
74
TR_BackwardUnionSingleBitContainerAnalysis(comp, comp->getFlowGraph(), optimizer, trace),
75
_fearGeneratingNodes(fearGeneratingNodes),
76
_EMPTY(comp->getNodeCount(), trMemory(), stackAlloc),
77
_topLevelFearOnly(topLevelFearOnly),
78
_trace(trace)
79
{
80
81
if (comp->getVisitCount() > 8000)
82
comp->resetVisitCounts(1);
83
84
85
// Allocate the map from node to BitVector of fear generating nodes that reach it
86
// Must be before the stack mark since it will be used by the caller
87
//
88
_fearfulNodes = (TR_SingleBitContainer**) trMemory()->allocateStackMemory(comp->getNodeCount() * sizeof(TR_SingleBitContainer *));
89
TR::NodeChecklist checklist(comp);
90
for (TR::TreeTop *treeTop = comp->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())
91
{
92
if (treeTop->getNode()->getOpCodeValue() == TR::BBStart)
93
{
94
TR::Block *currentBlock = treeTop->getEnclosingBlock();
95
if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())
96
{
97
treeTop = currentBlock->getExit();
98
continue;
99
}
100
}
101
102
computeFear(comp, treeTop->getNode(), checklist);
103
}
104
105
// Only nodes in fearGeneratingNodes will have fear initially, so it is cheaper to
106
// apply these directly
107
//
108
if (_topLevelFearOnly)
109
computeFearFromBitVector(comp);
110
111
112
// Allocate the block info before setting the stack mark - it will be used by
113
// the caller
114
//
115
initializeBlockInfo();
116
117
{
118
TR::StackMemoryRegion stackMemoryRegion(*trMemory());
119
performAnalysis(rootStructure, false);
120
}
121
122
}
123
124
void TR_FearPointAnalysis::computeFear(TR::Compilation *comp, TR::Node *node, TR::NodeChecklist &checklist)
125
{
126
if (checklist.contains(node))
127
return;
128
checklist.add(node);
129
_fearfulNodes[node->getGlobalIndex()] = new (trStackMemory()) TR_SingleBitContainer(comp->getNodeCount(), trMemory(), stackAlloc);
130
131
// If only the treetops are of concern then its safe to use the
132
// cheaper BitVector method to compute initial fear
133
//
134
if (_topLevelFearOnly)
135
return;
136
137
for (int i = 0; i < node->getNumChildren(); ++i)
138
{
139
computeFear(comp, node->getChild(i), checklist);
140
*(_fearfulNodes[node->getGlobalIndex()]) |= *(_fearfulNodes[node->getChild(i)->getGlobalIndex()]);
141
}
142
143
if (_fearGeneratingNodes.get(node->getGlobalIndex()))
144
{
145
if (_trace)
146
traceMsg(comp, "@@ n%dn generates fear\n", node->getGlobalIndex());
147
_fearfulNodes[node->getGlobalIndex()]->set();
148
}
149
}
150
151
#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)
152
bool TR_FearPointAnalysis::confirmFearFromBitVector(TR::Node *node)
153
{
154
if (_fearGeneratingNodes.get(node->getGlobalIndex()))
155
return true;
156
157
for (int i = 0; i < node->getNumChildren(); ++i)
158
if (confirmFearFromBitVector(node->getChild(i)))
159
return true;
160
161
return false;
162
}
163
#endif
164
165
void TR_FearPointAnalysis::computeFearFromBitVector(TR::Compilation *comp)
166
{
167
TR_BitVectorIterator nodes(_fearGeneratingNodes);
168
while (nodes.hasMoreElements())
169
{
170
int32_t index = nodes.getNextElement();
171
if (_trace)
172
traceMsg(comp, "@@ n%dn generates fear\n", index);
173
TR_ASSERT(_fearfulNodes[index],
174
"all fear generating nodes must be treetop nodes when using topLevelFearOnly, otherwise the data structure may not be initialized");
175
_fearfulNodes[index]->set();
176
}
177
178
#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)
179
// Do a complete pass to confirm the cheaper approach was used correctly
180
TR::NodeChecklist checklist(comp);
181
for (TR::TreeTop *treeTop = comp->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())
182
{
183
if (treeTop->getNode()->getOpCodeValue() == TR::BBStart)
184
{
185
TR::Block *currentBlock = treeTop->getEnclosingBlock();
186
if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())
187
{
188
treeTop = currentBlock->getExit();
189
continue;
190
}
191
}
192
193
bool fearful = confirmFearFromBitVector(treeTop->getNode());
194
TR_ASSERT(_fearfulNodes[treeTop->getNode()->getGlobalIndex()]->get() == fearful,
195
"all fear generating nodes must be treetop nodes when using topLevelFearOnly, otherwise the initial fear may be incorrect");
196
}
197
#endif
198
}
199
200
TR_SingleBitContainer *TR_FearPointAnalysis::generatedFear(TR::Node *node)
201
{
202
TR_SingleBitContainer *returnValue = _fearfulNodes[node->getGlobalIndex()];
203
if (!returnValue)
204
return &_EMPTY;
205
return returnValue;
206
}
207
208
void TR_FearPointAnalysis::initializeGenAndKillSetInfo()
209
{
210
for (int32_t i = 0; i < comp()->getFlowGraph()->getNextNodeNumber(); ++i)
211
{
212
_regularGenSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);
213
_exceptionGenSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);
214
_regularKillSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);
215
_exceptionKillSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);
216
}
217
218
TR::Block *currentBlock = NULL;
219
bool exceptingTTSeen = false;
220
for (TR::TreeTop *treeTop = comp()->findLastTree(); treeTop; treeTop = treeTop->getPrevTreeTop())
221
{
222
if (treeTop->getNode()->getOpCodeValue() == TR::BBEnd)
223
{
224
exceptingTTSeen = false;
225
currentBlock = treeTop->getEnclosingBlock();
226
if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())
227
{
228
_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
229
_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
230
treeTop = currentBlock->getEntry();
231
}
232
continue;
233
}
234
235
if (treeTop->getNode()->getOpCode().canRaiseException())
236
{
237
exceptingTTSeen = true;
238
_exceptionKillSetInfo[currentBlock->getNumber()]->empty();
239
}
240
241
if (comp()->isPotentialOSRPointWithSupport(treeTop))
242
{
243
_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
244
_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
245
_regularGenSetInfo[currentBlock->getNumber()]->empty();
246
}
247
248
// kill any fear originating from inside
249
if (virtualGuardsKillFear()
250
&& treeTop->getNode()->isTheVirtualGuardForAGuardedInlinedCall()
251
&& comp()->cg()->supportsMergingGuards())
252
{
253
_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
254
_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());
255
//*(_regularKillSetInfo[currentBlock->getNumber()]) |= *(_inlinedCalleeMasks[treeTop->getNode()->getByteCodeInfo().getCallerIndex()]);
256
//*(_exceptionKillSetInfo[currentBlock->getNumber()]) |= *(_inlinedCalleeMasks[treeTop->getNode()->getByteCodeInfo().getCallerIndex()]);
257
}
258
259
TR_SingleBitContainer *fear = generatedFear(treeTop->getNode());
260
*(_regularGenSetInfo[currentBlock->getNumber()] ) |= *fear;
261
if (exceptingTTSeen)
262
*(_exceptionGenSetInfo[currentBlock->getNumber()]) |= *fear;
263
}
264
}
265
266
bool TR_FearPointAnalysis::postInitializationProcessing()
267
{
268
return true;
269
}
270
271
272