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 */ 23 package org.graalvm.compiler.java; 24 25 import java.util.BitSet; 26 27 import org.graalvm.compiler.java.BciBlockMapping.BciBlock; 28 29 public 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 }