Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/optimizer/J9EstimateCodeSize.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 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
23
#ifndef J9ESTIMATECS_INCL
24
#define J9ESTIMATECS_INCL
25
26
#include "il/Block.hpp"
27
#include "ilgen/J9ByteCodeIterator.hpp"
28
#include "compile/Compilation.hpp"
29
#include "optimizer/Inliner.hpp"
30
#include "optimizer/J9Inliner.hpp"
31
#include "il/Node.hpp"
32
#include "infra/Stack.hpp"
33
#include "il/TreeTop.hpp"
34
#include "control/Recompilation.hpp"
35
#include "control/RecompilationInfo.hpp"
36
#include "env/TRMemory.hpp"
37
#include "optimizer/EstimateCodeSize.hpp"
38
39
class TR_ResolvedMethod;
40
class NeedsPeekingHeuristic;
41
42
class TR_J9EstimateCodeSize : public TR_EstimateCodeSize
43
{
44
public:
45
46
TR_J9EstimateCodeSize() : TR_EstimateCodeSize(), _optimisticSize(0), _lastCallBlockFrequency(-1) { }
47
48
int32_t getOptimisticSize() { return _optimisticSize; }
49
50
/** \brief
51
* The inliner weight adjustment factor used for java/lang/String* compression related methods.
52
*/
53
static const float STRING_COMPRESSION_ADJUSTMENT_FACTOR;
54
55
/** \brief
56
* The inliner weight adjustment factor used for `java/lang/reflect/Method.invoke`.
57
*/
58
static const float METHOD_INVOKE_ADJUSTMENT_FACTOR;
59
60
/** \brief
61
* Adjusts the estimated \p value by a \p factor for string compression related methods.
62
* \param method
63
* The method we are trying to make an estimate adjustment for.
64
* \param value
65
* The estimated value we are trying to adjust.
66
* \param factor
67
* The factor multiplier to adjust the value by.
68
* \return
69
* true if the \p value was adjusted by the \p factor for the specific \p method; false otherwise.
70
* \note
71
* If an adjustment is performed the formula used to calculate the new value is:
72
* \code
73
* value *= factor;
74
* \endcode
75
*/
76
static bool adjustEstimateForStringCompression(TR_ResolvedMethod* method, int32_t& value, float factor);
77
78
/** \brief
79
* Adjusts the estimated \p value by a \p factor for `java/lang/reflect/Method.invoke`.
80
* \param method
81
* The method we are trying to make an estimate adjustment for.
82
* \param value
83
* The estimated value we are trying to adjust.
84
* \param factor
85
* The factor multiplier to adjust the value by.
86
* \return
87
* true if the \p value was adjusted by the \p factor for the specific \p method; false otherwise.
88
* \note
89
* If an adjustment is performed the formula used to calculate the new value is:
90
* \code
91
* value *= factor;
92
* \endcode
93
*/
94
static bool adjustEstimateForMethodInvoke(TR_ResolvedMethod* method, int32_t& value, float factor);
95
96
static TR::Block *getBlock(TR::Compilation *comp, TR::Block * * blocks, TR_ResolvedMethod *feMethod, int32_t i, TR::CFG & cfg);
97
98
static void setupNode(TR::Node *node, uint32_t bcIndex, TR_ResolvedMethod *feMethod, TR::Compilation *comp);
99
static void setupLastTreeTop(TR::Block *currentBlock, TR_J9ByteCode bc,
100
uint32_t bcIndex, TR::Block *destinationBlock, TR_ResolvedMethod *feMethod,
101
TR::Compilation *comp);
102
103
protected:
104
bool estimateCodeSize(TR_CallTarget *, TR_CallStack * , bool recurseDown = true);
105
106
/** \brief
107
* Generates a CFG for the calltarget->_calleeMethod.
108
*
109
* \param calltarget
110
* The calltarget which we wish to generate a CFG for.
111
*
112
* \param cfgRegion
113
* The memory region where the cfg is going to be stored
114
*
115
* \param bci
116
* The bytecode iterator. Must be instantiated in the following way:
117
* \code
118
* bci(0, static_cast<TR_ResolvedJ9Method *> (calltarget->_calleeMethod), ...)
119
* \endcode
120
*
121
* \param nph
122
* Pointer to NeedsPeekingHeuristic.
123
*
124
* \param blocks
125
* Array of block pointers. Size of array must be equal to the maximum
126
* bytecode index in calltarget->_calleeMethod
127
*
128
* \param flags
129
* Array of flags8_t. Size of array must be equal to maximum bytecode
130
* index in calltarget->_calleeMethod
131
*
132
* \return
133
* Reference to cfg
134
*/
135
TR::CFG &processBytecodeAndGenerateCFG(TR_CallTarget *calltarget, TR::Region &cfgRegion, TR_J9ByteCodeIterator &bci, NeedsPeekingHeuristic &nph, TR::Block** blocks, flags8_t * flags);
136
bool realEstimateCodeSize(TR_CallTarget *calltarget, TR_CallStack *prevCallStack, bool recurseDown, TR::Region &cfgRegion);
137
138
bool reduceDAAWrapperCodeSize(TR_CallTarget* target);
139
140
// Partial Inlining Logic
141
bool isInExceptionRange(TR_ResolvedMethod * feMethod, int32_t bcIndex);
142
bool trimBlocksForPartialInlining (TR_CallTarget *calltarget, TR_Queue<TR::Block> *);
143
bool isPartialInliningCandidate(TR_CallTarget *calltarget, TR_Queue<TR::Block> *);
144
bool graphSearch( TR::CFG *, TR::Block *, TR::Block::partialFlags, TR::Block::partialFlags);
145
int32_t labelGraph( TR::CFG *, TR_Queue<TR::Block> *, TR_Queue<TR::Block> *);
146
void processGraph(TR_CallTarget * );
147
148
149
int32_t _lastCallBlockFrequency;
150
int32_t _optimisticSize; // size if we assume we are doing a partial inline
151
};
152
153
#define NUM_PREV_BC 5
154
class TR_prevArgs
155
{
156
public:
157
TR_prevArgs() { for (int32_t i = 0 ; i < NUM_PREV_BC ; i++ ) { _prevBC[i] = J9BCunknown ; } }
158
159
void printIndexes(TR::Compilation *comp)
160
{
161
for (int32_t i = 0 ; i < NUM_PREV_BC ; i++)
162
{
163
if(comp->getDebug())
164
traceMsg(comp,"_prevBC[%d] = %s\n" ,i,((TR_J9VM*)(comp->fej9()))->getByteCodeName(_prevBC[i]));
165
}
166
}
167
168
void updateArg(TR_J9ByteCode bc )
169
{
170
for(int32_t i=NUM_PREV_BC-2 ; i>=0 ; i-- )
171
{
172
_prevBC[i+1] = _prevBC[i];
173
}
174
_prevBC[0] = bc;
175
}
176
177
bool isArgAtIndexReceiverObject (int32_t index)
178
{
179
if ( index < NUM_PREV_BC && _prevBC[index] == J9BCaload0)
180
{
181
return true;
182
}
183
else
184
return false;
185
}
186
187
int32_t getNumPrevConstArgs(int32_t numparms)
188
{
189
int32_t count=0;
190
191
for(int32_t i=0 ; i < NUM_PREV_BC && i < numparms ; i++)
192
{
193
switch (_prevBC[i])
194
{
195
case J9BCaconstnull:
196
case J9BCiconstm1:
197
case J9BCiconst0:
198
case J9BCiconst1:
199
case J9BCiconst2:
200
case J9BCiconst3:
201
case J9BCiconst4:
202
case J9BCiconst5:
203
case J9BClconst0:
204
case J9BClconst1:
205
case J9BCfconst0:
206
case J9BCfconst1:
207
case J9BCfconst2:
208
case J9BCdconst0:
209
case J9BCdconst1:
210
case J9BCldc: case J9BCldcw: case J9BCldc2lw: case J9BCldc2dw:
211
case J9BCbipush: case J9BCsipush:
212
count++;
213
break;
214
default:
215
break;
216
}
217
}
218
return count;
219
}
220
221
222
protected:
223
TR_J9ByteCode _prevBC[NUM_PREV_BC];
224
};
225
226
227
228
229
#endif
230
231