Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/optimizer/IdiomRecognition.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2022 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 IDIOMRECOGNITION_INCL
24
#define IDIOMRECOGNITION_INCL
25
26
#include <stdint.h>
27
#include <string.h>
28
#include "compile/Compilation.hpp"
29
#include "compile/CompilationTypes.hpp"
30
#include "env/TRMemory.hpp"
31
#include "il/DataTypes.hpp"
32
#include "il/ILOpCodes.hpp"
33
#include "il/ILOps.hpp"
34
#include "il/ILProps.hpp"
35
#include "infra/Assert.hpp"
36
#include "infra/BitVector.hpp"
37
#include "infra/Flags.hpp"
38
#include "infra/HashTab.hpp"
39
#include "infra/Link.hpp"
40
#include "infra/List.hpp"
41
#include "infra/TRlist.hpp"
42
#include "optimizer/LoopCanonicalizer.hpp"
43
#include "optimizer/OptimizationManager.hpp"
44
45
class TR_CISCTransformer;
46
class TR_RegionStructure;
47
class TR_UseDefInfo;
48
namespace TR { class Block; }
49
namespace TR { class CFG; }
50
namespace TR { class CFGEdge; }
51
namespace TR { class CFGNode; }
52
namespace TR { class Node; }
53
namespace TR { class Optimization; }
54
namespace TR { class Optimizer; }
55
namespace TR { class SymbolReference; }
56
namespace TR { class TreeTop; }
57
58
typedef enum
59
{
60
TR_variable = TR::NumIlOps,
61
TR_booltable,
62
TR_entrynode,
63
TR_exitnode,
64
TR_allconst,
65
TR_ahconst, // constant for array header
66
TR_variableORconst,
67
TR_quasiConst, // Currently, variable or constant or arraylength
68
TR_quasiConst2, // Currently, variable or constant, arraylength, or *iiload* (for non-array)
69
// We shouldn't use it in an idiom including iistore to *non-array* variable.
70
TR_iaddORisub, // addition or subtraction
71
TR_conversion, // all data conversions, such as b2i, c2i, i2l, ...
72
TR_ifcmpall, // all if instructions
73
TR_ishrall, // ishr and iushr
74
TR_bitop1, // AND, OR, and XOR
75
TR_arrayindex, // variable or addition
76
TR_arraybase, // variable or iaload
77
TR_inbload, // indirect non-byte load
78
TR_inbstore, // indirect non-byte store
79
TR_indload, // indirect load
80
TR_indstore, // indirect store
81
TR_ibcload, // indirect byte or char load
82
TR_ibcstore // indirect byte or char store
83
} TR_CISCOps;
84
85
struct TrNodeInfo
86
{
87
TR::Block *_block;
88
TR::Node *_node;
89
TR::TreeTop *_treeTop;
90
};
91
92
93
class TR_CISCNode
94
{
95
public:
96
TR_ALLOC(TR_Memory::LoopTransformer);
97
TR_HeapMemory trHeapMemory() { return _trMemory; }
98
99
bool isEqualOpc(TR_CISCNode *t);
100
101
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_AllocationKind allocKind = heapAlloc)
102
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
103
{
104
initialize(opc, id, dagId, ncfgs, nchildren);
105
}
106
107
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred, TR_AllocationKind allocKind = heapAlloc)
108
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
109
{
110
initialize(opc, id, dagId, ncfgs, nchildren);
111
pred->setSucc(0, this);
112
}
113
114
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred, TR_CISCNode *child0, TR_AllocationKind allocKind = heapAlloc)
115
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
116
{
117
initialize(opc, id, dagId, ncfgs, nchildren);
118
pred->setSucc(0, this);
119
setChild(0, child0);
120
}
121
122
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred, TR_CISCNode *child0, TR_CISCNode *child1, TR_AllocationKind allocKind = heapAlloc)
123
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
124
{
125
initialize(opc, id, dagId, ncfgs, nchildren);
126
pred->setSucc(0, this);
127
setChildren(child0, child1);
128
}
129
130
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, int32_t otherInfo, TR_AllocationKind allocKind = heapAlloc)
131
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
132
{
133
initialize(opc, id, dagId, ncfgs, nchildren, otherInfo);
134
}
135
136
TR_CISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, int32_t otherInfo, TR_CISCNode *pred, TR_AllocationKind allocKind = heapAlloc)
137
: _allocKind(allocKind), _trMemory(m), _preds(m), _parents(m), _dest(m), _chains(m), _hintChildren(m), _trNodeInfo(m), _dt(dt)
138
{
139
initialize(opc, id, dagId, ncfgs, nchildren, otherInfo);
140
pred->setSucc(0, this);
141
}
142
143
void initialize(uint32_t opc, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren)
144
{
145
initializeMembers(opc, id, dagId, ncfgs, nchildren);
146
allocArrays(ncfgs, nchildren);
147
}
148
149
void initializeMembers(uint32_t opc, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren);
150
void initialize(uint32_t opc, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, int32_t otherInfo)
151
{
152
initialize(opc, id, dagId, ncfgs, nchildren);
153
setOtherInfo(otherInfo);
154
}
155
156
TR_Memory * trMemory() { return _trMemory; }
157
158
void setOtherInfo(int32_t otherInfo)
159
{
160
_flags.set(_isValidOtherInfo);
161
_otherInfo = otherInfo;
162
checkFlags();
163
}
164
165
void checkFlags()
166
{
167
if (isValidOtherInfo())
168
{
169
switch(_opcode)
170
{
171
case TR::iconst:
172
case TR::sconst:
173
case TR::bconst:
174
case TR::lconst:
175
setIsInterestingConstant();
176
break;
177
}
178
}
179
}
180
181
void replaceSucc(uint32_t index, TR_CISCNode *to);
182
inline void setSucc(uint32_t index, TR_CISCNode *ch)
183
{
184
TR_ASSERT(index < _numSuccs, "TR_CISCNode::setSucc index out of range");
185
_succs[index] = ch;
186
ch->addPred(this);
187
}
188
189
void setSucc(TR_CISCNode *ch)
190
{
191
setSucc(0, ch);
192
}
193
194
void setSuccs(TR_CISCNode *ch1, TR_CISCNode *ch2)
195
{
196
setSucc(0, ch1);
197
setSucc(1, ch2);
198
}
199
200
void replaceChild(uint32_t index, TR_CISCNode *ch);
201
inline void setChild(uint32_t index, TR_CISCNode *ch)
202
{
203
TR_ASSERT(index < _numChildren, "TR_CISCNode::setChild index out of range");
204
_children[index] = ch;
205
ch->addParent(this);
206
}
207
208
void setChild(TR_CISCNode *ch)
209
{
210
setChild(0, ch);
211
}
212
213
void setChildren(TR_CISCNode *ch1, TR_CISCNode *ch2)
214
{
215
setChild(0, ch1);
216
setChild(1, ch2);
217
}
218
219
inline TR_CISCNode *getSucc(uint32_t index)
220
{
221
TR_ASSERT(index < _numSuccs, "TR_CISCNode::getSucc index out of range");
222
return _succs[index];
223
}
224
225
inline TR_CISCNode *getChild(uint32_t index)
226
{
227
TR_ASSERT(index < _numChildren, "TR_CISCNode::getChild index out of range");
228
return _children[index];
229
}
230
231
TR_CISCNode *getNodeIfSingleChain() { return _chains.isSingleton() ? _chains.getListHead()->getData() : 0; }
232
233
inline uint16_t getChildID(uint32_t index) { return getChild(index)->_id; }
234
inline uint32_t getOpcode() { return _opcode; }
235
inline const TR::ILOpCode& getIlOpCode() { return _ilOpCode; }
236
inline TR::DataType getDataType() { return _dt; }
237
inline uint16_t getNumChildren() { return _numChildren; }
238
inline uint16_t getNumSuccs() { return _numSuccs; }
239
inline uint16_t getID() { return _id; }
240
inline uint16_t getDagID() { return _dagId; }
241
inline void setDagID(int16_t d) { _dagId = d; }
242
inline int32_t getOtherInfo() { return _otherInfo; }
243
void initChains() { _chains.init(); }
244
245
// flags
246
bool isValidOtherInfo() { return _flags.testAny(_isValidOtherInfo); }
247
void setIsStoreDirect(bool v = true) { _flags.set(_isStoreDirect, v); }
248
bool isStoreDirect() { return _flags.testAny(_isStoreDirect); }
249
void setIsLoadVarDirect(bool v = true) { _flags.set(_isLoadVarDirect, v); }
250
bool isLoadVarDirect() { return _flags.testAny(_isLoadVarDirect); }
251
void setIsNegligible(bool v = true) { _flags.set(_isNegligible, v); }
252
bool isNegligible() { return _flags.testAny(_isNegligible); }
253
void setIsSuccSimplyConnected(bool v = true) { _flags.set(_isSuccSimplyConnected, v); }
254
bool isSuccSimplyConnected() { return _flags.testAny(_isSuccSimplyConnected); }
255
void setIsPredSimplyConnected(bool v = true) { _flags.set(_isPredSimplyConnected, v); }
256
bool isPredSimplyConnected() { return _flags.testAny(_isPredSimplyConnected); }
257
void setIsChildSimplyConnected(bool v = true) { _flags.set(_isChildSimplyConnected, v); }
258
bool isChildSimplyConnected() { return _flags.testAny(_isChildSimplyConnected); }
259
void setIsParentSimplyConnected(bool v = true) { _flags.set(_isParentSimplyConnected, v); }
260
bool isParentSimplyConnected() { return _flags.testAny(_isParentSimplyConnected); }
261
void setIsEssentialNode(bool v = true) { _flags.set(_isEssentialNode, v); }
262
bool isEssentialNode() { return _flags.testAny(_isEssentialNode); }
263
void setIsOptionalNode(bool v = true) { _flags.set(_isOptionalNode, v); }
264
bool isOptionalNode() { return _flags.testAny(_isOptionalNode); }
265
void setIsChildDirectlyConnected(bool v = true) { _flags.set(_isChildDirectlyConnected, v); }
266
bool isChildDirectlyConnected() { return _flags.testAny(_isChildDirectlyConnected); }
267
void setIsSuccDirectlyConnected(bool v = true) { _flags.set(_isSuccDirectlyConnected, v); }
268
bool isSuccDirectlyConnected() { return _flags.testAny(_isSuccDirectlyConnected); }
269
void setIsInterestingConstant(bool v = true) { _flags.set(_isInterestingConstant, v); }
270
bool isInterestingConstant() { return _flags.testAny(_isInterestingConstant); }
271
void setIsNecessaryScreening(bool v = true) { _flags.set(_isNecessaryScreening, v); }
272
bool isNecessaryScreening() { return _flags.testAny(_isNecessaryScreening); }
273
void setIsLightScreening(bool v = true) { _flags.set(_isLightScreening, v); }
274
bool isLightScreening() { return _flags.testAny(_isLightScreening); }
275
bool isDataConnected() { return _flags.testAll(_isChildSimplyConnected |
276
_isParentSimplyConnected); }
277
bool isCFGConnected() { return _flags.testAll(_isSuccSimplyConnected |
278
_isPredSimplyConnected); }
279
bool isCFGDataConected() { return _flags.testAll(_isSuccSimplyConnected |
280
_isPredSimplyConnected |
281
_isChildSimplyConnected |
282
_isParentSimplyConnected); }
283
void setOutsideOfLoop(bool v = true) { _flags.set(_isOutsideOfLoop, v); }
284
bool isOutsideOfLoop() { return _flags.testAny(_isOutsideOfLoop); }
285
void setCISCNodeModified(bool v = true) { _flags.set(_isCISCNodeModified, v); }
286
bool isCISCNodeModified() { return _flags.testAny(_isCISCNodeModified); }
287
void setNewCISCNode(bool v = true) { _flags.set(_isNewCISCNode, v); }
288
bool isNewCISCNode() { return _flags.testAny(_isNewCISCNode); }
289
void setSkipParentsCheck(bool v = true) { _flags.set(_isSkipParentsCheck, v); }
290
bool isSkipParentsCheck() { return _flags.testAny(_isSkipParentsCheck); }
291
292
// short cut
293
bool isCommutative() { return _ilOpCode.isCommutative(); }
294
295
TR_CISCNode *getLatestDest()
296
{
297
TR_ASSERT( _opcode == TR_variable, "TR_CISCNode::getLatestDest()");
298
return _latestDest;
299
}
300
//bool checkParents(TR_CISCNode *, const int8_t level);
301
static bool checkParentsNonRec(TR_CISCNode *, TR_CISCNode *, int8_t level, TR::Compilation *);
302
void reverseBranchOpCodes();
303
304
static const char *getName(TR_CISCOps, TR::Compilation *);
305
void dump(TR::FILE *pOutFile, TR::Compilation *);
306
void printStdout();
307
308
void addChain(TR_CISCNode *tgt, bool alsoAddChainsTgt = false)
309
{
310
_chains.add(tgt);
311
if (alsoAddChainsTgt) tgt->_chains.add(this);
312
}
313
314
enum // flag bits
315
{
316
_isValidOtherInfo = 0x00000001,
317
_isStoreDirect = 0x00000002,
318
_isNegligible = 0x00000004,
319
_isSuccSimplyConnected = 0x00000008,
320
_isPredSimplyConnected = 0x00000010,
321
_isChildSimplyConnected = 0x00000020,
322
_isParentSimplyConnected = 0x00000040,
323
_isLoadVarDirect = 0x00000080,
324
_isEssentialNode = 0x00000100,
325
_isOptionalNode = 0x00000200,
326
_isChildDirectlyConnected = 0x00000400,
327
_isSuccDirectlyConnected = 0x00000800,
328
_isInterestingConstant = 0x00001000,
329
_isNecessaryScreening = 0x00002000,
330
_isLightScreening = 0x00004000,
331
_isOutsideOfLoop = 0x00008000,
332
_isCISCNodeModified = 0x00010000,
333
_isNewCISCNode = 0x00020000,
334
_isSkipParentsCheck = 0x00040000,
335
_dummyEnum
336
};
337
338
339
void initializeLists()
340
{
341
_preds.init();
342
_parents.init();
343
_dest.init();
344
_hintChildren.init();
345
_trNodeInfo.init();
346
initChains();
347
}
348
349
virtual void allocArrays(uint16_t ncfgs, uint16_t nchildren)
350
{
351
_succs = (TR_CISCNode **)(ncfgs ? trMemory()->allocateMemory(ncfgs * sizeof(*_succs), _allocKind) : 0);
352
_children = (TR_CISCNode **)(nchildren ? trMemory()->allocateMemory(nchildren * sizeof(*_children), _allocKind) : 0);
353
}
354
355
virtual void addPred(TR_CISCNode *t) { _preds.add(t); }
356
virtual void addParent(TR_CISCNode *t) { _parents.add(t); }
357
List<TR_CISCNode> *getPreds() { return &_preds; }
358
TR_CISCNode *getHeadOfPredecessors() { return _preds.getListHead()->getData(); }
359
List<TR_CISCNode> *getParents() { return &_parents; }
360
TR_CISCNode *getHeadOfParents() { return _parents.getListHead()->getData(); }
361
362
void addTrNode(TR::Block *b, TR::TreeTop *t, TR::Node *n)
363
{
364
TrNodeInfo *newInfo = (TrNodeInfo *)trMemory()->allocateMemory(sizeof(*newInfo), _allocKind);
365
newInfo->_block = b;
366
newInfo->_treeTop = t;
367
newInfo->_node = n;
368
_trNodeInfo.add(newInfo);
369
}
370
List<TrNodeInfo> *getTrNodeInfo() { return &_trNodeInfo; }
371
inline TrNodeInfo *getHeadOfTrNodeInfo() { return _trNodeInfo.getListHead()->getData(); }
372
inline TR::Node *getHeadOfTrNode() { return _trNodeInfo.getListHead()->getData()->_node; }
373
inline TR::TreeTop *getHeadOfTreeTop() { return _trNodeInfo.getListHead()->getData()->_treeTop; }
374
inline TR::Block *getHeadOfBlock() { return _trNodeInfo.getListHead()->getData()->_block; }
375
376
void setDest(TR_CISCNode *v)
377
{
378
TR_ASSERT(v != 0 && v->_opcode == TR_variable, "TR_CISCNode::setDest(), input error");
379
if (v->_latestDest)
380
{
381
TR_ASSERT(v->_latestDest->_dest.find(v), "TR_CISCNode::setDest(), input variable is not found in _latestDest");
382
v->_latestDest->_dest.remove(v);
383
}
384
ListAppender<TR_CISCNode> appender(&_dest);
385
appender.add(v);
386
v->_latestDest = this;
387
}
388
TR_CISCNode *getFirstDest()
389
{
390
return _dest.isEmpty() ? 0 : _dest.getListHead()->getData();
391
}
392
List<TR_CISCNode> *getHintChildren() { return &_hintChildren; }
393
void addHint(TR_CISCNode *n) { _hintChildren.add(n); }
394
bool isEmptyHint() { return _hintChildren.isEmpty(); }
395
List<TR_CISCNode> *getChains() {return &_chains; }
396
bool checkDagIdInChains();
397
TR::TreeTop *getDestination(bool isFallThrough = false);
398
void deadAllChildren();
399
TR_CISCNode *duplicate()
400
{
401
TR_CISCNode *ret = new (trHeapMemory()) TR_CISCNode(_trMemory, _opcode, _dt, _id, _dagId, _numSuccs, _numChildren);
402
ret->_otherInfo = _otherInfo;
403
ret->_flags = _flags;
404
405
// duplicate _trNodeIndo
406
ListIterator<TrNodeInfo> li(&_trNodeInfo);
407
ListAppender<TrNodeInfo> appender(&ret->_trNodeInfo);
408
for (TrNodeInfo *t = li.getFirst(); t; t = li.getNext()) appender.add(t);
409
410
// Duplicating other lists will be performed in the caller.
411
412
return ret;
413
}
414
415
// Variables
416
protected:
417
void setOpcode(uint32_t opc)
418
{
419
_opcode = opc;
420
_ilOpCode.setOpCodeValue(opc < TR::NumIlOps ? (TR::ILOpCodes)opc : TR::BadILOp);
421
}
422
uint32_t _opcode; // TR::ILOpCodes enum
423
TR::ILOpCode _ilOpCode;
424
TR::DataType _dt;
425
TR_CISCNode **_succs;
426
TR_CISCNode **_children;
427
TR_CISCNode *_latestDest;
428
int32_t _otherInfo;
429
uint16_t _numSuccs;
430
uint16_t _numChildren;
431
432
uint16_t _id;
433
uint16_t _dagId;
434
flags32_t _flags;
435
436
TR_AllocationKind _allocKind;
437
TR_Memory * _trMemory;
438
List<TR_CISCNode> _preds;
439
List<TR_CISCNode> _parents;
440
List<TR_CISCNode> _dest; // destination operands
441
List<TR_CISCNode> _chains;
442
List<TR_CISCNode> _hintChildren;
443
List<TrNodeInfo> _trNodeInfo;
444
};
445
446
447
// Use persistent allocation
448
class TR_PCISCNode : public TR_CISCNode
449
{
450
public:
451
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren)
452
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, persistentAlloc)
453
{
454
};
455
456
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred)
457
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, pred, persistentAlloc)
458
{
459
}
460
461
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred, TR_CISCNode *child0)
462
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, pred, child0, persistentAlloc)
463
{
464
}
465
466
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, TR_CISCNode *pred, TR_CISCNode *child0, TR_CISCNode *child1)
467
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, pred, child0, child1, persistentAlloc)
468
{
469
}
470
471
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, int32_t otherInfo)
472
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, otherInfo, persistentAlloc)
473
{
474
}
475
476
TR_PCISCNode(TR_Memory * m, uint32_t opc, TR::DataType dt, uint16_t id, int16_t dagId, uint16_t ncfgs, uint16_t nchildren, int32_t otherInfo, TR_CISCNode *pred)
477
: TR_CISCNode(m, opc, dt, id, dagId, ncfgs, nchildren, otherInfo, pred, persistentAlloc)
478
{
479
}
480
481
TR_PCISCNode *getSucc(uint32_t index)
482
{
483
return (TR_PCISCNode *) TR_CISCNode::getSucc(index);
484
}
485
486
TR_PCISCNode *getChild(uint32_t index)
487
{
488
return (TR_PCISCNode *) TR_CISCNode::getChild(index);
489
}
490
491
virtual void addPred(TR_CISCNode *t)
492
{
493
TR_PersistentList<TR_CISCNode> *p = (TR_PersistentList<TR_CISCNode> *)&_preds;
494
p->add(t);
495
}
496
virtual void addParent(TR_CISCNode *t)
497
{
498
TR_PersistentList<TR_CISCNode> *p = (TR_PersistentList<TR_CISCNode> *)&_parents;
499
p->add(t);
500
}
501
virtual void allocArrays(uint16_t ncfgs, uint16_t nchildren)
502
{
503
_succs = (TR_CISCNode **)(ncfgs ? jitPersistentAlloc(ncfgs * sizeof(*_succs)) : 0);
504
_children = (TR_CISCNode **)(nchildren ? jitPersistentAlloc(nchildren * sizeof(*_children)) : 0);
505
}
506
};
507
508
509
class TR_CISCHash
510
{
511
public:
512
TR_ALLOC(TR_Memory::LoopTransformer);
513
514
TR_CISCHash(TR_Memory * m, uint32_t num = 0, TR_AllocationKind allocKind = heapAlloc)
515
:_trMemory(m)
516
{
517
if (num > 0)
518
setNumBuckets(num, allocKind);
519
else
520
{
521
_numBuckets = 0;
522
_buckets = 0;
523
_allocationKind = allocKind;
524
}
525
}
526
527
TR_Memory * trMemory() { return _trMemory; }
528
529
void setNumBuckets(uint32_t num, TR_AllocationKind allocKind)
530
{
531
_allocationKind = allocKind;
532
setNumBuckets(num);
533
}
534
535
void setNumBuckets(uint32_t num)
536
{
537
TR_ASSERT(num > 0, "error: num == 0!");
538
_numBuckets = num;
539
uint32_t size = num * sizeof(*_buckets);
540
_buckets = (HashTableEntry **)trMemory()->allocateMemory(size, _allocationKind);
541
memset(_buckets, 0, size);
542
}
543
544
struct HashTableEntry
545
{
546
HashTableEntry *_next;
547
uint64_t _key;
548
TR_CISCNode *_node;
549
};
550
551
TR_CISCNode *find(uint64_t key);
552
bool add(uint64_t key, TR_CISCNode *, bool checkExist = false);
553
uint32_t getNumBuckets() { return _numBuckets; }
554
555
private:
556
557
uint32_t _numBuckets;
558
HashTableEntry **_buckets;
559
TR_Memory * _trMemory;
560
TR_AllocationKind _allocationKind;
561
};
562
563
564
enum TR_GraphAspects // flag bits
565
{
566
storeShiftCount = 12,
567
nbValue = (0xFF & ~ILTypeProp::Size_1),
568
existAccess = 0x00000100,
569
loadMasks = 0x000001FF,
570
storeMasks = 0x001FF000,
571
sameTypeLoadStore = 0x00200000,
572
573
bitop1 = 0x00800000,
574
iadd = 0x01000000,
575
isub = 0x02000000,
576
call = 0x04000000,
577
shr = 0x08000000,
578
bndchk = 0x10000000,
579
reminder = 0x20000000,
580
division = 0x40000000,
581
mul = 0x80000000
582
};
583
584
class TR_CISCGraphAspects : public flags32_t
585
{
586
public:
587
588
TR_CISCGraphAspects() {init();}
589
void init() {clear();}
590
void setLoadAspects(uint32_t val, bool orExistAccess = true); // assuming val as a combination of ILTypeProp::*
591
void setStoreAspects(uint32_t val, bool orExistAccess = true); // assuming val as a combination of ILTypeProp::*
592
void modifyAspects();
593
uint32_t getLoadAspects() { return getValue(loadMasks); }
594
uint32_t getStoreAspects() { return getValue(storeMasks) >> storeShiftCount; }
595
virtual void print(TR::Compilation *, bool noaspects);
596
};
597
598
599
class TR_CISCGraphAspectsWithCounts : public TR_CISCGraphAspects
600
{
601
public:
602
603
TR_CISCGraphAspectsWithCounts() {init();}
604
void init() {TR_CISCGraphAspects::init(); setMinCounts(0,0,0);}
605
void setAspectsByOpcode(int opc);
606
void setAspectsByOpcode(TR_CISCNode *n) { setAspectsByOpcode(n->getOpcode()); }
607
void print(TR::Compilation *, bool noaspects);
608
609
void setMinCounts(uint8_t ifCount, uint8_t iloadCount, uint8_t istoreCount)
610
{ _ifCount = ifCount; _indirectLoadCount = iloadCount; _indirectStoreCount = istoreCount; }
611
uint8_t incIfCount() { return ++_ifCount; }
612
uint8_t incIndirectLoadCount() { return ++_indirectLoadCount; }
613
uint8_t incIndirectStoreCount() { return ++_indirectStoreCount; }
614
uint8_t getIfCount() { return _ifCount; }
615
uint8_t getIndirectLoadCount() { return _indirectLoadCount; }
616
uint8_t getIndirectStoreCount() { return _indirectStoreCount; }
617
bool meetMinCounts(TR_CISCGraphAspectsWithCounts *p) // p is for the pattern
618
{
619
return (_ifCount >= p->_ifCount &&
620
_indirectLoadCount >= p->_indirectLoadCount &&
621
_indirectStoreCount >= p->_indirectStoreCount);
622
}
623
624
protected:
625
uint8_t _ifCount;
626
uint8_t _indirectLoadCount;
627
uint8_t _indirectStoreCount;
628
};
629
630
631
632
template <class T> class TR_ListDuplicator
633
{
634
public:
635
TR_ALLOC(TR_Memory::LoopTransformer);
636
TR_HeapMemory trHeapMemory() { return _trMemory; }
637
638
TR_ListDuplicator<T>(TR_Memory * m)
639
: _trMemory(m), _list(0)
640
{
641
_flags.clear();
642
}
643
644
virtual void setList(List<T>* l) { setRegistered(); setDuplicated(false); _list = l; }
645
List<T>* getList() { TR_ASSERT(isRegistered(), "error"); return _list; }
646
virtual List<T>* duplicateList(bool ifNecessary = true)
647
{
648
if (ifNecessary && isDuplicated()) return _list;
649
setDuplicated();
650
List<T>* ret = new (trHeapMemory()) List<T>(_trMemory);
651
ListAppender<T> appender(ret);
652
ListIterator<T> li(_list);
653
T *t;
654
for (t = li.getFirst(); t; t = li.getNext()) appender.add(t);
655
_list = ret;
656
return ret;
657
}
658
659
enum // flag bits
660
{
661
_isRegistered = 0x0001,
662
_isDuplicated = 0x0002,
663
_isDuplicateElement = 0x0004,
664
_dummyEnum
665
};
666
667
void setRegistered(bool v = true) { _flags.set(_isRegistered, v); }
668
bool isRegistered() { return _flags.testAny(_isRegistered); }
669
void setDuplicated(bool v = true) { _flags.set(_isDuplicated, v); }
670
bool isDuplicated() { return _flags.testAny(_isDuplicated); }
671
void setDuplicateElement(bool v = true) { _flags.set(_isDuplicateElement, v); }
672
bool isDuplicateElement() { return _flags.testAny(_isDuplicateElement); }
673
674
protected:
675
List<T> *_list;
676
flags8_t _flags;
677
TR_Memory * _trMemory;
678
};
679
680
681
class ListOfCISCNodeDuplicator : public TR_ListDuplicator<TR_CISCNode>
682
{
683
public:
684
ListOfCISCNodeDuplicator(TR_Memory * m) : TR_ListDuplicator<TR_CISCNode>(m), _mapping(m) {};
685
virtual void setList(List<TR_CISCNode>* l)
686
{
687
TR_ListDuplicator<TR_CISCNode>::setList(l);
688
_mapping.init();
689
}
690
virtual List<TR_CISCNode> *duplicateList(bool ifNecessary = true)
691
{
692
if (ifNecessary && isDuplicated()) return _list;
693
setDuplicated();
694
List<TR_CISCNode>* ret = new (trHeapMemory()) List<TR_CISCNode>(_trMemory);
695
ListAppender<TR_CISCNode> appender(ret);
696
ListIterator<TR_CISCNode> li(_list);
697
TR_CISCNode *t;
698
_list = ret;
699
if (isDuplicateElement())
700
{
701
TR_CISCNode *newCISC;
702
for (t = li.getFirst(); t; t = li.getNext())
703
{
704
newCISC = t->duplicate();
705
appender.add(newCISC);
706
TR_Pair<TR_CISCNode,TR_CISCNode> *pair = new (trHeapMemory()) TR_Pair<TR_CISCNode,TR_CISCNode>(t, newCISC);
707
_mapping.add(pair);
708
}
709
ListIterator<TR_CISCNode> liNew(ret);
710
for (t = li.getFirst(), newCISC = liNew.getFirst(); t; t = li.getNext(), newCISC = liNew.getNext())
711
{
712
int32_t i;
713
for (i = 0; i < t->getNumChildren(); i++)
714
newCISC->setChild(i, findCorrespondingNode(t->getChild(i)));
715
for (i = 0; i < t->getNumSuccs(); i++)
716
newCISC->setSucc(i, findCorrespondingNode(t->getSucc(i)));
717
restructureList(t->getChains(), newCISC->getChains());
718
restructureList(t->getHintChildren(), newCISC->getHintChildren());
719
}
720
}
721
else
722
{
723
for (t = li.getFirst(); t; t = li.getNext()) { appender.add(t); }
724
}
725
return ret;
726
}
727
728
TR_CISCNode *findCorrespondingNode(TR_CISCNode *old)
729
{
730
TR_Pair<TR_CISCNode,TR_CISCNode> *pair;
731
ListElement<TR_Pair<TR_CISCNode,TR_CISCNode> > *le;
732
// Search for old
733
for (le = _mapping.getListHead(); le; le = le->getNextElement())
734
{
735
pair = le->getData();
736
if (pair->getKey() == old) return pair->getValue();
737
}
738
TR_ASSERT(false, "error");
739
return NULL;
740
}
741
742
void restructureList(List<TR_CISCNode> *oldList, List<TR_CISCNode> *newList)
743
{
744
TR_ASSERT(newList->isEmpty(), "error");
745
ListAppender<TR_CISCNode> appender(newList);
746
ListIterator<TR_CISCNode> li(oldList);
747
TR_CISCNode *t;
748
for (t = li.getFirst(); t; t = li.getNext()) appender.add(findCorrespondingNode(t));
749
}
750
751
protected:
752
List<TR_Pair<TR_CISCNode,TR_CISCNode> > _mapping;
753
};
754
755
756
757
#define MAX_IMPORTANT_NODES 8
758
#define MAX_SPECIALCARE_NODES 4
759
typedef bool (* TransformerPtr)(TR_CISCTransformer *);
760
typedef bool (* SpecialNodeTransformerPtr)(TR_CISCTransformer *);
761
class TR_CISCGraph
762
{
763
public:
764
TR_ALLOC(TR_Memory::LoopTransformer);
765
766
static void setEssentialNodes(TR_CISCGraph*);
767
static void makePreparedCISCGraphs(TR::Compilation *c);
768
static void initializeGraphs(TR::Compilation *c);
769
770
TR_CISCGraph(TR_Memory * m, const char *title = 0, int32_t numHashTrNode = 31, int32_t numHashOpc = 17)
771
: _titleOfCISC(title), _entryNode(0), _exitNode(0), _numNodes(0), _numDagIds(0),
772
_dagId2Nodes(0), _transformer(0), _specialNodeTransformer(0), _hotness(noOpt),
773
_javaSource(0), _versionLength(0), _trMemory(m),
774
_trNode2CISCNode(m), _opc2CISCNode(m), _nodes(m), _orderByData(m),
775
_duplicatorNodes(m), _patternType(-1)
776
{
777
initializeLists();
778
_flags.clear();
779
_aspects.init();
780
if (numHashTrNode > 0) _trNode2CISCNode.setNumBuckets(numHashTrNode);
781
if (numHashOpc > 0) _opc2CISCNode.setNumBuckets(numHashOpc);
782
int32_t i;
783
for (i = MAX_IMPORTANT_NODES; --i >= 0; ) _importantNode[i] = 0;
784
for (i = MAX_SPECIALCARE_NODES; --i >= 0; ) _specialCareNode[i] = 0;
785
}
786
787
TR_CISCNode *getCISCNode(TR::Node *n) { return _trNode2CISCNode.find(getHashKeyTrNode(n)); }
788
TR_CISCNode *getCISCNode(uint32_t opc, bool validOther, int32_t other)
789
{
790
return _opc2CISCNode.find(getHashKeyOpcs(opc, validOther, other));
791
}
792
793
void setEntryNode(TR_CISCNode *n) {_entryNode = n;}
794
TR_CISCNode *getEntryNode() {return _entryNode;}
795
796
void setExitNode(TR_CISCNode *n) {_exitNode = n;}
797
TR_CISCNode *getExitNode() {return _exitNode;}
798
799
void setImportantNode(uint32_t idx, TR_CISCNode *n)
800
{
801
TR_ASSERT(idx < MAX_IMPORTANT_NODES, "TR_CISCGraph::setImportantNode index out of range");
802
_importantNode[idx] = n;
803
}
804
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2)
805
{
806
setImportantNode(0, n1);
807
setImportantNode(1, n2);
808
}
809
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3)
810
{
811
setImportantNode(0, n1);
812
setImportantNode(1, n2);
813
setImportantNode(2, n3);
814
}
815
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3, TR_CISCNode *n4)
816
{
817
setImportantNode(0, n1);
818
setImportantNode(1, n2);
819
setImportantNode(2, n3);
820
setImportantNode(3, n4);
821
}
822
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3, TR_CISCNode *n4, TR_CISCNode *n5)
823
{
824
setImportantNode(0, n1);
825
setImportantNode(1, n2);
826
setImportantNode(2, n3);
827
setImportantNode(3, n4);
828
setImportantNode(4, n5);
829
}
830
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3, TR_CISCNode *n4, TR_CISCNode *n5, TR_CISCNode *n6)
831
{
832
setImportantNode(0, n1);
833
setImportantNode(1, n2);
834
setImportantNode(2, n3);
835
setImportantNode(3, n4);
836
setImportantNode(4, n5);
837
setImportantNode(5, n6);
838
}
839
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3, TR_CISCNode *n4, TR_CISCNode *n5, TR_CISCNode *n6, TR_CISCNode *n7)
840
{
841
setImportantNode(0, n1);
842
setImportantNode(1, n2);
843
setImportantNode(2, n3);
844
setImportantNode(3, n4);
845
setImportantNode(4, n5);
846
setImportantNode(5, n6);
847
setImportantNode(6, n7);
848
}
849
void setImportantNodes(TR_CISCNode *n1, TR_CISCNode *n2, TR_CISCNode *n3, TR_CISCNode *n4, TR_CISCNode *n5, TR_CISCNode *n6, TR_CISCNode *n7, TR_CISCNode *n8)
850
{
851
setImportantNode(0, n1);
852
setImportantNode(1, n2);
853
setImportantNode(2, n3);
854
setImportantNode(3, n4);
855
setImportantNode(4, n5);
856
setImportantNode(5, n6);
857
setImportantNode(6, n7);
858
setImportantNode(7, n8);
859
}
860
TR_CISCNode *getImportantNode(uint32_t idx)
861
{
862
TR_ASSERT(idx < MAX_IMPORTANT_NODES, "TR_CISCGraph::getImportantNode index out of range");
863
return _importantNode[idx];
864
}
865
866
void setSpecialCareNode(uint32_t idx, TR_CISCNode *n)
867
{
868
TR_ASSERT(idx < MAX_SPECIALCARE_NODES, "TR_CISCGraph::setSpecialCareNode index out of range");
869
_specialCareNode[idx] = n;
870
}
871
TR_CISCNode *getSpecialCareNode(uint32_t idx)
872
{
873
TR_ASSERT(idx < MAX_SPECIALCARE_NODES, "TR_CISCGraph::getSpecialCareNode index out of range");
874
return _specialCareNode[idx];
875
}
876
877
TR_Memory * trMemory() { return _trMemory; }
878
879
uint16_t getNumNodes() {return _numNodes;}
880
uint16_t incNumNodes() {return _numNodes++;}
881
882
uint16_t getNumDagIds() {return _numDagIds;}
883
void setNumDagIds(uint16_t n) {_numDagIds = n;}
884
885
TR_CISCNode *getHeadOfNodes()
886
{
887
return _nodes.isEmpty() ? 0 : _nodes.getListHead()->getData();
888
}
889
void addTrNode(TR_CISCNode *n, TR::Block *block, TR::TreeTop *top, TR::Node *trNode);
890
virtual void addNode(TR_CISCNode *n, TR::Block *block = 0, TR::TreeTop *top = 0, TR::Node *trNode = 0);
891
892
void createInternalData(int32_t loopBodyDagId)
893
{
894
createDagId2NodesTable();
895
createOrderByData();
896
setOutsideOfLoopFlag(loopBodyDagId);
897
}
898
899
bool isDagIdCycle(uint16_t dagId) { TR_ASSERT(dagId < _numDagIds, "error"); return getDagId2Nodes()[dagId].isMultipleEntry(); }
900
bool isDagIdDag(uint16_t dagId) { TR_ASSERT(dagId < _numDagIds, "error"); return getDagId2Nodes()[dagId].isSingleton(); }
901
void dump(TR::FILE *pOutFile, TR::Compilation *);
902
903
void importUDchains(TR::Compilation *comp, TR_UseDefInfo *useDefInfo, bool reinitialize = false);
904
905
void setTransformer(TransformerPtr t) { _transformer = t; }
906
TransformerPtr getTransformer() { return _transformer; }
907
bool isPatternGraph() { return _transformer != 0; }
908
909
void setSpecialNodeTransformer(SpecialNodeTransformerPtr t) { _specialNodeTransformer = t; }
910
SpecialNodeTransformerPtr getSpecialNodeTransformer() { return _specialNodeTransformer; }
911
912
// flags
913
bool isSetUDDUchains() { return _flags.testAny(_isSetUDDUchains); }
914
void setIsSetUDDUchains(bool v = true) { _flags.set(_isSetUDDUchains, v); }
915
bool isInhibitAfterVersioning() { TR_ASSERT(isPatternGraph(), "error"); return _flags.testAny(_inhibitAfterVersioning); }
916
void setInhibitAfterVersioning(bool v = true) { TR_ASSERT(isPatternGraph(), "error"); _flags.set(_inhibitAfterVersioning, v); }
917
bool isInhibitBeforeVersioning() { TR_ASSERT(isPatternGraph(), "error"); return _flags.testAny(_inhibitBeforeVersioning); }
918
void setInhibitBeforeVersioning(bool v = true) { TR_ASSERT(isPatternGraph(), "error"); _flags.set(_inhibitBeforeVersioning, v); }
919
bool isInsideOfFastVersioned() { TR_ASSERT(!isPatternGraph(), "error"); return _flags.testAny(_insideOfFastVersioned); }
920
void setInsideOfFastVersioned(bool v = true) { TR_ASSERT(!isPatternGraph(), "error"); _flags.set(_insideOfFastVersioned, v); }
921
bool isRequireAHconst() { TR_ASSERT(isPatternGraph(), "error"); return _flags.testAny(_requireAHconst); }
922
void setRequireAHconst(bool v = true) { TR_ASSERT(isPatternGraph(), "error"); _flags.set(_requireAHconst, v); }
923
bool isHighFrequency() { return _flags.testAny(_highFrequency); }
924
void setHighFrequency(bool v = true) { _flags.set(_highFrequency, v); }
925
bool isNoFragmentDagId() { return _flags.testAny(_noFragmentDagId); }
926
void setNoFragmentDagId(bool v = true) { _flags.set(_noFragmentDagId, v); }
927
bool isRecordingAspectsByOpcode() { return _flags.testAny(_recordingAspectsByOpcode); }
928
void setRecordingAspectsByOpcode(bool v = true) { _flags.set(_recordingAspectsByOpcode, v); }
929
930
bool needsInductionVariableInit() { return _flags.testAny(_needsInductionVariableInit); }
931
void setNeedsInductionVariableInit(bool v = false) { _flags.set(_needsInductionVariableInit, v); }
932
933
enum // flag bits
934
{
935
_isSetUDDUchains = 0x0001,
936
_inhibitAfterVersioning = 0x0002, // for compilation time reduction
937
_inhibitBeforeVersioning = 0x0004, // for compilation time reduction
938
_insideOfFastVersioned = _inhibitAfterVersioning,
939
_highFrequency = 0x0008,
940
_noFragmentDagId = 0x0010,
941
_recordingAspectsByOpcode = 0x0020,
942
_requireAHconst = 0x0040,
943
_needsInductionVariableInit = 0x0080,
944
_dummyEnum
945
};
946
947
void initializeLists()
948
{
949
_nodes.init();
950
_orderByData.init();
951
}
952
953
List<TR_CISCNode> *getNodes() { return &_nodes; }
954
List<TR_CISCNode> *getDagId2Nodes() { return _dagId2Nodes; }
955
List<TR_CISCNode> *getOrderByData() { return &_orderByData; }
956
ListOfCISCNodeDuplicator *getDuplicatorNodes() { return &_duplicatorNodes; }
957
virtual void createDagId2NodesTable();
958
virtual void createOrderByData();
959
const char *getTitle() { return _titleOfCISC; }
960
void setMemAspects(uint32_t load, uint32_t store)
961
{
962
_aspects.setLoadAspects(load);
963
_aspects.setStoreAspects(store);
964
}
965
void setAspects(uint32_t val) { _aspects.set(val); }
966
void setAspects(uint32_t val, uint32_t load, uint32_t store)
967
{
968
setAspects(val);
969
setMemAspects(load, store);
970
}
971
uint32_t getAspectsValue() { return _aspects.getValue(); }
972
bool testAllAspects(TR_CISCGraph *P) { return _aspects.testAll(P->getAspectsValue()); }
973
void modifyTargetGraphAspects() { _aspects.modifyAspects(); }
974
975
void setNoMemAspects(uint32_t load, uint32_t store)
976
{
977
_noaspects.setLoadAspects(load, false);
978
_noaspects.setStoreAspects(store, false);
979
}
980
void setNoAspects(uint32_t val) { _noaspects.set(val); }
981
void setNoAspects(uint32_t val, uint32_t load, uint32_t store)
982
{
983
setNoAspects(val);
984
setNoMemAspects(load, store);
985
}
986
uint32_t getNoAspectsValue() { return _noaspects.getValue(); }
987
bool testAnyNoAspects(TR_CISCGraph *P) { return _aspects.testAny(P->getNoAspectsValue()); }
988
989
TR_Hotness getHotness() { return _hotness; }
990
void setHotness(TR_Hotness hotness) { _hotness = hotness; }
991
void setHotness(TR_Hotness hotness, bool highFreq) { setHotness(hotness); setHighFrequency(highFreq); }
992
int32_t defragDagId();
993
void setJavaSource(char *s) { _javaSource = s; }
994
char *getJavaSource() { return _javaSource; }
995
TR_CISCGraphAspectsWithCounts * getAspects() { return &_aspects; }
996
void setMinCounts(uint8_t ifCount, uint8_t iloadCount, uint8_t istoreCount) { _aspects.setMinCounts(ifCount,iloadCount,istoreCount);}
997
bool meetMinCounts(TR_CISCGraph *p) { return _aspects.meetMinCounts(&p->_aspects); }
998
uint16_t getVersionLength() { return _versionLength; }
999
void setVersionLength(uint16_t len) { _versionLength = len; }
1000
void setListsDuplicator()
1001
{
1002
_duplicatorNodes.setList(&_nodes);
1003
_duplicatorNodes.setDuplicateElement();
1004
}
1005
void duplicateListsDuplicator()
1006
{
1007
_duplicatorNodes.duplicateList();
1008
}
1009
void restoreListsDuplicator()
1010
{
1011
_nodes.setListHead(_duplicatorNodes.getList()->getListHead());
1012
if (_duplicatorNodes.isDuplicated())
1013
{
1014
createOrderByData();
1015
createDagId2NodesTable();
1016
_entryNode = _duplicatorNodes.findCorrespondingNode(_entryNode);
1017
_exitNode = _duplicatorNodes.findCorrespondingNode(_exitNode);
1018
}
1019
}
1020
TR_CISCNode *searchStore(TR_CISCNode *target, TR_CISCNode *to);
1021
1022
int32_t getPatternType() { return _patternType; }
1023
void setPatternType(int32_t v) { _patternType = v; }
1024
1025
protected:
1026
uint64_t getHashKeyTrNode(TR::Node *n) { return ((uintptr_t)n) >> 2; }
1027
uint64_t getHashKeyOpcs(uint32_t opc, bool validOtherInfo, uint32_t otherInfo)
1028
{
1029
return (((uint64_t)(opc << 1) | (uint64_t)(validOtherInfo ? 1 : 0)) << 32) ^ (uint64_t)otherInfo;
1030
}
1031
bool addTrNode2CISCNode(TR::Node *n, TR_CISCNode *c)
1032
{
1033
return _trNode2CISCNode.add(getHashKeyTrNode(n), c, true);
1034
}
1035
void addOpc2CISCNode(TR_CISCNode *c);
1036
bool addOpc2CISCNode(uint32_t opc, bool valid, int32_t other, TR_CISCNode *c)
1037
{
1038
return _opc2CISCNode.add(getHashKeyOpcs(opc, valid, other), c, true);
1039
}
1040
void setOutsideOfLoopFlag(uint16_t loopBodyDagId);
1041
const char *_titleOfCISC; // title for debug message
1042
1043
TR_Memory * _trMemory;
1044
TransformerPtr _transformer;
1045
SpecialNodeTransformerPtr _specialNodeTransformer;
1046
TR_CISCNode *_entryNode;
1047
TR_CISCNode *_exitNode;
1048
TR_CISCNode *_importantNode[MAX_IMPORTANT_NODES];
1049
TR_CISCNode *_specialCareNode[MAX_SPECIALCARE_NODES];
1050
TR_CISCHash _trNode2CISCNode;
1051
TR_CISCHash _opc2CISCNode;
1052
TR_CISCGraphAspectsWithCounts _aspects;
1053
TR_CISCGraphAspects _noaspects;
1054
TR_Hotness _hotness;
1055
uint16_t _numNodes;
1056
uint16_t _numDagIds;
1057
flags16_t _flags;
1058
uint16_t _versionLength;
1059
1060
List<TR_CISCNode> _nodes;
1061
List<TR_CISCNode> *_dagId2Nodes;
1062
List<TR_CISCNode> _orderByData;
1063
ListOfCISCNodeDuplicator _duplicatorNodes;
1064
char *_javaSource; // corresponding Java code to assist programmers
1065
int32_t _patternType;
1066
};
1067
1068
1069
class TR_PCISCGraph : public TR_CISCGraph
1070
{
1071
public:
1072
TR_PCISCGraph(TR_Memory * m, const char *title = 0, int32_t numHashTrNode = 31, int32_t numHashOpc = 17)
1073
: TR_CISCGraph(m, title, 0, 0)
1074
{
1075
if (numHashTrNode > 0) _trNode2CISCNode.setNumBuckets(numHashTrNode, persistentAlloc);
1076
if (numHashOpc > 0) _opc2CISCNode.setNumBuckets(numHashOpc, persistentAlloc);
1077
};
1078
virtual void createDagId2NodesTable();
1079
virtual void createOrderByData();
1080
virtual void addNode(TR_CISCNode *n, TR::Block *block = 0, TR::TreeTop *top = 0, TR::Node *trNode = 0);
1081
};
1082
1083
1084
/*********** FOR OPTIMIZATION ************/
1085
class TR_CISCNodeRegion : public ListHeadAndTail<TR_CISCNode>
1086
{
1087
private:
1088
flags16_t _flags;
1089
TR_BitVector _bv;
1090
int32_t _bvnum;
1091
1092
public:
1093
1094
TR_ALLOC(TR_Memory::LLList)
1095
1096
TR_CISCNodeRegion(int32_t bvnum, TR::Region &region) : ListHeadAndTail<TR_CISCNode>(region) { init(bvnum, region); }
1097
//void init() {ListHeadAndTail<TR_CISCNode>::init(); _flags.clear();}
1098
1099
void init(int32_t bvnum, TR::Region &region)
1100
{ListHeadAndTail<TR_CISCNode>::init(); _flags.clear(); _bvnum = bvnum; _bv.init(bvnum, region);}
1101
// flags
1102
bool isIncludeEssentialNode() { return _flags.testAny(_isIncludeEssentialNode); }
1103
void setIncludeEssentialNode(bool v = true) { _flags.set(_isIncludeEssentialNode, v); }
1104
bool isOptionalNode() { return _flags.testAny(_isOptionalNode); }
1105
void setIsOptionalNode(bool v = true) { _flags.set(_isOptionalNode, v); }
1106
1107
enum // flag bits
1108
{
1109
_isIncludeEssentialNode = 0x0001,
1110
_isOptionalNode = 0x0002,
1111
_dummyEnum
1112
};
1113
1114
bool isIncluded(int32_t id) { return _bv.isSet(id); }
1115
bool isIncluded(TR_CISCNode *n) { return _bv.isSet(n->getID()); }
1116
1117
ListElement<TR_CISCNode> *add(TR_CISCNode *p)
1118
{
1119
if (p->isEssentialNode()) setIncludeEssentialNode();
1120
if (p->isOptionalNode()) setIsOptionalNode();
1121
_bv.set(p->getID());
1122
return ListHeadAndTail<TR_CISCNode>::add(p);
1123
}
1124
1125
ListElement<TR_CISCNode> *append(TR_CISCNode *p)
1126
{
1127
if (p->isEssentialNode()) setIncludeEssentialNode();
1128
if (p->isOptionalNode()) setIsOptionalNode();
1129
_bv.set(p->getID());
1130
return ListHeadAndTail<TR_CISCNode>::append(p);
1131
}
1132
1133
TR_CISCNodeRegion *clone();
1134
};
1135
1136
1137
class TR_CFGReversePostOrder
1138
{
1139
public:
1140
TR_ALLOC(TR_Memory::LoopTransformer);
1141
1142
TR_CFGReversePostOrder(TR_Memory * m) : _revPost(m) { }
1143
1144
List<TR::CFGNode> *compute( TR::CFG *cfg);
1145
void createReversePostOrder(TR::CFG *cfg, TR::CFGNode *n);
1146
void dump(TR::Compilation * comp);
1147
//void initReversePostOrder();
1148
//void initReversePostOrder(TR::CFG *cfg);
1149
//void createReversePostOrderRec(TR::CFGNode *n);
1150
1151
protected:
1152
struct TR_StackForRevPost : public TR_Link<TR_StackForRevPost>
1153
{
1154
TR::CFGNode *n;
1155
// ListElement<TR::CFGEdge> *le;
1156
TR::CFGEdgeList::iterator le;
1157
};
1158
1159
ListHeadAndTail<TR::CFGNode> _revPost;
1160
// TR::CFG *_cfg;
1161
//TR_BitVector _visited;
1162
};
1163
1164
1165
class TR_CISCCandidate
1166
{
1167
public:
1168
TR_ALLOC(TR_Memory::LoopTransformer);
1169
1170
TR_CISCCandidate(TR_Memory * m) : _listIdioms(m) { init(); }
1171
void init()
1172
{
1173
_minBCIndex = 0x7fffffff;
1174
_maxBCIndex = -_minBCIndex;
1175
_minLineNumber = 0x7fffffff;
1176
_maxLineNumber = -_minBCIndex;
1177
_listIdioms.init();
1178
}
1179
void add(TR_CISCGraph *idiom, int32_t minBC, int32_t maxBC, int32_t minLN, int32_t maxLN)
1180
{
1181
_listIdioms.add(idiom);
1182
if (_minBCIndex > minBC) _minBCIndex = minBC;
1183
if (_maxBCIndex < maxBC) _maxBCIndex = maxBC;
1184
if (_minLineNumber > minLN) _minLineNumber = minLN;
1185
if (_maxLineNumber < maxLN) _maxLineNumber = maxLN;
1186
}
1187
int32_t getMinBCIndex() { return _minBCIndex; }
1188
int32_t getMaxBCIndex() { return _maxBCIndex; }
1189
int32_t getMinLineNumber() { return _minLineNumber; }
1190
int32_t getMaxLineNumber() { return _maxLineNumber; }
1191
List<TR_CISCGraph> *getListIdioms() { return &_listIdioms; }
1192
1193
protected:
1194
int32_t _minBCIndex;
1195
int32_t _maxBCIndex;
1196
int32_t _minLineNumber;
1197
int32_t _maxLineNumber;
1198
List<TR_CISCGraph> _listIdioms;
1199
};
1200
1201
1202
class TR_NodeDuplicator
1203
{
1204
public:
1205
TR_ALLOC(TR_Memory::LoopTransformer);
1206
1207
TR_NodeDuplicator(TR::Compilation * comp) : _list(comp->trMemory()), _comp(comp) { init(); }
1208
1209
TR::Compilation * comp() { return _comp; }
1210
1211
TR_HeapMemory trHeapMemory() { return _comp->trMemory(); }
1212
1213
void init() { _list.init(); }
1214
TR::Node *duplicateTree(TR::Node *org);
1215
1216
protected:
1217
TR::Node *restructureTree(TR::Node *oldTree, TR::Node *newTree);
1218
List<TR_Pair<TR::Node,TR::Node> > _list;
1219
1220
private:
1221
TR::Compilation * _comp;
1222
};
1223
1224
1225
class TR_UseTreeTopMap
1226
{
1227
public:
1228
TR_ALLOC(TR_Memory::LoopTransformer);
1229
1230
TR_UseTreeTopMap(TR::Compilation * comp, TR::Optimizer * optimizer);
1231
TR_HashTabInt _useToParentMap; // lists of owning treetops indexed by use index
1232
int32_t buildAllMap();
1233
void buildUseTreeTopMap(TR::TreeTop* treeTop,TR::Node *node);
1234
TR::TreeTop * findParentTreeTop(TR::Node *useNode);
1235
TR::Compilation *comp() { return _compilation; }
1236
1237
protected:
1238
bool _buildAllMap;
1239
TR::Compilation *_compilation;
1240
TR::Optimizer *_optimizer;
1241
TR_UseDefInfo *_info;
1242
};
1243
1244
1245
typedef enum
1246
{
1247
_T2P_NULL = 0,
1248
_T2P_NotMatch = 1,
1249
_T2P_MatchMask = 2,
1250
_T2P_Single = 4,
1251
_T2P_Multiple = 8,
1252
_T2P_MatchAndSingle = _T2P_MatchMask | _T2P_Single, // Match and T2P is single
1253
_T2P_MatchAndMultiple = _T2P_MatchMask | _T2P_Multiple, // Match and T2P is multiple
1254
} CISCT2PCond;
1255
1256
class TR_CISCTransformer : public TR_LoopTransformer
1257
{
1258
public:
1259
static void showCISCNodeRegion(TR_CISCNodeRegion *region, TR::Compilation * );
1260
static void showCISCNodeRegions(List<TR_CISCNodeRegion> *regions, TR::Compilation * );
1261
static TR::Block *getSuccBlockIfSingle(TR::Block *block);
1262
static bool searchNodeInTrees(TR::Node *top, TR::Node *target, TR::Node **retParent = NULL, int *retChildNum = NULL);
1263
static bool compareTrNodeTree(TR::Node *a, TR::Node *b);
1264
static bool compareBlockTrNodeTree(TR::Block *a, TR::Block *b);
1265
bool getBCIndexMinMax(List<TR_CISCNode> *l, int32_t *minIndex, int32_t *maxIndex, int32_t *_minLN, int32_t *_maxLN, bool allowInlined);
1266
1267
TR_CISCTransformer(TR::OptimizationManager *manager);
1268
static TR::Optimization *create(TR::OptimizationManager *manager)
1269
{
1270
return new (manager->allocator()) TR_CISCTransformer(manager);
1271
}
1272
1273
void easyTreeSimplification(TR::Node *const node);
1274
TR_CISCNode *addAllSubNodes(TR_CISCGraph *const graph, TR::Block *const block, TR::TreeTop *const top, TR::Node *const parent, TR::Node *const node, const int32_t dagId);
1275
bool makeCISCGraphForBlock(TR_CISCGraph *graph, TR::Block *const block, int32_t dagId);
1276
void resolveBranchTargets(TR_CISCGraph *graph, TR_CISCNode *);
1277
uint16_t renumberDagId(TR_CISCGraph *graph, int32_t tempMaxDagId, int32_t bodyDagId);
1278
TR_CISCGraph *makeCISCGraph(List<TR::Block> *pred, List<TR::Block> *body, List<TR::Block> *succ);
1279
1280
struct TR_BitsKeepAliveInfo
1281
{
1282
TR_ALLOC(TR_Memory::LoopTransformer);
1283
1284
TR_BitsKeepAliveInfo(TR::Block * block, TR::TreeTop *treeTop, TR::TreeTop *prevTreeTop):
1285
_block(block), _treeTop(treeTop), _prevTreeTop(prevTreeTop)
1286
{}
1287
1288
TR::Block *_block;
1289
TR::TreeTop *_treeTop;
1290
TR::TreeTop *_prevTreeTop;
1291
};
1292
1293
bool removeBitsKeepAliveCalls(List<TR::Block> *body);
1294
void insertBitsKeepAliveCalls(TR::Block * block);
1295
void restoreBitsKeepAliveCalls();
1296
1297
virtual int32_t perform();
1298
virtual const char * optDetailString() const throw();
1299
1300
bool createLoopCandidates(List<TR_RegionStructure> *ret);
1301
TR::Block * findPredecessorBlockOfLoopEntry(TR_RegionStructure *loop);
1302
TR::Block *addPreHeaderIfNeeded(TR_RegionStructure *loop);
1303
1304
bool computeTopologicalEmbedding(TR_CISCGraph *P, TR_CISCGraph *T);
1305
bool embeddingHasConflictingBranches();
1306
void showEmbeddedData(char *title, uint8_t *data);
1307
bool computeEmbeddedForData();
1308
bool computeEmbeddedForCFG();
1309
bool dagEmbed(TR_CISCNode *, TR_CISCNode*);
1310
bool cycleEmbed(uint16_t, uint16_t);
1311
bool checkParents(TR_CISCNode *p, TR_CISCNode *t, uint8_t *result, bool *inLoop, bool *optionalParents);
1312
bool makeLists();
1313
int32_t analyzeConnectionOnePairChild(TR_CISCNode *const p, TR_CISCNode *const t, TR_CISCNode *const pn, TR_CISCNode *tn);
1314
void analyzeConnectionOnePair(TR_CISCNode *const p, TR_CISCNode *const t);
1315
void analyzeConnection();
1316
void analyzeArrayHeaderConst();
1317
void showT2P();
1318
TR_CISCNodeRegion* extractMatchingRegion();
1319
bool findFirstNode(TR::TreeTop **retTree, TR::Node **retNode, TR::Block **retBlock);
1320
int countP2T(TR_CISCNode *p, bool inLoop = false);
1321
TR_CISCNode *getP2TRep(TR_CISCNode *p);
1322
TR_CISCNode *getP2TRepInLoop(TR_CISCNode *p, TR_CISCNode *exclude = NULL);
1323
TR_CISCNode *getP2TInLoopIfSingle(TR_CISCNode *p);
1324
TR_CISCNode *getP2TInLoopAllowOptionalIfSingle(TR_CISCNode *p);
1325
bool verifyCandidate();
1326
void addEdge(TR::CFGEdgeList *succList, TR::Block *, TR::Block *);
1327
void removeEdge(List<TR::CFGEdge> *succList, TR::Block *, TR::Block *);
1328
void removeEdgesExceptFor(TR::CFGEdgeList *succList, TR::Block *, TR::Block *);
1329
void setEdge(TR::CFGEdgeList *succList, TR::Block *, TR::Block *);
1330
TR::Block *analyzeSuccessorBlock(TR::Node *ignoreTree = 0);
1331
void setSuccessorEdge(TR::Block *block, TR::Block *target = 0);
1332
void setEdges(TR::CFGEdgeList *succList, TR::Block *, TR::Block *, TR::Block *);
1333
TR::Block *searchOtherBlockInSuccBlocks(TR::Block *target0, TR::Block *target1);
1334
TR::Block *searchOtherBlockInSuccBlocks(TR::Block *target0);
1335
TR::Block *setSuccessorEdges(TR::Block *block, TR::Block *target, TR::Block *);
1336
TR::TreeTop *removeAllNodes(TR::TreeTop *start, TR::TreeTop *end);
1337
void initTopologicalEmbedding()
1338
{
1339
_beforeInsertions.init();
1340
_afterInsertions.init();
1341
_afterInsertionsIdiom[0].init();
1342
_afterInsertionsIdiom[1].init();
1343
_offsetOperand1 = 0;
1344
_offsetOperand2 = 0;
1345
}
1346
TR::Block *insertBeforeNodes(TR::Block *block);
1347
TR::Block *insertAfterNodes(TR::Block *block, List<TR::Node> *l, bool prepend = false);
1348
TR::Block *insertAfterNodes(TR::Block *block, bool prepend = false);
1349
TR::Block *insertAfterNodesIdiom(TR::Block *block, int32_t pos, bool prepend = false);
1350
TR::Node *findStoreToSymRefInInsertBeforeNodes(int32_t symRefNumberToBeMatched);
1351
bool areAllNodesIncluded(TR_CISCNodeRegion *r);
1352
1353
inline uint32_t idx(uint32_t a, uint32_t x) { return (a * _numTNodes) + x; }
1354
1355
TR_CISCGraph *getP() { return _P; }
1356
TR_CISCGraph *getT() { return _T; }
1357
List<TR_CISCNode> *getP2T() { return _P2T; }
1358
List<TR_CISCNode> *getT2P() { return _T2P; }
1359
TR_CISCNode *getT2PheadRep(int32_t tid)
1360
{
1361
List<TR_CISCNode> *l = _T2P + tid;
1362
return l->isEmpty() ? 0 : l->getListHead()->getData();
1363
}
1364
TR_CISCNode *getT2PheadRep(TR_CISCNode *t) {return getT2PheadRep(t->getID());}
1365
TR_CISCNode *getT2Phead(int32_t tid)
1366
{
1367
TR_ASSERT(!_T2P[tid].isMultipleEntry(), "maybe error");
1368
return getT2PheadRep(tid);
1369
}
1370
TR_CISCNode *getT2Phead(TR_CISCNode *t) {return getT2Phead(t->getID());}
1371
bool isGenerateI2L() { return _isGenerateI2L; }
1372
bool showMesssagesStdout() { return _showMesssagesStdout; }
1373
TR_CISCNodeRegion *getCandidateRegion() { return _candidateRegion; }
1374
bool analyzeBoolTable(TR_BitVector **bv, TR::TreeTop **retTreeTop, TR_CISCNode *boolTable,
1375
TR_BitVector *defBV, TR_CISCNode *defNode,
1376
TR_CISCNode *ignoreNode,
1377
int32_t bvoffset, int32_t allocBVSize);
1378
int32_t analyzeByteBoolTable(TR_CISCNode *booltable, uint8_t *table256, TR_CISCNode *ignoreNode = 0, TR::TreeTop **retSameExit = 0);
1379
int32_t analyzeCharBoolTable(TR_CISCNode *booltable, uint8_t *table65536, TR_CISCNode *ignoreNode = 0, TR::TreeTop **retSameExit = 0);
1380
bool isEmptyBeforeInsertionList() { return _beforeInsertions.isEmpty(); }
1381
ListHeadAndTail<TR::Node> *getBeforeInsertionList() { return &_beforeInsertions; }
1382
bool isEmptyAfterInsertionList() { return _afterInsertions.isEmpty(); }
1383
ListHeadAndTail<TR::Node> *getAfterInsertionList() { return &_afterInsertions; }
1384
bool isEmptyAfterInsertionIdiomList(int32_t pos) { return _afterInsertionsIdiom[pos].isEmpty(); }
1385
ListHeadAndTail<TR::Node> *getAfterInsertionIdiomList(int32_t pos) { TR_ASSERT(pos < 2, "error"); return _afterInsertionsIdiom+pos; }
1386
bool alignTopOfRegion(TR_CISCNodeRegion *r);
1387
static bool isInsideOfFastVersionedLoop(TR_RegionStructure *l);
1388
void setColdLoopBody();
1389
void analyzeHighFrequencyLoop(TR_CISCGraph *graph, TR_RegionStructure *naturalLoop);
1390
int32_t getNumOfBBlistPred() { return _bblistPred.getSize(); }
1391
int32_t getNumOfBBlistBody() { return _bblistBody.getSize(); }
1392
int32_t getNumOfBBlistSucc() { return _bblistSucc.getSize(); }
1393
bool isBlockInLoopBody(TR::Block *b);
1394
int16_t getOffsetOperand1() { return _offsetOperand1; }
1395
int16_t getOffsetOperand2() { return _offsetOperand2; }
1396
void setOffsetOperand1(int16_t v) { _offsetOperand1 = v; }
1397
void setOffsetOperand2(int16_t v) { _offsetOperand2 = v; }
1398
1399
CISCT2PCond analyzeT2P(TR_CISCNode *t, TR_CISCNode *p = 0);
1400
1401
enum
1402
{
1403
_Unknown = 0, // the pair (p, t) is not processed yet.
1404
_NotEmbed = 0x1, // the status when the other four status are not satisfied
1405
_Desc = (_NotEmbed | 0x2), // there is the _Embed status within a pair (p, a descendent of t).
1406
_Cond = 4, // (1) the labels of p and t are equivalent but (2) all children of p and t are not processed yet.
1407
_Embed = (_Desc | 0x4) // (1) the labels of p and t are equivalent and (2) descendents of t include all children of p.
1408
};
1409
static inline bool isDescOrEmbed(uint8_t status) { return ((status & _Desc) == _Desc); } // Assume _Desc=3 and _Embed=7
1410
1411
void setFlag1(bool v = true) { _flagsForTransformer.set(_flag1, v); }
1412
bool isFlag1() { return _flagsForTransformer.testAny(_flag1); }
1413
void setFlag2(bool v = true) { _flagsForTransformer.set(_flag2, v); }
1414
bool isFlag2() { return _flagsForTransformer.testAny(_flag2); }
1415
void setFlag3(bool v = true) { _flagsForTransformer.set(_flag3, v); }
1416
bool isFlag3() { return _flagsForTransformer.testAny(_flag3); }
1417
void setFlag4(bool v = true) { _flagsForTransformer.set(_flag4, v); }
1418
bool isFlag4() { return _flagsForTransformer.testAny(_flag4); }
1419
void resetFlags() { _flagsForTransformer.reset(_maskForFlagsPtr); }
1420
void setIsInitializeNegative128By1(bool v = true) { setFlag1(v); }
1421
bool isInitializeNegative128By1() { return isFlag1(); }
1422
void setTableBackedByRawStorage(bool v = true) { setFlag1(v); }
1423
bool isTableBackedByRawStorage() { return isFlag1(); }
1424
void setCompareTo(bool v = true) { setFlag1(v); }
1425
bool isCompareTo() { return isFlag1(); }
1426
void setIndexOf(bool v = true) { setFlag2(v); }
1427
bool isIndexOf() { return isFlag2(); }
1428
void setMEMCPYDec(bool v = true) { setFlag1(v); }
1429
bool isMEMCPYDec() { return isFlag1(); }
1430
bool isAfterVersioning() { return manager()->numPassesCompleted() > 0; }
1431
void setShowingCandidates(bool v = true) { _flagsForTransformer.set(_isShowingCandidates, v); }
1432
bool isShowingCandidates() { return _flagsForTransformer.testAny(_isShowingCandidates); }
1433
void setFirstTime(bool v = true) { _flagsForTransformer.set(_isFirstTime, v); }
1434
bool isFirstTime() { return _flagsForTransformer.testAny(_isFirstTime); }
1435
void setConverged(bool v = true) { _flagsForTransformer.set(_isConverged, v); }
1436
bool isConverged() { return _flagsForTransformer.testAny(_isConverged); }
1437
enum // flag bits for _flagsForTransformer
1438
{
1439
_flag1 = 0x0001, // for TransformerPtr
1440
_flag2 = 0x0002, // for TransformerPtr
1441
_flag3 = 0x0004, // for TransformerPtr
1442
_flag4 = 0x0008, // for TransformerPtr
1443
_maskForFlagsPtr = _flag1|_flag2|_flag3|_flag4, // for TransformerPtr
1444
// UNUSED = 0x1000,
1445
_isShowingCandidates = 0x2000,
1446
_isFirstTime = 0x4000,
1447
_isConverged = 0x8000,
1448
_dummyEnum
1449
};
1450
TR_UseDefInfo *getUseDefInfo() { return _useDefInfo; }
1451
void showCandidates();
1452
void registerCandidates();
1453
void moveCISCNodesInList(List<TR_CISCNode> *l, TR_CISCNode *from, TR_CISCNode *to, TR_CISCNode *moveTo);
1454
void moveCISCNodes(TR_CISCNode *from, TR_CISCNode *to, TR_CISCNode *moveTo, char *debugStr = NULL);
1455
TR::Block *searchPredecessorOfBlock(TR::Block *block);
1456
TR::Block *modifyBlockByVersioningCheck(TR::Block *block, TR::TreeTop *startTop, TR::Node *lengthNode, List<TR::Node> *guardList = NULL);
1457
TR::Block *modifyBlockByVersioningCheck(TR::Block *block, TR::TreeTop *startTop, List<TR::Node> *guardList);
1458
TR::Block *cloneLoopBodyForPeel(TR::Block **firstBlock, TR::Block **lastBlock, TR_CISCNode *cmpifCISCNode = NULL);
1459
TR::Block *appendBlocks(TR::Block *block, TR::Block *firstBlock, TR::Block *lastBlock);
1460
bool isDeadStore(TR::Node *node);
1461
TR::Block *skipGoto(TR::Block *block, TR::Node *ignoreTree);
1462
bool analyzeOneArrayIndex(TR_CISCNode *arrayindex, TR::SymbolReference *tInductionVariable);
1463
bool analyzeArrayIndex(TR::SymbolReference *tInductionVariable);
1464
int32_t countGoodArrayIndex(TR::SymbolReference *tInductionVariable);
1465
bool simpleOptimization();
1466
uint64_t getHashValue(TR_CISCNodeRegion *);
1467
bool canConvertArrayCmpSign(TR::Node *storeNode, List<TR::TreeTop> *compareIfs, bool *canConvertToArrayCmp);
1468
1469
TR_RegionStructure *getCurrentLoop() { return _loopStructure; }
1470
void setCurrentLoop(TR_RegionStructure *loop) { _loopStructure = loop; }
1471
1472
private:
1473
List<TR::Block> _bblistPred;
1474
List<TR::Block> _bblistBody;
1475
List<TR::Block> _bblistSucc;
1476
List<TR_BitsKeepAliveInfo> _BitsKeepAliveList;
1477
1478
TR_CISCNodeRegion *_candidateRegion;
1479
TR_CISCCandidate _candidatesForShowing;
1480
List<TR_CISCNodeRegion> _candidatesForRegister;
1481
ListHeadAndTail<TR_CISCNode> *_candidateBBStartEnd;
1482
1483
TR_UseDefInfo *_useDefInfo;
1484
TR_CISCNode *_lastCFGNode; // just for working
1485
List<TR_CISCNode> _backPatchList; // just for working
1486
TR_UseTreeTopMap _useTreeTopMap;
1487
1488
// embedded information
1489
List<TR_CISCNode> *_P2T; // just for working
1490
List<TR_CISCNode> *_T2P; // just for working
1491
ListHeadAndTail<TR::Node> _beforeInsertions;
1492
ListHeadAndTail<TR::Node> _afterInsertions;
1493
ListHeadAndTail<TR::Node> * _afterInsertionsIdiom; // Idiom specific
1494
TR_RegionStructure *_loopStructure; // current loop being analyzed
1495
1496
uint16_t _sizeP2T;
1497
uint16_t _sizeT2P;
1498
uint16_t _numPNodes;
1499
uint16_t _numTNodes;
1500
uint16_t _sizeResult;
1501
uint16_t _sizeDE;
1502
int16_t _offsetOperand1;
1503
int16_t _offsetOperand2;
1504
flags16_t _flagsForTransformer;
1505
TR_CISCGraph *_P;
1506
TR_CISCGraph *_T;
1507
uint8_t *_embeddedForData; // result of data dependence
1508
uint8_t *_embeddedForCFG; // result of control flow graph
1509
uint8_t *_EM; // just for working
1510
uint8_t *_DE; // just for working
1511
bool _isGenerateI2L;
1512
bool _showMesssagesStdout;
1513
};
1514
1515
#endif
1516
1517