-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathOMROptimization.hpp
177 lines (142 loc) · 6.73 KB
/
OMROptimization.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*******************************************************************************
* 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 OMR_OPTIMIZATION_INCL
#define OMR_OPTIMIZATION_INCL
/*
* The following #define and typedef must appear before any #includes in this file
*/
#ifndef OMR_OPTIMIZATION_CONNECTOR
#define OMR_OPTIMIZATION_CONNECTOR
namespace OMR { class Optimization; }
namespace OMR { typedef OMR::Optimization OptimizationConnector; }
#endif
#include <stddef.h>
#include <stdint.h>
#include "compile/Compilation.hpp"
#include "env/TRMemory.hpp"
#include "il/ILOpCodes.hpp"
#include "infra/Assert.hpp"
#include "infra/Random.hpp"
#include "optimizer/OptimizationManager.hpp"
#include "optimizer/OptimizationManager_inlines.hpp"
#include "optimizer/Optimizations.hpp"
#include "optimizer/Optimizer.hpp"
class TR_Debug;
class TR_FrontEnd;
namespace TR { class SymbolReferenceTable; }
namespace TR { class Block; }
namespace TR { class CodeGenerator; }
namespace TR { class Node; }
namespace TR { class Optimization; }
namespace OMR
{
class OMR_EXTENSIBLE Optimization: public TR_HasRandomGenerator
{
public:
static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((Optimization*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() better return the same allocator as used for new */
/* Virtual destructor is necessary for the above delete operator to work
* See "Modern C++ Design" section 4.7
*/
virtual ~Optimization() {}
inline TR::Optimization * self();
Optimization(TR::OptimizationManager *manager)
: TR_HasRandomGenerator(manager->comp()),
_manager(manager)
{}
virtual bool shouldPerform()
{
// Opts that need to do additional checks should override this method.
return true;
}
virtual int32_t perform() = 0;
// called once before perform is executed
virtual void prePerform();
// called once after perform is executed
virtual void postPerform();
virtual int32_t performOnBlock(TR::Block *block)
{
TR_ASSERT(0, "performOnBlock should be implemented if this opt is being enabled block by block\n");
return 0;
}
// called once before performOnBlock is executed for all relevant blocks
virtual void prePerformOnBlocks() {}
// called once after performOnBlock is executed for all relevant blocks
virtual void postPerformOnBlocks() {}
TR::OptimizationManager * manager() { return _manager; }
TR::Compilation * comp() { return _manager->comp(); }
TR::Optimizer * optimizer() { return _manager->optimizer(); }
TR::CodeGenerator * cg();
TR_FrontEnd * fe();
TR_Debug * getDebug();
TR::SymbolReferenceTable *getSymRefTab();
TR_Memory * trMemory();
TR_StackMemory trStackMemory();
TR_HeapMemory trHeapMemory();
TR_PersistentMemory * trPersistentMemory();
TR::Allocator allocator();
OMR::Optimizations id();
const char * name();
virtual const char * optDetailString() const throw() = 0;
inline bool trace();
void setTrace(bool trace = true);
/**
* @brief Checks if opt has any trace options specified
*
* @return True if any trace option is specified, false otherwise
*/
bool traceAny();
bool getLastRun();
void requestOpt(OMR::Optimizations optNum, bool value = true, TR::Block *block = NULL);
// useful utility functions for opts
void requestDeadTreesCleanup(bool value = true, TR::Block *block = NULL);
void prepareToReplaceNode(TR::Node * node);
void prepareToReplaceNode(TR::Node * node, TR::ILOpCodes opcode);
// Code refactored from SimplifierCommon. In all methods using anchorTree,
// children needing to be anchored will be anchored before the specified
// treetop (via insertBefore)
//
// FIXME: The majority of these functions don't belong here, and should be moved.
bool nodeIsOrderDependent(TR::Node *node, uint32_t depth, bool hasCommonedAncestor);
void anchorChildren(TR::Node *node, TR::TreeTop* anchorTree, uint32_t depth=0, bool hasCommonedAncestor=false, TR::Node *replacement=0);
void anchorAllChildren(TR::Node *node, TR::TreeTop* anchorTree);
void generateAnchor(TR::Node *node, TR::TreeTop* anchorTree);
void anchorNode(TR::Node *node, TR::TreeTop* anchorTree);
//lower-level methods for folding branches
//promoted to TR_Optimization, so the other opts can call this method
bool removeOrconvertIfToGoto(TR::Node*& node, TR::Block* block, int takeBranch, TR::TreeTop* curTree, TR::TreeTop*& reachableTarget, TR::TreeTop*& unreachableTarget, const char* opt_details);
TR::CFGEdge* changeConditionalToUnconditional(TR::Node*& node, TR::Block* block, int takeBranch, TR::TreeTop* curTree, const char* opt_details = "UNKNOWN OPT");
void prepareToStopUsingNode(TR::Node *node, TR::TreeTop* anchorTree, bool anchorChildren=true);
TR::Node *replaceNodeWithChild(TR::Node *node, TR::Node *child, TR::TreeTop* anchorTree, TR::Block *block, bool correctBCDPrecision=true);
TR::Node *replaceNode(TR::Node * node, TR::Node *other, TR::TreeTop* anchorTree, bool anchorChildren=true);
void removeNode(TR::Node * node, TR::TreeTop* anchorTree);
protected:
TR::OptimizationManager *_manager;
};
}
#endif