1/*
2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.java;
24
25import java.util.BitSet;
26
27import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
28
29public final class LargeLocalLiveness extends LocalLiveness {
30    private BitSet[] localsLiveIn;
31    private BitSet[] localsLiveOut;
32    private BitSet[] localsLiveGen;
33    private BitSet[] localsLiveKill;
34    private BitSet[] localsChangedInLoop;
35
36    public LargeLocalLiveness(BciBlock[] blocks, int maxLocals, int loopCount) {
37        super(blocks);
38        int blocksSize = blocks.length;
39        localsLiveIn = new BitSet[blocksSize];
40        localsLiveOut = new BitSet[blocksSize];
41        localsLiveGen = new BitSet[blocksSize];
42        localsLiveKill = new BitSet[blocksSize];
43        for (int i = 0; i < blocksSize; i++) {
44            localsLiveIn[i] = new BitSet(maxLocals);
45            localsLiveOut[i] = new BitSet(maxLocals);
46            localsLiveGen[i] = new BitSet(maxLocals);
47            localsLiveKill[i] = new BitSet(maxLocals);
48        }
49        localsChangedInLoop = new BitSet[loopCount];
50        for (int i = 0; i < loopCount; ++i) {
51            localsChangedInLoop[i] = new BitSet(maxLocals);
52        }
53    }
54
55    @Override
56    protected String debugLiveIn(int blockID) {
57        return localsLiveIn[blockID].toString();
58    }
59
60    @Override
61    protected String debugLiveOut(int blockID) {
62        return localsLiveOut[blockID].toString();
63    }
64
65    @Override
66    protected String debugLiveGen(int blockID) {
67        return localsLiveGen[blockID].toString();
68    }
69
70    @Override
71    protected String debugLiveKill(int blockID) {
72        return localsLiveKill[blockID].toString();
73    }
74
75    @Override
76    protected int liveOutCardinality(int blockID) {
77        return localsLiveOut[blockID].cardinality();
78    }
79
80    @Override
81    protected void propagateLiveness(int blockID, int successorID) {
82        localsLiveOut[blockID].or(localsLiveIn[successorID]);
83    }
84
85    @Override
86    protected void updateLiveness(int blockID) {
87        BitSet liveIn = localsLiveIn[blockID];
88        liveIn.clear();
89        liveIn.or(localsLiveOut[blockID]);
90        liveIn.andNot(localsLiveKill[blockID]);
91        liveIn.or(localsLiveGen[blockID]);
92    }
93
94    @Override
95    protected void loadOne(int blockID, int local) {
96        if (!localsLiveKill[blockID].get(local)) {
97            localsLiveGen[blockID].set(local);
98        }
99    }
100
101    @Override
102    protected void storeOne(int blockID, int local) {
103        if (!localsLiveGen[blockID].get(local)) {
104            localsLiveKill[blockID].set(local);
105        }
106
107        BciBlock block = blocks[blockID];
108        long tmp = block.loops;
109        int pos = 0;
110        while (tmp != 0) {
111            if ((tmp & 1L) == 1L) {
112                this.localsChangedInLoop[pos].set(local);
113            }
114            tmp >>>= 1;
115            ++pos;
116        }
117    }
118
119    @Override
120    public boolean localIsLiveIn(BciBlock block, int local) {
121        return block.getId() >= Integer.MAX_VALUE ? true : localsLiveIn[block.getId()].get(local);
122    }
123
124    @Override
125    public boolean localIsLiveOut(BciBlock block, int local) {
126        return block.getId() >= Integer.MAX_VALUE ? true : localsLiveOut[block.getId()].get(local);
127    }
128
129    @Override
130    public boolean localIsChangedInLoop(int loopId, int local) {
131        return localsChangedInLoop[loopId].get(local);
132    }
133}
134