-
Notifications
You must be signed in to change notification settings - Fork 747
/
Copy pathMethodHandleTransformer.hpp
160 lines (138 loc) · 6.36 KB
/
MethodHandleTransformer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*******************************************************************************
* Copyright IBM Corp. and others 2021
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#ifndef METHODHANDLETRANSFORMER_INCL
#define METHODHANDLETRANSFORMER_INCL
#include <set>
#include <vector>
#include "il/ParameterSymbol.hpp"
#include "compile/Compilation.hpp"
#include "infra/List.hpp"
#include "optimizer/Optimization.hpp"
#include "optimizer/OptimizationManager.hpp"
#include "env/KnownObjectTable.hpp"
/*
* This transformer is used to transform OpenJDK MethodHandle related methods,
* to make sure those methods are optimized for performance.
*
* Most of the transformation require knowledge of object-type node. Sources of
* object info include the following:
* 1. Prex arg info if under inlining
* 2. Nodes with known object index
* 3. Nodes whose value can be compile-time inferred and is a known object
*
* We'd like the object info be avaliable at places where we want to do transformation,
* however, the objects will be stored into autos and autos will be used instead of
* nodes with known object index. Thus we need to track the object info while walking
* the trees.
*
* Data flow analysis is expensive and we can't afford it especially in ilgen. Most of
* the methods we want to optimize should have only one store to an auto, i.e. most of
* the autos are not shared. So we can track the object info in autos with a reverse
* post-order traversal of CFG. Update object info while walking trees of a block, and
* propagate it to the block's successor. When visiting a block, if there exist a
* predecessor unvisited, simply clear the object info inherited from the successors.
*
* This opt will also try to discover as many known objects as possible.
*/
class TR_MethodHandleTransformer : public TR::Optimization
{
public:
TR_MethodHandleTransformer(TR::OptimizationManager *manager)
: TR::Optimization(manager),
_numLocals(0),
_currentObjectInfo(NULL),
_blockEndObjectInfos(NULL)
{}
static TR::Optimization *create(TR::OptimizationManager *manager)
{
return new (manager->allocator()) TR_MethodHandleTransformer(manager);
}
virtual int32_t perform();
virtual const char * optDetailString() const throw();
typedef TR::typed_allocator<TR::KnownObjectTable::Index, TR::Region &> ObjectInfoAllocator;
typedef std::vector<TR::KnownObjectTable::Index, ObjectInfoAllocator> ObjectInfo;
// Walk through trees and nodes in block, update local object info
// Also discover new known objects through field folding
//
void processBlockAndUpdateObjectInfo(TR::Block *block, ObjectInfo *objectInfo);
// Merge ObjectInfo from second into first
//
void mergeObjectInfo(ObjectInfo *first, ObjectInfo *second);
// Obect info at method entry or first block of the method
// The object info comes from prex arg info
//
ObjectInfo* getMethodEntryObjectInfo();
// Object info of a block can be derived from its predecessors
//
ObjectInfo* blockStartObjectInfoFromPredecessors(TR::Block* block);
// Assign local index to autos
//
void assignLocalIndices();
// Walk trees and collect autos into a list
//
void collectAutosFromTrees(List<TR::SymbolReference> &autosList);
// Given an address-typed node, try to figure out it's object info
//
TR::KnownObjectTable::Index getObjectInfoOfNode(TR::Node* node);
// The folowing visit functions will visit different types of node, update object info,
// and/or do transformations
//
void visitIndirectLoad(TR::TreeTop* tt, TR::Node* node);
void visitStoreToLocalVariable(TR::TreeTop* tt, TR::Node* node);
void visitCall(TR::TreeTop* tt, TR::Node* node);
void visitNode(TR::TreeTop* tt, TR::Node* node, TR::NodeChecklist &visitedNodes);
// Refine MethodHandle.invokeBasic with known object info
//
void process_java_lang_invoke_MethodHandle_invokeBasic(TR::TreeTop* tt, TR::Node* node);
// Refine MethodHandle.linkTo* with known object info
//
void process_java_lang_invoke_MethodHandle_linkTo(TR::TreeTop* tt, TR::Node* node);
/** \brief
* Transforms calls to java/lang/invoke/Invokers.checkExactType to ZEROCHK, or eliminated
* entirely if the check can be performed at compile time
*
* \param tt
* The treetop of the call node
*
* \param node
* The call node representing the call to java/lang/invoke/Invokers.checkExactType
*/
void process_java_lang_invoke_Invokers_checkExactType(TR::TreeTop* tt, TR::Node* node);
/** \brief
* Eliminates calls to java/lang/invoke/Invokers.checkCustomized when its argument
* is a known object
*
* \param tt
* The treetop of the call node
*
* \param node
* The call node representing the call to java/lang/invoke/Invokers.checkCustomized
*/
void process_java_lang_invoke_Invokers_checkCustomized(TR::TreeTop* tt, TR::Node* node);
private:
int32_t _numLocals; // Number of parms, autos and temps
ObjectInfo * _currentObjectInfo; // Object info for current block being processed
typedef TR::typed_allocator<std::pair<const int32_t, ObjectInfo *>, TR::Region &> ResultAllocator;
typedef std::map<int32_t, ObjectInfo *, std::less<int32_t>, ResultAllocator> BlockResultMap;
BlockResultMap* _blockEndObjectInfos; // A map of object info at the end of blocks
};
#endif