Skip to content

Commit 2c5b9e9

Browse files
committed
[GR-68420] Use a sparse bitset and process fewer blocks during global liveness
PullRequest: graal/21894
2 parents 3437410 + 48c7c3b commit 2c5b9e9

File tree

16 files changed

+487
-204
lines changed

16 files changed

+487
-204
lines changed

compiler/src/jdk.graal.compiler.management/src/jdk/graal/compiler/management/JMXServiceProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static class GCTimeStatisticsImpl implements GCTimeStatistics {
122122
}
123123

124124
@Override
125-
public long getGCTimeMills() {
125+
public long getGCTimeMillis() {
126126
long afterMillis = 0;
127127
for (GarbageCollectorMXBean gc : gcs) {
128128
afterMillis += gc.getCollectionTime();

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/util/CompilationAlarm.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public void checkExpiration() {
201201
// Include information about time spent in the GC if it's available.
202202
String gcMessage = "";
203203
if (gcTiming != null) {
204-
gcMessage = String.format(" (GC time is %s ms of %s ms elapsed)", gcTiming.getGCTimeMills(), gcTiming.getElapsedTimeMillis());
204+
gcMessage = String.format(" (GC time is %s ms of %s ms elapsed)", gcTiming.getGCTimeMillis(), gcTiming.getElapsedTimeMillis());
205205
}
206206

207207
throw new PermanentBailoutException("Compilation exceeded %.3f seconds%s. %n Phase timings:%n %s <===== TIMEOUT HERE", period, gcMessage, sb.toString().trim());

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilationTask.java

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import java.io.PrintStream;
3737
import java.util.List;
3838
import java.util.ListIterator;
39-
import java.util.concurrent.TimeUnit;
4039

4140
import org.graalvm.collections.EconomicMap;
4241

@@ -78,7 +77,6 @@
7877
import jdk.graal.compiler.phases.tiers.Suites;
7978
import jdk.graal.compiler.printer.GraalDebugHandlersFactory;
8079
import jdk.graal.compiler.serviceprovider.GraalServices;
81-
import jdk.graal.compiler.serviceprovider.JMXService;
8280
import jdk.vm.ci.code.BailoutException;
8381
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
8482
import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
@@ -594,16 +592,6 @@ public HotSpotInstalledCode getInstalledCode() {
594592
*/
595593
public static final TimerKey CompilationTime = DebugContext.timer("CompilationTime").doc("Time spent in compilation and code installation.");
596594

597-
/**
598-
* Time spent in garbage collection during this compilation.
599-
*/
600-
public static final TimerKey GarbageCollectionTime = DebugContext.timer("GarbageCollectionTime").doc("Time spent in GC during compilation and code installation.");
601-
602-
/**
603-
* Number of garbage collection during this compilation.
604-
*/
605-
public static final CounterKey GarbageCollectionCount = DebugContext.counter("GarbageCollectionCount").doc("Number of GCs during compilation and code installation.");
606-
607595
/**
608596
* Counts the number of compiled {@linkplain CompilationResult#getBytecodeSize() bytecodes}.
609597
*/
@@ -638,27 +626,9 @@ public HotSpotCompilationRequestResult runCompilation(OptionValues initialOption
638626
}
639627
}
640628

641-
public record GCTimerScope(DebugContext debug, JMXService.GCTimeStatistics gcStats) implements DebugCloseable {
642-
static DebugCloseable create(DebugContext debug) {
643-
if (GarbageCollectionTime.isEnabled(debug) || GarbageCollectionCount.isEnabled(debug)) {
644-
final JMXService.GCTimeStatistics gcStats = GraalServices.getGCTimeStatistics();
645-
if (gcStats != null) {
646-
return new GCTimerScope(debug, gcStats);
647-
}
648-
}
649-
return null;
650-
}
651-
652-
@Override
653-
public void close() {
654-
GarbageCollectionCount.add(debug, gcStats.getGCCount());
655-
GarbageCollectionTime.add(debug, gcStats.getGCTimeMills(), TimeUnit.MILLISECONDS);
656-
}
657-
}
658-
659629
@SuppressWarnings({"try"})
660630
public HotSpotCompilationRequestResult runCompilation(DebugContext debug) {
661-
try (DebugCloseable a = CompilationTime.start(debug); DebugCloseable b = GCTimerScope.create(debug)) {
631+
try (DebugCloseable a = CompilationTime.start(debug); DebugCloseable b = GraalServices.GCTimerScope.create(debug)) {
662632
HotSpotCompilationRequestResult result = runCompilation(debug, new HotSpotCompilationWrapper());
663633
LibGraalSupport libgraal = LibGraalSupport.INSTANCE;
664634
if (libgraal != null) {

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScan.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
import java.util.ArrayList;
3434
import java.util.Arrays;
35-
import java.util.BitSet;
3635
import java.util.List;
3736

3837
import org.graalvm.collections.Pair;
@@ -75,6 +74,10 @@
7574
*/
7675
public class LinearScan {
7776

77+
protected boolean isDetailedAsserts() {
78+
return Assertions.assertionsEnabled() && detailedAsserts;
79+
}
80+
7881
public static class Options {
7982
// @formatter:off
8083
@Option(help = "Enable spill position optimization", type = OptionType.Debug)
@@ -90,28 +93,34 @@ public static class BlockData {
9093
* block. The bit index of an operand is its {@linkplain LinearScan#operandNumber(Value)
9194
* operand number}.
9295
*/
93-
public BitSet liveIn;
96+
public SparseBitSet liveIn;
9497

9598
/**
9699
* Bit map specifying which operands are live upon exit from this block. These are values
97100
* used in a successor block that are either defined in this block or were live upon entry
98101
* to this block. The bit index of an operand is its
99102
* {@linkplain LinearScan#operandNumber(Value) operand number}.
100103
*/
101-
public BitSet liveOut;
104+
public SparseBitSet liveOut;
102105

103106
/**
104107
* Bit map specifying which operands are used (before being defined) in this block. That is,
105108
* these are the values that are live upon entry to the block. The bit index of an operand
106109
* is its {@linkplain LinearScan#operandNumber(Value) operand number}.
107110
*/
108-
public BitSet liveGen;
111+
public SparseBitSet liveGen;
109112

110113
/**
111114
* Bit map specifying which operands are defined/overwritten in this block. The bit index of
112115
* an operand is its {@linkplain LinearScan#operandNumber(Value) operand number}.
113116
*/
114-
public BitSet liveKill;
117+
public SparseBitSet liveKill;
118+
119+
/**
120+
* State used during {@link LinearScanLifetimeAnalysisPhase#computeGlobalLiveSets()} to
121+
* create a worklist.
122+
*/
123+
boolean dirty = true;
115124
}
116125

117126
public static final int DOMINATOR_SPILL_MOVE_ID = -2;
@@ -160,14 +169,14 @@ public static class BlockData {
160169
private Interval[] sortedIntervals;
161170

162171
/**
163-
* Map from an instruction {@linkplain LIRInstruction#id id} to the instruction. Entries should
164-
* be retrieved with {@link #instructionForId(int)} as the id is not simply an index into this
165-
* array.
172+
* Map from an instruction {@linkplain LIRInstruction#id() id} to the instruction. Entries
173+
* should be retrieved with {@link #instructionForId(int)} as the id is not simply an index into
174+
* this array.
166175
*/
167176
private LIRInstruction[] opIdToInstructionMap;
168177

169178
/**
170-
* Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain BasicBlock
179+
* Map from an instruction {@linkplain LIRInstruction#id() id} to the {@linkplain BasicBlock
171180
* block} containing the instruction. Entries should be retrieved with {@link #blockForId(int)}
172181
* as the id is not simply an index into this array.
173182
*/
@@ -188,7 +197,7 @@ public static class BlockData {
188197
*/
189198
protected final Interval intervalEndMarker;
190199
public final Range rangeEndMarker;
191-
public final boolean detailedAsserts;
200+
private final boolean detailedAsserts;
192201
private final LIRGenerationResult res;
193202

194203
@SuppressWarnings("this-escape")
@@ -461,7 +470,7 @@ int maxOpId() {
461470
}
462471

463472
/**
464-
* Converts an {@linkplain LIRInstruction#id instruction id} to an instruction index. All LIR
473+
* Converts an {@linkplain LIRInstruction#id() instruction id} to an instruction index. All LIR
465474
* instructions in a method have an index one greater than their linear-scan order predecessor
466475
* with the first instruction having an index of 0.
467476
*/
@@ -470,10 +479,10 @@ private static int opIdToIndex(int opId) {
470479
}
471480

472481
/**
473-
* Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id id}.
482+
* Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id() id}.
474483
*
475-
* @param opId an instruction {@linkplain LIRInstruction#id id}
476-
* @return the instruction whose {@linkplain LIRInstruction#id} {@code == id}
484+
* @param opId an instruction {@linkplain LIRInstruction#id() id}
485+
* @return the instruction whose {@linkplain LIRInstruction#id()} {@code == id}
477486
*/
478487
public LIRInstruction instructionForId(int opId) {
479488
assert isEven(opId) : "opId not even";
@@ -485,7 +494,7 @@ public LIRInstruction instructionForId(int opId) {
485494
/**
486495
* Gets the block containing a given instruction.
487496
*
488-
* @param opId an instruction {@linkplain LIRInstruction#id id}
497+
* @param opId an instruction {@linkplain LIRInstruction#id() id}
489498
* @return the block containing the instruction denoted by {@code opId}
490499
*/
491500
public BasicBlock<?> blockForId(int opId) {
@@ -500,7 +509,7 @@ boolean isBlockBegin(int opId) {
500509
/**
501510
* Determines if an {@link LIRInstruction} destroys all caller saved registers.
502511
*
503-
* @param opId an instruction {@linkplain LIRInstruction#id id}
512+
* @param opId an instruction {@linkplain LIRInstruction#id() id}
504513
* @return {@code true} if the instruction denoted by {@code id} destroys all caller saved
505514
* registers.
506515
*/
@@ -740,14 +749,14 @@ protected void allocate(TargetDescription target, LIRGenerationResult lirGenRes,
740749

741750
sortIntervalsAfterAllocation();
742751

743-
if (detailedAsserts) {
752+
if (isDetailedAsserts()) {
744753
verify();
745754
}
746755
beforeSpillMoveElimination();
747756
createSpillMoveEliminationPhase().apply(target, lirGenRes, context);
748757
createAssignLocationsPhase().apply(target, lirGenRes, context);
749758

750-
if (detailedAsserts) {
759+
if (isDetailedAsserts()) {
751760
verifyIntervals();
752761
}
753762
} catch (Throwable e) {

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanAllocationPhase.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,12 @@
2424
*/
2525
package jdk.graal.compiler.lir.alloc.lsra;
2626

27-
import jdk.graal.compiler.debug.DebugContext;
28-
import jdk.graal.compiler.debug.DebugContext.CompilerPhaseScope;
29-
import jdk.graal.compiler.lir.gen.LIRGenerationResult;
3027
import jdk.graal.compiler.lir.phases.AllocationPhase;
3128
import jdk.graal.compiler.lir.phases.LIRPhase;
32-
import jdk.vm.ci.code.TargetDescription;
33-
34-
abstract class LinearScanAllocationPhase {
35-
36-
final CharSequence getName() {
37-
return LIRPhase.createName(getClass());
38-
}
3929

30+
abstract class LinearScanAllocationPhase extends LIRPhase<AllocationPhase.AllocationContext> {
4031
@Override
4132
public final String toString() {
4233
return getName().toString();
4334
}
44-
45-
public final void apply(TargetDescription target, LIRGenerationResult lirGenRes, AllocationPhase.AllocationContext context) {
46-
apply(target, lirGenRes, context, true);
47-
}
48-
49-
@SuppressWarnings("try")
50-
public final void apply(TargetDescription target, LIRGenerationResult lirGenRes, AllocationPhase.AllocationContext context, boolean dumpLIR) {
51-
DebugContext debug = lirGenRes.getLIR().getDebug();
52-
CharSequence name = getName();
53-
try (DebugContext.Scope s = debug.scope(name, this); CompilerPhaseScope cps = debug.enterCompilerPhase(name, null)) {
54-
run(target, lirGenRes, context);
55-
if (dumpLIR) {
56-
if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
57-
debug.dump(DebugContext.VERBOSE_LEVEL, lirGenRes.getLIR(), "After %s", name);
58-
}
59-
}
60-
} catch (Throwable e) {
61-
throw debug.handle(e);
62-
}
63-
}
64-
65-
protected abstract void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationPhase.AllocationContext context);
66-
6735
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanAssignLocationsPhase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ protected Value colorLirOperand(LIRInstruction op, Variable operand, LIRInstruct
7979
assert interval != null : "interval must exist";
8080

8181
if (opId != -1) {
82-
if (allocator.detailedAsserts) {
82+
if (allocator.isDetailedAsserts()) {
8383
BasicBlock<?> block = allocator.blockForId(opId);
8484
if (block.getSuccessorCount() <= 1 && opId == allocator.getLastLirInstructionId(block)) {
8585
/*

0 commit comments

Comments
 (0)