summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/Optimizer/IroSubable.c
blob: 513ac6caae416fb0c5d932bfa2a93cd721048598 (plain)
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
#include "IroSubable.h"
#include "IroLinearForm.h"
#include "IroPropagate.h"
#include "IroUtil.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler/types.h"

static Boolean IsSubableOp[MAXEXPR];

void IRO_InitializeIsSubableOpArray(void) {
    int i;

    for (i = 0; i < MAXEXPR; i++)
        IsSubableOp[i] = 0;

    IsSubableOp[EPOSTINC] = 0;
    IsSubableOp[EPOSTDEC] = 0;
    IsSubableOp[EPREINC] = 0;
    IsSubableOp[EPREDEC] = 0;
    IsSubableOp[EINDIRECT] = 0;
    IsSubableOp[EMONMIN] = 1;
    IsSubableOp[EBINNOT] = 1;
    IsSubableOp[ELOGNOT] = 1;
    IsSubableOp[EFORCELOAD] = 0;
    IsSubableOp[EMUL] = 1;
    IsSubableOp[EMULV] = 1;
    IsSubableOp[EDIV] = 1;
    IsSubableOp[EMODULO] = 1;
    IsSubableOp[EADDV] = 1;
    IsSubableOp[ESUBV] = 1;
    IsSubableOp[EADD] = 1;
    IsSubableOp[ESUB] = 1;
    IsSubableOp[ESHL] = 1;
    IsSubableOp[ESHR] = 1;
    IsSubableOp[ELESS] = 0;
    IsSubableOp[EGREATER] = 0;
    IsSubableOp[ELESSEQU] = 0;
    IsSubableOp[EGREATEREQU] = 0;
    IsSubableOp[EEQU] = 0;
    IsSubableOp[ENOTEQU] = 0;
    IsSubableOp[EAND] = 1;
    IsSubableOp[EXOR] = 1;
    IsSubableOp[EOR] = 1;
    IsSubableOp[ELAND] = 0;
    IsSubableOp[ELOR] = 0;
    IsSubableOp[EASS] = 0;
    IsSubableOp[EMULASS] = 0;
    IsSubableOp[EDIVASS] = 0;
    IsSubableOp[EMODASS] = 0;
    IsSubableOp[EADDASS] = 0;
    IsSubableOp[ESUBASS] = 0;
    IsSubableOp[ESHLASS] = 0;
    IsSubableOp[ESHRASS] = 0;
    IsSubableOp[EANDASS] = 0;
    IsSubableOp[EXORASS] = 0;
    IsSubableOp[EORASS] = 0;
    IsSubableOp[ECOMMA] = 0;
    IsSubableOp[EPMODULO] = 0;
    IsSubableOp[EROTL] = 0;
    IsSubableOp[EROTR] = 0;
    IsSubableOp[EBCLR] = 0;
    IsSubableOp[EBTST] = 0;
    IsSubableOp[EBSET] = 0;
    IsSubableOp[ETYPCON] = 0;
    IsSubableOp[EBITFIELD] = 0;
    IsSubableOp[EINTCONST] = 0;
    IsSubableOp[EFLOATCONST] = 0;
    IsSubableOp[ESTRINGCONST] = 0;
    IsSubableOp[ECOND] = 0;
    IsSubableOp[EFUNCCALL] = 0;
    IsSubableOp[EFUNCCALLP] = 0;
    IsSubableOp[EOBJREF] = 0;
    IsSubableOp[EMFPOINTER] = 0;
    IsSubableOp[ENULLCHECK] = 0;
    IsSubableOp[EPRECOMP] = 0;
    IsSubableOp[ETEMP] = 0;
    IsSubableOp[EARGOBJ] = 0;
    IsSubableOp[ELOCOBJ] = 0;
    IsSubableOp[ELABEL] = 0;
    IsSubableOp[ESETCONST] = 0;
    IsSubableOp[ENEWEXCEPTION] = 0;
    IsSubableOp[ENEWEXCEPTIONARRAY] = 0;
    IsSubableOp[EOBJLIST] = 0;
    IsSubableOp[EMEMBER] = 0;
    IsSubableOp[ETEMPLDEP] = 0;
    IsSubableOp[EINSTRUCTION] = 0;
    IsSubableOp[EDEFINE] = 0;
    IsSubableOp[EREUSE] = 0;
    IsSubableOp[EASSBLK] = 0;
    IsSubableOp[EVECTOR128CONST] = 0;
    IsSubableOp[ECONDASS] = 0;
}

static int IsSubscript(IROLinear *nd) {
    return 0;
}

Boolean IRO_IsSubableExpression(IROLinear *nd) {
    Object *varobj;
    Boolean result;

    switch (nd->type) {
        case IROLinearOp2Arg:
            if (nd->nodetype == EADD || nd->nodetype == ESUB) {
                if (
                    IRO_IsConstant(nd->u.diadic.right) &&
                    (varobj = IRO_IsVariable(nd->u.diadic.left)) &&
                        varobj->datatype == DLOCAL &&
                        varobj->u.var.info &&
                        !varobj->u.var.info->noregister)
                        return 0;

            }
            result = IsSubableOp[nd->nodetype] && !IsSubscript(nd);
            return result;
        case IROLinearOp1Arg:
            if (IsSubableOp[nd->nodetype] && !IsSubscript(nd))
                return 1;

            if (nd->nodetype == EINDIRECT && !(nd->flags & IROLF_Assigned)) {
                if (nd->flags & IROLF_Ind) {
                    nd = nd->u.monadic;
                    if (nd->type == IROLinearOperand &&
                        nd->u.node->type == EOBJREF &&
                        nd->u.node->data.objref->datatype == DLOCAL &&
                        nd->u.node->data.objref->u.var.info &&
                        !nd->u.node->data.objref->u.var.info->noregister
                        )
                        return 0;
                    return 1;
                }

                if (IRO_IsVariable(nd) && IRO_IsRegable(nd->u.monadic->u.node->data.objref))
                    return 0;
                return 1;
            } else if (nd->nodetype == ETYPCON && IS_TYPE_INT(nd->rtype) && nd->rtype->size >= nd->u.monadic->rtype->size) {
                return 1;
            } else {
                return 0;
            }
        case IROLinearOperand:
        default:
            return 0;
    }
}

Boolean IRO_IsVectorTempCandidate(IROLinear *nd) {
    return
        (
            nd->type == IROLinearOp1Arg ||
            nd->type == IROLinearOp2Arg ||
            nd->type == IROLinearOp3Arg ||
            nd->type == IROLinearOperand ||
            nd->type == IROLinearFunccall
        ) && (
            (nd->flags & IROLF_LoopInvariant) &&
            !(nd->flags & IROLF_Ind)
        );
}