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.lir.dfa;
24
25 import static jdk.vm.ci.code.ValueUtil.isIllegal;
26
27 import java.util.ArrayList;
28 import java.util.EnumSet;
29
30 import org.graalvm.compiler.core.common.LIRKind;
31 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
32 import org.graalvm.compiler.core.common.cfg.BlockMap;
33 import org.graalvm.compiler.debug.Debug;
34 import org.graalvm.compiler.debug.Indent;
35 import org.graalvm.compiler.lir.InstructionStateProcedure;
36 import org.graalvm.compiler.lir.LIR;
37 import org.graalvm.compiler.lir.LIRFrameState;
38 import org.graalvm.compiler.lir.LIRInstruction;
39 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
40 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
41 import org.graalvm.compiler.lir.ValueConsumer;
42 import org.graalvm.compiler.lir.framemap.FrameMap;
43 import org.graalvm.compiler.lir.util.ValueSet;
44
45 import jdk.vm.ci.code.Register;
46 import jdk.vm.ci.meta.PlatformKind;
47 import jdk.vm.ci.meta.Value;
48
49 public abstract class LocationMarker<S extends ValueSet<S>> {
50
51 private final LIR lir;
52 private final BlockMap<S> liveInMap;
53 private final BlockMap<S> liveOutMap;
85 /**
86 * Merge outSet with in-set of successors.
87 */
88 private boolean updateOutBlock(AbstractBlockBase<?> block) {
89 S union = newLiveValueSet();
90 for (AbstractBlockBase<?> succ : block.getSuccessors()) {
91 union.putAll(liveInMap.get(succ));
92 }
93 S outSet = liveOutMap.get(block);
94 // check if changed
95 if (outSet == null || !union.equals(outSet)) {
96 liveOutMap.put(block, union);
97 return true;
98 }
99 return false;
100 }
101
102 @SuppressWarnings("try")
103 private void processBlock(AbstractBlockBase<?> block, UniqueWorkList worklist) {
104 if (updateOutBlock(block)) {
105 try (Indent indent = Debug.logAndIndent("handle block %s", block)) {
106 currentSet = liveOutMap.get(block).copy();
107 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
108 for (int i = instructions.size() - 1; i >= 0; i--) {
109 LIRInstruction inst = instructions.get(i);
110 processInstructionBottomUp(inst);
111 }
112 liveInMap.put(block, currentSet);
113 currentSet = null;
114 for (AbstractBlockBase<?> b : block.getPredecessors()) {
115 worklist.add(b);
116 }
117 }
118 }
119 }
120
121 private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG);
122
123 private S currentSet;
124
125 /**
126 * Process all values of an instruction bottom-up, i.e. definitions before usages. Values that
127 * start or end at the current operation are not included.
128 */
129 @SuppressWarnings("try")
130 private void processInstructionBottomUp(LIRInstruction op) {
131 try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) {
132 // kills
133
134 op.visitEachTemp(defConsumer);
135 op.visitEachOutput(defConsumer);
136 if (frameMap != null && op.destroysCallerSavedRegisters()) {
137 for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
138 PlatformKind kind = frameMap.getTarget().arch.getLargestStorableKind(reg.getRegisterCategory());
139 defConsumer.visitValue(reg.asValue(LIRKind.value(kind)), OperandMode.TEMP, REGISTER_FLAG_SET);
140 }
141 }
142
143 // gen - values that are considered alive for this state
144 op.visitEachAlive(useConsumer);
145 op.visitEachState(useConsumer);
146 // mark locations
147 op.forEachState(stateConsumer);
148 // gen
149 op.visitEachInput(useConsumer);
150 }
151 }
152
153 InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
154 @Override
155 public void doState(LIRInstruction inst, LIRFrameState info) {
156 processState(inst, info, currentSet);
157 }
158 };
159
160 ValueConsumer useConsumer = new ValueConsumer() {
161 @Override
162 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
163 if (shouldProcessValue(operand)) {
164 // no need to insert values and derived reference
165 if (Debug.isLogEnabled()) {
166 Debug.log("set operand: %s", operand);
167 }
168 currentSet.put(operand);
169 }
170 }
171 };
172
173 ValueConsumer defConsumer = new ValueConsumer() {
174 @Override
175 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
176 if (shouldProcessValue(operand)) {
177 if (Debug.isLogEnabled()) {
178 Debug.log("clear operand: %s", operand);
179 }
180 currentSet.remove(operand);
181 } else {
182 assert isIllegal(operand) || !operand.getValueKind().equals(LIRKind.Illegal) || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s",
183 operand, mode);
184 }
185 }
186 };
187 }
|
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.lir.dfa;
24
25 import static jdk.vm.ci.code.ValueUtil.isIllegal;
26
27 import java.util.ArrayList;
28 import java.util.EnumSet;
29
30 import org.graalvm.compiler.core.common.LIRKind;
31 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
32 import org.graalvm.compiler.core.common.cfg.BlockMap;
33 import org.graalvm.compiler.debug.DebugContext;
34 import org.graalvm.compiler.debug.Indent;
35 import org.graalvm.compiler.lir.InstructionStateProcedure;
36 import org.graalvm.compiler.lir.LIR;
37 import org.graalvm.compiler.lir.LIRFrameState;
38 import org.graalvm.compiler.lir.LIRInstruction;
39 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
40 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
41 import org.graalvm.compiler.lir.ValueConsumer;
42 import org.graalvm.compiler.lir.framemap.FrameMap;
43 import org.graalvm.compiler.lir.util.ValueSet;
44
45 import jdk.vm.ci.code.Register;
46 import jdk.vm.ci.meta.PlatformKind;
47 import jdk.vm.ci.meta.Value;
48
49 public abstract class LocationMarker<S extends ValueSet<S>> {
50
51 private final LIR lir;
52 private final BlockMap<S> liveInMap;
53 private final BlockMap<S> liveOutMap;
85 /**
86 * Merge outSet with in-set of successors.
87 */
88 private boolean updateOutBlock(AbstractBlockBase<?> block) {
89 S union = newLiveValueSet();
90 for (AbstractBlockBase<?> succ : block.getSuccessors()) {
91 union.putAll(liveInMap.get(succ));
92 }
93 S outSet = liveOutMap.get(block);
94 // check if changed
95 if (outSet == null || !union.equals(outSet)) {
96 liveOutMap.put(block, union);
97 return true;
98 }
99 return false;
100 }
101
102 @SuppressWarnings("try")
103 private void processBlock(AbstractBlockBase<?> block, UniqueWorkList worklist) {
104 if (updateOutBlock(block)) {
105 DebugContext debug = lir.getDebug();
106 try (Indent indent = debug.logAndIndent("handle block %s", block)) {
107 currentSet = liveOutMap.get(block).copy();
108 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
109 for (int i = instructions.size() - 1; i >= 0; i--) {
110 LIRInstruction inst = instructions.get(i);
111 processInstructionBottomUp(inst);
112 }
113 liveInMap.put(block, currentSet);
114 currentSet = null;
115 for (AbstractBlockBase<?> b : block.getPredecessors()) {
116 worklist.add(b);
117 }
118 }
119 }
120 }
121
122 private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG);
123
124 private S currentSet;
125
126 /**
127 * Process all values of an instruction bottom-up, i.e. definitions before usages. Values that
128 * start or end at the current operation are not included.
129 */
130 @SuppressWarnings("try")
131 private void processInstructionBottomUp(LIRInstruction op) {
132 DebugContext debug = lir.getDebug();
133 try (Indent indent = debug.logAndIndent("handle op %d, %s", op.id(), op)) {
134 // kills
135
136 op.visitEachTemp(defConsumer);
137 op.visitEachOutput(defConsumer);
138 if (frameMap != null && op.destroysCallerSavedRegisters()) {
139 for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
140 PlatformKind kind = frameMap.getTarget().arch.getLargestStorableKind(reg.getRegisterCategory());
141 defConsumer.visitValue(reg.asValue(LIRKind.value(kind)), OperandMode.TEMP, REGISTER_FLAG_SET);
142 }
143 }
144
145 // gen - values that are considered alive for this state
146 op.visitEachAlive(useConsumer);
147 op.visitEachState(useConsumer);
148 // mark locations
149 op.forEachState(stateConsumer);
150 // gen
151 op.visitEachInput(useConsumer);
152 }
153 }
154
155 InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
156 @Override
157 public void doState(LIRInstruction inst, LIRFrameState info) {
158 processState(inst, info, currentSet);
159 }
160 };
161
162 ValueConsumer useConsumer = new ValueConsumer() {
163 @Override
164 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
165 if (shouldProcessValue(operand)) {
166 // no need to insert values and derived reference
167 DebugContext debug = lir.getDebug();
168 if (debug.isLogEnabled()) {
169 debug.log("set operand: %s", operand);
170 }
171 currentSet.put(operand);
172 }
173 }
174 };
175
176 ValueConsumer defConsumer = new ValueConsumer() {
177 @Override
178 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
179 if (shouldProcessValue(operand)) {
180 DebugContext debug = lir.getDebug();
181 if (debug.isLogEnabled()) {
182 debug.log("clear operand: %s", operand);
183 }
184 currentSet.remove(operand);
185 } else {
186 assert isIllegal(operand) || !operand.getValueKind().equals(LIRKind.Illegal) || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s",
187 operand, mode);
188 }
189 }
190 };
191 }
|