comparison graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java @ 21508:dd612c515242

LinearScanWalker: outsource register range check.
author Josef Eisl <josef.eisl@jku.at>
date Wed, 27 May 2015 12:06:50 +0200
parents 4677c5d78ca6
children ce2113326bc8
comparison
equal deleted inserted replaced
21507:4677c5d78ca6 21508:dd612c515242
28 28
29 import java.util.*; 29 import java.util.*;
30 30
31 import com.oracle.graal.api.code.*; 31 import com.oracle.graal.api.code.*;
32 import com.oracle.graal.api.meta.*; 32 import com.oracle.graal.api.meta.*;
33 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig.*;
33 import com.oracle.graal.compiler.common.cfg.*; 34 import com.oracle.graal.compiler.common.cfg.*;
34 import com.oracle.graal.compiler.common.util.*; 35 import com.oracle.graal.compiler.common.util.*;
35 import com.oracle.graal.debug.*; 36 import com.oracle.graal.debug.*;
36 import com.oracle.graal.lir.*; 37 import com.oracle.graal.lir.*;
37 import com.oracle.graal.lir.StandardOp.MoveOp; 38 import com.oracle.graal.lir.StandardOp.MoveOp;
47 protected final int[] blockPos; 48 protected final int[] blockPos;
48 49
49 protected List<Interval>[] spillIntervals; 50 protected List<Interval>[] spillIntervals;
50 51
51 private MoveResolver moveResolver; // for ordering spill moves 52 private MoveResolver moveResolver; // for ordering spill moves
53
54 private int minReg;
55
56 private int maxReg;
52 57
53 /** 58 /**
54 * Only 10% of the lists in {@link #spillIntervals} are actually used. But when they are used, 59 * Only 10% of the lists in {@link #spillIntervals} are actually used. But when they are used,
55 * they can grow quite long. The maximum length observed was 45 (all numbers taken from a 60 * they can grow quite long. The maximum length observed was 45 (all numbers taken from a
56 * bootstrap run of Graal). Therefore, we initialize {@link #spillIntervals} with this marker 61 * bootstrap run of Graal). Therefore, we initialize {@link #spillIntervals} with this marker
93 spillIntervals[i].clear(); 98 spillIntervals[i].clear();
94 } 99 }
95 } 100 }
96 } 101 }
97 102
103 int maxRegisterNumber() {
104 return maxReg;
105 }
106
107 int minRegisterNumber() {
108 return minReg;
109 }
110
111 boolean isRegisterInRange(int reg) {
112 return reg >= minRegisterNumber() && reg <= maxRegisterNumber();
113 }
114
98 void excludeFromUse(Interval i) { 115 void excludeFromUse(Interval i) {
99 Value location = i.location(); 116 Value location = i.location();
100 int i1 = asRegister(location).number; 117 int i1 = asRegister(location).number;
101 if (i1 >= availableRegs[0].number && i1 <= availableRegs[availableRegs.length - 1].number) { 118 if (isRegisterInRange(i1)) {
102 usePos[i1] = 0; 119 usePos[i1] = 0;
103 } 120 }
104 } 121 }
105 122
106 void setUsePos(Interval interval, int usePos, boolean onlyProcessUsePos) { 123 void setUsePos(Interval interval, int usePos, boolean onlyProcessUsePos) {
107 if (usePos != -1) { 124 if (usePos != -1) {
108 assert usePos != 0 : "must use excludeFromUse to set usePos to 0"; 125 assert usePos != 0 : "must use excludeFromUse to set usePos to 0";
109 int i = asRegister(interval.location()).number; 126 int i = asRegister(interval.location()).number;
110 if (i >= availableRegs[0].number && i <= availableRegs[availableRegs.length - 1].number) { 127 if (isRegisterInRange(i)) {
111 if (this.usePos[i] > usePos) { 128 if (this.usePos[i] > usePos) {
112 this.usePos[i] = usePos; 129 this.usePos[i] = usePos;
113 } 130 }
114 if (!onlyProcessUsePos) { 131 if (!onlyProcessUsePos) {
115 List<Interval> list = spillIntervals[i]; 132 List<Interval> list = spillIntervals[i];
124 } 141 }
125 142
126 void setBlockPos(Interval i, int blockPos) { 143 void setBlockPos(Interval i, int blockPos) {
127 if (blockPos != -1) { 144 if (blockPos != -1) {
128 int reg = asRegister(i.location()).number; 145 int reg = asRegister(i.location()).number;
129 if (reg >= availableRegs[0].number && reg <= availableRegs[availableRegs.length - 1].number) { 146 if (isRegisterInRange(reg)) {
130 if (this.blockPos[reg] > blockPos) { 147 if (this.blockPos[reg] > blockPos) {
131 this.blockPos[reg] = blockPos; 148 this.blockPos[reg] = blockPos;
132 } 149 }
133 if (usePos[reg] > blockPos) { 150 if (usePos[reg] > blockPos) {
134 usePos[reg] = blockPos; 151 usePos[reg] = blockPos;
694 711
695 Register reg = null; 712 Register reg = null;
696 Register minFullReg = null; 713 Register minFullReg = null;
697 Register maxPartialReg = null; 714 Register maxPartialReg = null;
698 715
699 for (int i = 0; i < availableRegs.length; ++i) { 716 for (Register availableReg : availableRegs) {
700 Register availableReg = availableRegs[i];
701 int number = availableReg.number; 717 int number = availableReg.number;
702 if (usePos[number] >= intervalTo) { 718 if (usePos[number] >= intervalTo) {
703 // this register is free for the full interval 719 // this register is free for the full interval
704 if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) { 720 if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) {
705 minFullReg = availableReg; 721 minFullReg = availableReg;
856 } 872 }
857 return false; 873 return false;
858 } 874 }
859 875
860 void initVarsForAlloc(Interval interval) { 876 void initVarsForAlloc(Interval interval) {
861 availableRegs = allocator.regAllocConfig.getAllocatableRegisters(interval.kind().getPlatformKind()).allocatableRegisters; 877 AllocatableRegisters allocatableRegisters = allocator.regAllocConfig.getAllocatableRegisters(interval.kind().getPlatformKind());
878 availableRegs = allocatableRegisters.allocatableRegisters;
879 minReg = allocatableRegisters.minRegisterNumber;
880 maxReg = allocatableRegisters.maxRegisterNumber;
862 } 881 }
863 882
864 static boolean isMove(LIRInstruction op, Interval from, Interval to) { 883 static boolean isMove(LIRInstruction op, Interval from, Interval to) {
865 if (op instanceof MoveOp) { 884 if (op instanceof MoveOp) {
866 MoveOp move = (MoveOp) op; 885 MoveOp move = (MoveOp) op;