summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/LiveVariables.c
blob: 210761ee3315bb74d993085cd5bf917165c39dad (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
#include "compiler/LiveInfo.h"
#include "compiler/BitVectors.h"
#include "compiler/Coloring.h"
#include "compiler/CompilerTools.h"
#include "compiler/PCode.h"
#include "compiler/Registers.h"
#include "compiler/objects.h"
#include "compiler/types.h"
#include "compiler/CParser.h"

LiveInfo *liveinfo;

static void allocateliveinfo(void) {
    UInt32 regs;
    LiveInfo *info;
    int i;

    regs = used_virtual_registers[coloring_class];

    liveinfo = oalloc(sizeof(LiveInfo) * pcblockcount);
    for (i = 0, info = liveinfo; i < pcblockcount; i++, info++) {
        bitvectorinitialize(info->use = oalloc(4 * ((regs + 31) >> 5)), regs, 0);
        bitvectorinitialize(info->def = oalloc(4 * ((regs + 31) >> 5)), regs, 0);
        bitvectorinitialize(info->in = oalloc(4 * ((regs + 31) >> 5)), regs, 0);
        bitvectorinitialize(info->out = oalloc(4 * ((regs + 31) >> 5)), regs, 0);
    }
}

static void computelocalusedef(void) {
    LiveInfo *info;
    PCodeBlock *block;
    PCode *instr;
    UInt32 *use;
    UInt32 *def;
    PCodeArg *op;
    int i;

    for (block = pcbasicblocks; block; block = block->nextBlock) {
        info = &liveinfo[block->blockIndex];
        use = info->use;
        def = info->def;

        for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
            op = instr->args;
            i = instr->argCount;
            while (i--) {
                if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class) && !bitvectorgetbit(op->data.reg.reg, def))
                    bitvectorsetbit(op->data.reg.reg, use);
                op++;
            }

            op = instr->args;
            i = instr->argCount;
            while (i--) {
                if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class) && !bitvectorgetbit(op->data.reg.reg, use))
                    bitvectorsetbit(op->data.reg.reg, def);
                op++;
            }
        }
    }
}

static void computeglobalinout(void) {
    UInt32 regs;
    LiveInfo *info;
    UInt32 *use;
    UInt32 *def;
    UInt32 *in;
    UInt32 *out;
    int bitvecsize;
    int blockIndex;
    int i;
    int flag;
    PCodeBlock *block;
    PCLink *link;
    UInt32 val;

    regs = used_virtual_registers[coloring_class];
    bitvecsize = (regs + 31) >> 5;
    flag = 1;
    while (flag) {
        flag = 0;
        blockIndex = pcblockcount;
        while (blockIndex) {
            if ((block = depthfirstordering[--blockIndex])) {
                info = &liveinfo[block->blockIndex];
                if ((link = block->successors)) {
                    out = info->out;
                    bitvectorcopy(out, liveinfo[link->block->blockIndex].in, regs);
                    for (link = link->nextLink; link; link = link->nextLink)
                        bitvectorunion(out, liveinfo[link->block->blockIndex].in, regs);
                }

                out = info->out;
                in = info->in;
                use = info->use;
                def = info->def;
                for (i = 0; i < bitvecsize; i++) {
                    val = *use | (*out & ~*def);
                    if (val != *in) {
                        *in = val;
                        flag = 1;
                    }
                    in++;
                    out++;
                    use++;
                    def++;
                }
            }
        }
    }
}

void computelivevariables(Object *proc) {
    Type *returnType;

    returnType = TYPE_FUNC(proc->type)->functype;
    computedepthfirstordering();
    allocateliveinfo();
    computelocalusedef();

    if (coloring_class == RegClass_GPR && TYPE_FITS_IN_REGISTER(returnType)) {
        bitvectorsetbit(3, liveinfo[epilogue->blockIndex].use);
        if (TYPE_IS_8BYTES(returnType))
            bitvectorsetbit(4, liveinfo[pclastblock->blockIndex].use);
    } else if (coloring_class == RegClass_FPR && IS_TYPE_FLOAT(returnType)) {
        bitvectorsetbit(1, liveinfo[epilogue->blockIndex].use);
    } else if (coloring_class == RegClass_VR && IS_TYPE_VECTOR(returnType)) {
        bitvectorsetbit(2, liveinfo[epilogue->blockIndex].use);
    }

    computeglobalinout();
}

int dead(PCode *instr, RegClass rclass, UInt32 *vec) {
    int i;
    PCodeArg *op;

    if (instr->flags & (fIsBranch | fIsWrite | fIsCall | fIsVolatile | fSideEffects))
        return 0;
    if (instr->block->flags & (fIsProlog | fIsEpilogue))
        return 0;

    op = instr->args;
    i = instr->argCount;
    while (i--) {
        if (
            op->kind == PCOp_REGISTER &&
            (op->data.reg.effect & EffectWrite) &&
            (rclass != op->arg || bitvectorgetbit(op->data.reg.reg, vec))
            )
            return 0;
        op++;
    }

    return copts.optimizationlevel > 0;
}