-
Notifications
You must be signed in to change notification settings - Fork 746
/
Copy pathNewInitialization.hpp
161 lines (137 loc) · 6.34 KB
/
NewInitialization.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
161
/*******************************************************************************
* Copyright IBM Corp. and others 2000
*
* 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 NEWINITIALIZATION_INCL
#define NEWINITIALIZATION_INCL
#include <stddef.h>
#include <stdint.h>
#include "infra/Link.hpp"
#include "optimizer/Optimization.hpp"
#include "optimizer/OptimizationManager.hpp"
class TR_BitVector;
namespace TR { class Node; }
namespace TR { class ResolvedMethodSymbol; }
namespace TR { class TreeTop; }
template <class T> class TR_Array;
template <class T> class TR_ScratchList;
/// Attempts to skip zero initializations of objects where possible. Basically
/// scans forward in the basic block from the point of the allocation and tries
/// to find explicit definitions of fields (say in constructors) that occur
/// before any use of the field. In these cases the zero initialization of
/// fields (required according to Java spec, so no field is uninitialized) can
/// be skipped. Note that for reference fields the presence of a GC point
/// before any user-specified definition means that the field must be zero
/// initialized. Peeking inside calls is done to maximize the number of explicit
/// field initializations seen by the analysis. In addition, for some special
/// array allocations (e.g. char arrays that are used by String, often do not
/// need zero initialization as they are filled in by arraycopy calls
/// immediately), we can skip zero initializations completely.
class TR_NewInitialization : public TR::Optimization
{
public:
TR_NewInitialization(TR::OptimizationManager *manager);
protected:
struct NodeEntry : public TR_Link<NodeEntry>
{
TR::Node *node;
};
struct TreeTopEntry : public TR_Link<TreeTopEntry>
{
TR::TreeTop *treeTop;
};
struct Candidate : public TR_Link<Candidate>
{
TR::TreeTop *treeTop;
TR::Node *node;
TR_BitVector *uninitializedWords;
TR_BitVector *initializedBytes;
TR_BitVector *uninitializedBytes;
TR_LinkHead<NodeEntry> localStores;
TR_LinkHead<NodeEntry> localLoads;
TR_LinkHead<TreeTopEntry> inlinedCalls;
int32_t size;
int32_t startOffset;
int32_t numUninitializedWords;
int32_t numInitializedBytes;
int32_t numUninitializedBytes;
bool isArrayNew;
bool isInSniffedMethod;
};
int32_t performAnalysis(bool doGlobalAnalysis);
bool doAnalysisOnce(int32_t iteration);
// Methods for finding the allocation node candidates and for scanning the
// trees for explicit initializations
//
//
void findNewCandidates();
bool findNewCandidatesInBlock(TR::TreeTop *startTree, TR::TreeTop *endTree);
bool findAllocationNode(TR::TreeTop *treeTop, TR::Node *node);
bool sniffCall(TR::TreeTop *callTree);
TR::ResolvedMethodSymbol *findInlinableMethod(TR::TreeTop *callTree);
TR::Node *resolveNode(TR::Node *node);
bool matchLocalLoad(TR::Node *node, Candidate *c);
Candidate *findBaseOfIndirection(TR::Node *directBase);
bool isNewObject(TR::Node *node, Candidate *c);
Candidate *findCandidateReference(TR::Node *node);
Candidate *findCandidateReferenceInSubTree(TR::Node *node, TR_ScratchList<TR::Node> *seenNodes);
bool visitNode(TR::Node *node);
void setAffectedCandidate(Candidate *c);
void escapeToUserCode(Candidate *c, TR::Node *cause);
void escapeToUserCodeAllCandidates(TR::Node *cause, bool onlyArrays = false);
void escapeToGC(Candidate *c, TR::Node *cause);
void escapeToGC(TR::Node *cause);
void escapeViaCall(TR::Node *callNode);
void escapeViaArrayCopyOrArraySet(TR::Node *arrayCopyNode);
void findUninitializedWords();
// Methods for actually changing the trees
//
bool changeNewCandidates();
void inlineCalls();
void modifyTrees(Candidate *candidate);
int32_t buildInitializationInfo(Candidate *c, TR_BitVector *wordsToBeInitialized, int32_t startWord);
virtual int32_t getValueNumber(TR::Node *n) = 0;
TR::TreeTop *_outermostCallSite;
TR_Array<TR::Node*> *_parms;
Candidate *_firstActiveCandidate;
TR_LinkHead<TreeTopEntry> _inlinedCallSites;
TR_LinkHeadAndTail<Candidate> _candidates;
int32_t _maxIterations;
int32_t _maxInlinedBytecodeSize;
int32_t _maxTotalInlinedBytecodeSize;
int32_t _totalInlinedBytecodeSize;
bool _sniffConstructorsOnly;
bool _sniffCalls;
bool _removeZeroStores;
bool _invalidateUseDefInfo;
};
class TR_LocalNewInitialization : public TR_NewInitialization
{
public:
TR_LocalNewInitialization(TR::OptimizationManager *manager);
static TR::Optimization *create(TR::OptimizationManager *manager)
{
return new (manager->allocator()) TR_LocalNewInitialization(manager);
}
virtual int32_t perform();
virtual const char * optDetailString() const throw();
virtual int32_t getValueNumber(TR::Node *n);
};
#endif