annotate graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java @ 19214:e1f63e69dc6c

Make ConstantLoadOptimization a LowLevelHighTierPhase.
author Josef Eisl <josef.eisl@jku.at>
date Mon, 09 Feb 2015 09:10:44 +0100
parents ecb9d0cedbab
children edd93c34d015
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
1 /*
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
2 * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
4 *
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
7 * published by the Free Software Foundation.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
8 *
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
13 * accompanied this code).
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
14 *
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
18 *
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
21 * questions.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
22 */
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
23 package com.oracle.graal.lir.constopt;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
24
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
25 import static com.oracle.graal.api.code.ValueUtil.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
26 import static com.oracle.graal.lir.LIRValueUtil.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
27
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
28 import java.util.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
29
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
30 import com.oracle.graal.api.code.*;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
31 import com.oracle.graal.api.meta.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
32 import com.oracle.graal.compiler.common.cfg.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
33 import com.oracle.graal.debug.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
34 import com.oracle.graal.debug.Debug.Scope;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
35 import com.oracle.graal.lir.*;
17283
e8b80721524d Remove InstructionValueConsumer.visitValue(LIRInstruction, Value).
Josef Eisl <josef.eisl@jku.at>
parents: 17277
diff changeset
36 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
e8b80721524d Remove InstructionValueConsumer.visitValue(LIRInstruction, Value).
Josef Eisl <josef.eisl@jku.at>
parents: 17277
diff changeset
37 import com.oracle.graal.lir.LIRInstruction.OperandMode;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
38 import com.oracle.graal.lir.StandardOp.MoveOp;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
39 import com.oracle.graal.lir.constopt.ConstantTree.Flags;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
40 import com.oracle.graal.lir.constopt.ConstantTree.NodeCost;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
41 import com.oracle.graal.lir.gen.*;
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
42 import com.oracle.graal.lir.phases.*;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
43 import com.oracle.graal.options.*;
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
44
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
45 /**
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
46 * This optimization tries to improve the handling of constants by replacing a single definition of
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
47 * a constant, which is potentially scheduled into a block with high probability, with one or more
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
48 * definitions in blocks with a lower probability.
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
49 */
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
50 public final class ConstantLoadOptimization extends LowLevelHighTierPhase {
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
51
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
52 public static class Options {
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
53 // @formatter:off
18674
ecb9d0cedbab First draft of option classification.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18187
diff changeset
54 @Option(help = "Enable constant load optimization.", type = OptionType.Debug)
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
55 public static final OptionValue<Boolean> ConstantLoadOptimization = new OptionValue<>(true);
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
56 // @formatter:on
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
57 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
58
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
59 @Override
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
60 protected void run(TargetDescription target, LIRGenerationResult lirGenRes, LIRGeneratorTool lirGen) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
61 new Optimization(lirGenRes.getLIR(), lirGen).apply();
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
62 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
63
17212
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
64 private static final DebugMetric constantsTotal = Debug.metric("ConstantLoadOptimization[total]");
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
65 private static final DebugMetric phiConstantsSkipped = Debug.metric("ConstantLoadOptimization[PhisSkipped]");
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
66 private static final DebugMetric singleUsageConstantsSkipped = Debug.metric("ConstantLoadOptimization[SingleUsageSkipped]");
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
67 private static final DebugMetric usageAtDefinitionSkipped = Debug.metric("ConstantLoadOptimization[UsageAtDefinitionSkipped]");
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
68 private static final DebugMetric materializeAtDefinitionSkipped = Debug.metric("ConstantLoadOptimization[MaterializeAtDefinitionSkipped]");
26d07b31c4a8 ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents: 17068
diff changeset
69 private static final DebugMetric constantsOptimized = Debug.metric("ConstantLoadOptimization[optimized]");
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
70
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
71 private static final class Optimization {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
72 private final LIR lir;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
73 private final LIRGeneratorTool lirGen;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
74 private final VariableMap<DefUseTree> map;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
75 private final BitSet phiConstants;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
76 private final BitSet defined;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
77 private final BlockMap<List<UseEntry>> blockMap;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
78 private final BlockMap<LIRInsertionBuffer> insertionBuffers;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
79
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
80 private Optimization(LIR lir, LIRGeneratorTool lirGen) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
81 this.lir = lir;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
82 this.lirGen = lirGen;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
83 this.map = new VariableMap<>();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
84 this.phiConstants = new BitSet();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
85 this.defined = new BitSet();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
86 this.insertionBuffers = new BlockMap<>(lir.getControlFlowGraph());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
87 this.blockMap = new BlockMap<>(lir.getControlFlowGraph());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
88 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
89
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
90 private void apply() {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
91 try (Indent indent = Debug.logAndIndent("ConstantLoadOptimization")) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
92 try (Scope s = Debug.scope("BuildDefUseTree")) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
93 // build DefUseTree
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
94 lir.getControlFlowGraph().getBlocks().forEach(this::analyzeBlock);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
95 // remove all with only one use
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
96 map.filter(t -> {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
97 if (t.usageCount() > 1) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
98 return true;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
99 } else {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
100 singleUsageConstantsSkipped.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
101 return false;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
102 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
103 });
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
104 // collect block map
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
105 map.forEach(tree -> tree.forEach(this::addUsageToBlockMap));
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
106 } catch (Throwable e) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
107 throw Debug.handle(e);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
108 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
109
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
110 try (Scope s = Debug.scope("BuildConstantTree")) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
111 // create ConstantTree
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
112 map.forEach(this::createConstantTree);
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
113
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
114 // insert moves, delete null instructions and reset instruction ids
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
115 lir.getControlFlowGraph().getBlocks().forEach(this::rewriteBlock);
17068
8456194ca311 Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 16953
diff changeset
116
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
117 assert verifyStates();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
118 } catch (Throwable e) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
119 throw Debug.handle(e);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
120 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
121 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
122 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
123
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
124 private boolean verifyStates() {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
125 map.forEach(this::verifyStateUsage);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
126 return true;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
127 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
128
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
129 private void verifyStateUsage(DefUseTree tree) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
130 Variable var = tree.getVariable();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
131 ValueConsumer stateConsumer = new ValueConsumer() {
17068
8456194ca311 Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 16953
diff changeset
132
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
133 @Override
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
134 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
135 assert !operand.equals(var) : "constant usage through variable in frame state " + var;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
136 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
137 };
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
138 for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
139 for (LIRInstruction inst : lir.getLIRforBlock(block)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
140 // set instruction id to the index in the lir instruction list
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
141 inst.visitEachState(stateConsumer);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
142 }
17068
8456194ca311 Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 16953
diff changeset
143 }
8456194ca311 Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 16953
diff changeset
144 }
8456194ca311 Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 16953
diff changeset
145
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
146 private static boolean isConstantLoad(LIRInstruction inst) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
147 if (!(inst instanceof MoveOp)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
148 return false;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
149 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
150 MoveOp move = (MoveOp) inst;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
151 return isConstant(move.getInput()) && isVariable(move.getResult());
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
152 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
153
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
154 private void addUsageToBlockMap(UseEntry entry) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
155 AbstractBlock<?> block = entry.getBlock();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
156 List<UseEntry> list = blockMap.get(block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
157 if (list == null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
158 list = new ArrayList<>();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
159 blockMap.put(block, list);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
160 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
161 list.add(entry);
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
162 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
163
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
164 /**
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
165 * Collects def-use information for a {@code block}.
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
166 */
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
167 private void analyzeBlock(AbstractBlock<?> block) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
168 try (Indent indent = Debug.logAndIndent("Block: %s", block)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
169
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
170 InstructionValueConsumer loadConsumer = (instruction, value, mode, flags) -> {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
171 if (isVariable(value)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
172 Variable var = (Variable) value;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
173
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
174 if (!phiConstants.get(var.index)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
175 if (!defined.get(var.index)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
176 defined.set(var.index);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
177 if (isConstantLoad(instruction)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
178 Debug.log("constant load: %s", instruction);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
179 map.put(var, new DefUseTree(instruction, block));
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
180 constantsTotal.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
181 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
182 } else {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
183 // Variable is redefined, this only happens for constant loads
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
184 // introduced by phi resolution -> ignore.
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
185 DefUseTree removed = map.remove(var);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
186 if (removed != null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
187 phiConstantsSkipped.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
188 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
189 phiConstants.set(var.index);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
190 Debug.log(3, "Removing phi variable: %s", var);
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
191 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
192 } else {
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
193 assert defined.get(var.index) : "phi but not defined? " + var;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
194 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
195 }
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
196 };
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
197
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
198 ValuePositionProcedure useProcedure = (instruction, position) -> {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
199 Value value = position.get(instruction);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
200 if (isVariable(value)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
201 Variable var = (Variable) value;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
202 if (!phiConstants.get(var.index)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
203 DefUseTree tree = map.get(var);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
204 if (tree != null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
205 tree.addUsage(block, instruction, position);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
206 Debug.log("usage of %s : %s", var, instruction);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
207 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
208 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
209 }
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
210 };
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
211
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
212 int opId = 0;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
213 for (LIRInstruction inst : lir.getLIRforBlock(block)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
214 // set instruction id to the index in the lir instruction list
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
215 inst.setId(opId++);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
216 inst.visitEachOutput(loadConsumer);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
217 inst.forEachInputPos(useProcedure);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
218 inst.forEachAlivePos(useProcedure);
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
219
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
220 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
221 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
222 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
223
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
224 /**
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
225 * Creates the dominator tree and searches for an solution.
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
226 */
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
227 private void createConstantTree(DefUseTree tree) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
228 ConstantTree constTree = new ConstantTree(lir.getControlFlowGraph(), tree);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
229 constTree.set(Flags.SUBTREE, tree.getBlock());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
230 tree.forEach(u -> constTree.set(Flags.USAGE, u.getBlock()));
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
231
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
232 if (constTree.get(Flags.USAGE, tree.getBlock())) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
233 // usage in the definition block -> no optimization
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
234 usageAtDefinitionSkipped.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
235 return;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
236 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
237
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
238 constTree.markBlocks();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
239
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
240 NodeCost cost = ConstantTreeAnalyzer.analyze(constTree, tree.getBlock());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
241 int usageCount = cost.getUsages().size();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
242 assert usageCount == tree.usageCount() : "Usage count differs: " + usageCount + " vs. " + tree.usageCount();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
243
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
244 if (Debug.isLogEnabled()) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
245 try (Indent i = Debug.logAndIndent("Variable: %s, Block: %s, prob.: %f", tree.getVariable(), tree.getBlock(), tree.getBlock().probability())) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
246 Debug.log("Usages result: %s", cost);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
247 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
248
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
249 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
250
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
251 if (cost.getNumMaterializations() > 1 || cost.getBestCost() < tree.getBlock().probability()) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
252 try (Scope s = Debug.scope("CLOmodify", constTree); Indent i = Debug.logAndIndent("Replacing %s = %s", tree.getVariable(), tree.getConstant().toValueString())) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
253 // mark original load for removal
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
254 deleteInstruction(tree);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
255 constantsOptimized.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
256
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
257 // collect result
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
258 createLoads(tree, constTree, tree.getBlock());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
259
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
260 } catch (Throwable e) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
261 throw Debug.handle(e);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
262 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
263 } else {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
264 // no better solution found
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
265 materializeAtDefinitionSkipped.increment();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
266 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
267 Debug.dump(constTree, "ConstantTree for " + tree.getVariable());
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
268 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
269
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
270 private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlock<?> startBlock) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
271 Deque<AbstractBlock<?>> worklist = new ArrayDeque<>();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
272 worklist.add(startBlock);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
273 while (!worklist.isEmpty()) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
274 AbstractBlock<?> block = worklist.pollLast();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
275 if (constTree.get(Flags.CANDIDATE, block)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
276 constTree.set(Flags.MATERIALIZE, block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
277 // create and insert load
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
278 insertLoad(tree.getConstant(), tree.getVariable().getLIRKind(), block, constTree.getCost(block).getUsages());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
279 } else {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
280 for (AbstractBlock<?> dominated : block.getDominated()) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
281 if (constTree.isMarked(dominated)) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
282 worklist.addLast(dominated);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
283 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
284 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
285 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
286 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
287 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
288
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
289 private void insertLoad(JavaConstant constant, LIRKind kind, AbstractBlock<?> block, List<UseEntry> usages) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
290 assert usages != null && usages.size() > 0 : String.format("No usages %s %s %s", constant, block, usages);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
291 // create variable
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
292 Variable variable = lirGen.newVariable(kind);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
293 // create move
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
294 LIRInstruction move = lir.getSpillMoveFactory().createMove(variable, constant);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
295 // insert instruction
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
296 getInsertionBuffer(block).append(1, move);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
297 Debug.log("new move (%s) and inserted in block %s", move, block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
298 // update usages
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
299 for (UseEntry u : usages) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
300 u.getPosition().set(u.getInstruction(), variable);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
301 Debug.log("patched instruction %s", u.getInstruction());
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
302 }
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
303 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
304
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
305 /**
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
306 * Inserts the constant loads created in {@link #createConstantTree} and deletes the
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
307 * original definition.
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
308 */
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
309 private void rewriteBlock(AbstractBlock<?> block) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
310 // insert moves
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
311 LIRInsertionBuffer buffer = insertionBuffers.get(block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
312 if (buffer != null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
313 assert buffer.initialized() : "not initialized?";
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
314 buffer.finish();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
315 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
316
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
317 // delete instructions
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
318 List<LIRInstruction> instructions = lir.getLIRforBlock(block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
319 boolean hasDead = false;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
320 for (LIRInstruction inst : instructions) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
321 if (inst == null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
322 hasDead = true;
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
323 } else {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
324 inst.setId(-1);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
325 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
326 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
327 if (hasDead) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
328 // Remove null values from the list.
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
329 instructions.removeAll(Collections.singleton(null));
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
330 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
331 }
19214
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
332
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
333 private void deleteInstruction(DefUseTree tree) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
334 AbstractBlock<?> block = tree.getBlock();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
335 LIRInstruction instruction = tree.getInstruction();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
336 Debug.log("deleting instruction %s from block %s", instruction, block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
337 lir.getLIRforBlock(block).set(instruction.id(), null);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
338 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
339
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
340 private LIRInsertionBuffer getInsertionBuffer(AbstractBlock<?> block) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
341 LIRInsertionBuffer insertionBuffer = insertionBuffers.get(block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
342 if (insertionBuffer == null) {
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
343 insertionBuffer = new LIRInsertionBuffer();
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
344 insertionBuffers.put(block, insertionBuffer);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
345 assert !insertionBuffer.initialized() : "already initialized?";
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
346 List<LIRInstruction> instructions = lir.getLIRforBlock(block);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
347 insertionBuffer.init(instructions);
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
348 }
e1f63e69dc6c Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents: 18674
diff changeset
349 return insertionBuffer;
16952
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
350 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
351 }
2451521ed26f Add ConstantLoadOptimization.
Josef Eisl <josef.eisl@jku.at>
parents:
diff changeset
352 }