-
Notifications
You must be signed in to change notification settings - Fork 140
/
Copy pathOMRSimplifierHelpers.hpp
116 lines (105 loc) · 6.95 KB
/
OMRSimplifierHelpers.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
/*******************************************************************************
*
* (c) Copyright IBM Corp. 2000, 2016
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 and
* Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* Contributors:
* Multiple authors (IBM Corp.) - initial implementation and documentation
*******************************************************************************/
#ifndef OMR_SIMPLIFIERHELPERS_INCL
#define OMR_SIMPLIFIERHELPERS_INCL
#include "il/DataTypes.hpp" // for DataTypes
#include "il/ILOps.hpp" // for TR::ILOpCode, ILOpCode
namespace TR { class Block; }
namespace TR { class Compilation; }
namespace TR { class Node; }
namespace TR { class Optimization; }
namespace TR { class TreeTop; }
namespace TR { class Simplifier; }
class TR_RegionStructure;
class TR_FrontEnd;
enum {XXCMP_EQ = 0, XXCMP_LT = 1, XXCMP_GT = 2};
#define XXCMP_TABLE {0, -1, 1}
#define XXCMP_SIMPLIFIER(node, block, s, Type) \
{ \
simplifyChildren(node, block, s); \
TR::Node *firstChild = node->getFirstChild(); \
TR::Node *secondChild = node->getSecondChild(); \
int8_t table[3] = XXCMP_TABLE; \
if (firstChild == secondChild) \
foldByteConstant(node, table[XXCMP_EQ], s, true /* anchorChildren */); \
else if (firstChild->getOpCode().isLoadConst() && \
secondChild->getOpCode().isLoadConst()) \
{ \
if (firstChild->get##Type() > secondChild->get##Type()) \
foldByteConstant(node, table[XXCMP_GT], s, false /* !anchorChildren*/); \
else if (firstChild->get##Type() < secondChild->get##Type()) \
foldByteConstant(node, table[XXCMP_LT], s, false /* !anchorChildren*/); \
else if (firstChild->get##Type() == secondChild->get##Type()) \
foldByteConstant(node, table[XXCMP_EQ], s, false /* !anchorChildren*/); \
} \
}
//**************************************
// Binary identity operation
//
// If the second child is a constant that represents an identity operation,
// replace this node with the first child.
//
#define BINARY_IDENTITY_OP(Type,NullValue) \
if (secondChild->getOpCode().isLoadConst() && secondChild->get##Type() == NullValue) \
return s->replaceNode(node, firstChild, s->_curTree);
/*
* Helper functions needed by simplifier handlers across projects
*/
void simplifyChildren(TR::Node * node, TR::Block * block, TR::Simplifier * s);
bool performTransformationSimplifier(TR::Node * node, TR::Simplifier * s);
void setIsHighWordZero(TR::Node * node, TR::Simplifier * s);
TR::Node *_gotoSimplifier(TR::Node * node, TR::Block * block, TR::TreeTop* curTree, TR::Optimization * s);
void foldIntConstant(TR::Node * node, int32_t value, TR::Simplifier * s, bool anchorChildrenP);
void foldUIntConstant(TR::Node * node, uint32_t value, TR::Simplifier * s, bool anchorChildrenP);
void foldLongIntConstant(TR::Node * node, int64_t value, TR::Simplifier * s, bool anchorChildrenP);
void foldFloatConstant(TR::Node * node, float value, TR::Simplifier * s);
void foldDoubleConstant(TR::Node * node, double value, TR::Simplifier * s);
void foldByteConstant(TR::Node * node, int8_t value, TR::Simplifier * s, bool anchorChildrenP);
void foldShortIntConstant(TR::Node * node, int16_t value, TR::Simplifier * s, bool anchorChildrenP);
bool swapChildren(TR::Node * node, TR::Node * & firstChild, TR::Node * & secondChild, TR::Simplifier * s);
bool isExprInvariant(TR_RegionStructure *region, TR::Node *node);
void orderChildren(TR::Node * node, TR::Node * & firstChild, TR::Node * & secondChild, TR::Simplifier * s);
TR::Node *foldRedundantAND(TR::Node * node, TR::ILOpCodes andOpCode, TR::ILOpCodes constOpCode, int64_t andVal, TR::Simplifier * s);
bool branchToFollowingBlock(TR::Node * node, TR::Block * block, TR::Compilation *comp);
void makeConstantTheRightChild(TR::Node * node, TR::Node * & firstChild, TR::Node * & secondChild, TR::Simplifier * s);
void makeConstantTheRightChildAndSetOpcode(TR::Node * node, TR::Node * & firstChild, TR::Node * & secondChild, TR::Simplifier * s);
TR::Node *replaceChild(int32_t childIndex, TR::Node* node, TR::Node* newChild, TR::Simplifier* s);
TR::Node *postWalkLowerTreeSimplifier(TR::TreeTop *tt, TR::Node *node, TR::Block *block, TR::Simplifier * s);
void foldFloatConstantEmulate(TR::Node * node, uint32_t value, TR::Simplifier * s);
void foldDoubleConstantEmulate(TR::Node * node, uint64_t value, TR::Simplifier * s);
bool isNaNFloat(TR::Node * node);
bool isNaNDouble(TR::Node * node);
bool isNZFloatPowerOfTwo(float value);
bool isNZDoublePowerOfTwo(double value);
bool isIntegralExponentInRange(TR::Node *parent, TR::Node *exponent, int64_t maxNegativeExponent, int64_t maxPositiveExponent, TR::Simplifier * s);
TR::Node *reduceExpTwoAndGreaterToMultiplication(int32_t exponentValue, TR::Node *baseNode, TR::ILOpCodes multOp, TR::Block *block, TR::Simplifier *s, int32_t maxExponent);
TR::Node *replaceExpWithMult(TR::Node *node,TR::Node *valueNode,TR::Node *exponentNode,TR::Block *block,TR::Simplifier *s);
bool propagateSignState(TR::Node *node, TR::Node *child, int32_t shiftAmount, TR::Block *block, TR::Simplifier *s);
bool propagateSignStateUnaryConversion(TR::Node *node, TR::Block *block, TR::Simplifier *s);
void convertStringToPacked(char *result, int32_t resultLen, bool resultIsEvenPrecision, char *source, int32_t sourceLen, uint32_t signCode);
void convertStringToZoned(char *result, int32_t resultLen, char *source, int32_t sourceLen, uint32_t signCode, bool signLeading);
void convertStringToZonedSeparate(char *result, int32_t resultLen, char *source, int32_t sourceLen, uint32_t signCode, bool signLeading);
void convertStringToUnicode(char *result, int32_t resultLen, char *source, int32_t sourceLen);
void convertStringToUnicodeSeparate(char *result, int32_t resultLen, char *source, int32_t sourceLen, uint32_t signCode, bool signLeading);
TR::Node *removeOperandWidening(TR::Node *node, TR::Node *parent, TR::Block *block, TR::Simplifier * s);
bool decodeConversionOpcode(TR::ILOpCode op, TR::DataTypes nodeDataType, TR::DataTypes &sourceDataType, TR::DataTypes &targetDataType);
int32_t floatToInt(float value, bool roundUp);
int32_t doubleToInt(double value, bool roundUp);
void removePaddingNode(TR::Node *node, TR::Simplifier *s);
void stopUsingSingleNode(TR::Node *node, bool removePadding, TR::Simplifier *s);
#endif