46 import java.util.ArrayList;
47 import java.util.HashSet;
48 import java.util.Set;
49 import java.util.concurrent.ConcurrentHashMap;
50
51 import jdk.internal.vm.compiler.collections.EconomicMap;
52 import jdk.internal.vm.compiler.collections.EconomicSet;
53 import jdk.internal.vm.compiler.collections.Equivalence;
54 import org.graalvm.compiler.asm.Assembler;
55 import org.graalvm.compiler.asm.Label;
56 import org.graalvm.compiler.asm.sparc.SPARCAddress;
57 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
58 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
59 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
60 import org.graalvm.compiler.code.CompilationResult;
61 import org.graalvm.compiler.code.DataSection;
62 import org.graalvm.compiler.code.DataSection.Data;
63 import org.graalvm.compiler.core.common.CompilationIdentifier;
64 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
65 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
66 import org.graalvm.compiler.core.sparc.SPARCNodeMatchRules;
67 import org.graalvm.compiler.debug.CounterKey;
68 import org.graalvm.compiler.debug.DebugContext;
69 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
70 import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
71 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
72 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
73 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
74 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
75 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
76 import org.graalvm.compiler.hotspot.stubs.Stub;
77 import org.graalvm.compiler.lir.InstructionValueConsumer;
78 import org.graalvm.compiler.lir.LIR;
79 import org.graalvm.compiler.lir.LIRFrameState;
80 import org.graalvm.compiler.lir.LIRInstruction;
81 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
82 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
83 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
84 import org.graalvm.compiler.lir.asm.DataBuilder;
85 import org.graalvm.compiler.lir.asm.FrameContext;
92 import org.graalvm.compiler.lir.sparc.SPARCFrameMap;
93 import org.graalvm.compiler.lir.sparc.SPARCFrameMapBuilder;
94 import org.graalvm.compiler.lir.sparc.SPARCLIRInstructionMixin;
95 import org.graalvm.compiler.lir.sparc.SPARCLIRInstructionMixin.SizeEstimate;
96 import org.graalvm.compiler.lir.sparc.SPARCTailDelayedLIRInstruction;
97 import org.graalvm.compiler.nodes.StructuredGraph;
98 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
99 import org.graalvm.compiler.options.OptionValues;
100
101 import jdk.vm.ci.code.CallingConvention;
102 import jdk.vm.ci.code.Register;
103 import jdk.vm.ci.code.RegisterConfig;
104 import jdk.vm.ci.code.StackSlot;
105 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
106 import jdk.vm.ci.meta.JavaType;
107 import jdk.vm.ci.meta.ResolvedJavaMethod;
108
109 /**
110 * HotSpot SPARC specific backend.
111 */
112 public class SPARCHotSpotBackend extends HotSpotHostBackend {
113
114 private static final SizeEstimateStatistics CONSTANT_ESTIMATED_STATS = new SizeEstimateStatistics("ESTIMATE");
115 private static final SizeEstimateStatistics CONSTANT_ACTUAL_STATS = new SizeEstimateStatistics("ACTUAL");
116
117 public SPARCHotSpotBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
118 super(config, runtime, providers);
119 }
120
121 private static class SizeEstimateStatistics {
122 private static final ConcurrentHashMap<String, CounterKey> counters = new ConcurrentHashMap<>();
123 private final String suffix;
124
125 SizeEstimateStatistics(String suffix) {
126 super();
127 this.suffix = suffix;
128 }
129
130 public void add(Class<?> c, int count, DebugContext debug) {
131 String name = SizeEstimateStatistics.class.getSimpleName() + "_" + c.getSimpleName() + "." + suffix;
132 CounterKey m = counters.computeIfAbsent(name, (n) -> DebugContext.counter(n));
133 m.add(debug, count);
134 }
135 }
136
137 @Override
138 public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
139 RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
140 return new SPARCFrameMapBuilder(newFrameMap(registerConfigNonNull), getCodeCache(), registerConfigNonNull);
141 }
142
143 @Override
144 public FrameMap newFrameMap(RegisterConfig registerConfig) {
145 return new SPARCFrameMap(getCodeCache(), registerConfig, this);
146 }
147
148 @Override
149 public LIRGeneratorTool newLIRGenerator(LIRGenerationResult lirGenRes) {
150 return new SPARCHotSpotLIRGenerator(getProviders(), getRuntime().getVMConfig(), lirGenRes);
151 }
152
153 @Override
154 public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph, Object stub) {
155 return new HotSpotLIRGenerationResult(compilationId, lir, frameMapBuilder, makeCallingConvention(graph, (Stub) stub), stub, config.requiresReservedStackCheck(graph.getMethods()));
156 }
157
158 @Override
159 public NodeLIRBuilderTool newNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen) {
160 return new SPARCHotSpotNodeLIRBuilder(graph, lirGen, new SPARCNodeMatchRules(lirGen));
161 }
162
163 @Override
164 protected void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset) {
165 // Use SPARCAddress to get the final displacement including the stack bias.
166 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
167 SPARCAddress address = new SPARCAddress(sp, -bangOffset);
168 if (SPARCAssembler.isSimm13(address.getDisplacement())) {
169 masm.stx(g0, address);
170 } else {
171 try (ScratchRegister sc = masm.getScratchRegister()) {
172 Register scratch = sc.getRegister();
173 assert isGlobalRegister(scratch) : "Only global (g1-g7) registers are allowed if the frame was not initialized here. Got register " + scratch;
174 masm.setx(address.getDisplacement(), scratch, false);
175 masm.stx(g0, new SPARCAddress(sp, scratch));
210 }
211 }
212
213 if (ZapStackOnMethodEntry.getValue(crb.getOptions())) {
214 final int slotSize = 8;
215 for (int i = 0; i < frameSize / slotSize; ++i) {
216 // 0xC1C1C1C1
217 masm.stx(g0, new SPARCAddress(sp, i * slotSize));
218 }
219 }
220 }
221
222 @Override
223 public void leave(CompilationResultBuilder crb) {
224 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
225 masm.restoreWindow();
226 }
227 }
228
229 @Override
230 protected Assembler createAssembler(FrameMap frameMap) {
231 return new SPARCMacroAssembler(getTarget());
232 }
233
234 @Override
235 public CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenRes, FrameMap frameMap, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
236 HotSpotLIRGenerationResult gen = (HotSpotLIRGenerationResult) lirGenRes;
237 LIR lir = gen.getLIR();
238 assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
239
240 Stub stub = gen.getStub();
241 Assembler masm = createAssembler(frameMap);
242 // On SPARC we always use stack frames.
243 HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
244 DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget());
245 OptionValues options = lir.getOptions();
246 DebugContext debug = lir.getDebug();
247 CompilationResultBuilder crb = factory.createBuilder(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, dataBuilder, frameContext, options, debug,
248 compilationResult, Register.None);
249 crb.setTotalFrameSize(frameMap.totalFrameSize());
250 crb.setMaxInterpreterFrameSize(gen.getMaxInterpreterFrameSize());
251 StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot();
252 if (deoptimizationRescueSlot != null && stub == null) {
253 crb.compilationResult.setCustomStackAreaOffset(deoptimizationRescueSlot);
254 }
255
256 if (stub != null) {
257 // Even on sparc we need to save floating point registers
258 EconomicSet<Register> destroyedCallerRegisters = gatherDestroyedCallerRegisters(lir);
259 EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = gen.getCalleeSaveInfo();
260 updateStub(stub, destroyedCallerRegisters, calleeSaveInfo, frameMap);
261 }
|
46 import java.util.ArrayList;
47 import java.util.HashSet;
48 import java.util.Set;
49 import java.util.concurrent.ConcurrentHashMap;
50
51 import jdk.internal.vm.compiler.collections.EconomicMap;
52 import jdk.internal.vm.compiler.collections.EconomicSet;
53 import jdk.internal.vm.compiler.collections.Equivalence;
54 import org.graalvm.compiler.asm.Assembler;
55 import org.graalvm.compiler.asm.Label;
56 import org.graalvm.compiler.asm.sparc.SPARCAddress;
57 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
58 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
59 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
60 import org.graalvm.compiler.code.CompilationResult;
61 import org.graalvm.compiler.code.DataSection;
62 import org.graalvm.compiler.code.DataSection.Data;
63 import org.graalvm.compiler.core.common.CompilationIdentifier;
64 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
65 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
66 import org.graalvm.compiler.core.gen.LIRGenerationProvider;
67 import org.graalvm.compiler.core.sparc.SPARCNodeMatchRules;
68 import org.graalvm.compiler.debug.CounterKey;
69 import org.graalvm.compiler.debug.DebugContext;
70 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
71 import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
72 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
73 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
74 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
75 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
76 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
77 import org.graalvm.compiler.hotspot.stubs.Stub;
78 import org.graalvm.compiler.lir.InstructionValueConsumer;
79 import org.graalvm.compiler.lir.LIR;
80 import org.graalvm.compiler.lir.LIRFrameState;
81 import org.graalvm.compiler.lir.LIRInstruction;
82 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
83 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
84 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
85 import org.graalvm.compiler.lir.asm.DataBuilder;
86 import org.graalvm.compiler.lir.asm.FrameContext;
93 import org.graalvm.compiler.lir.sparc.SPARCFrameMap;
94 import org.graalvm.compiler.lir.sparc.SPARCFrameMapBuilder;
95 import org.graalvm.compiler.lir.sparc.SPARCLIRInstructionMixin;
96 import org.graalvm.compiler.lir.sparc.SPARCLIRInstructionMixin.SizeEstimate;
97 import org.graalvm.compiler.lir.sparc.SPARCTailDelayedLIRInstruction;
98 import org.graalvm.compiler.nodes.StructuredGraph;
99 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
100 import org.graalvm.compiler.options.OptionValues;
101
102 import jdk.vm.ci.code.CallingConvention;
103 import jdk.vm.ci.code.Register;
104 import jdk.vm.ci.code.RegisterConfig;
105 import jdk.vm.ci.code.StackSlot;
106 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
107 import jdk.vm.ci.meta.JavaType;
108 import jdk.vm.ci.meta.ResolvedJavaMethod;
109
110 /**
111 * HotSpot SPARC specific backend.
112 */
113 public class SPARCHotSpotBackend extends HotSpotHostBackend implements LIRGenerationProvider {
114
115 private static final SizeEstimateStatistics CONSTANT_ESTIMATED_STATS = new SizeEstimateStatistics("ESTIMATE");
116 private static final SizeEstimateStatistics CONSTANT_ACTUAL_STATS = new SizeEstimateStatistics("ACTUAL");
117
118 public SPARCHotSpotBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
119 super(config, runtime, providers);
120 }
121
122 private static class SizeEstimateStatistics {
123 private static final ConcurrentHashMap<String, CounterKey> counters = new ConcurrentHashMap<>();
124 private final String suffix;
125
126 SizeEstimateStatistics(String suffix) {
127 super();
128 this.suffix = suffix;
129 }
130
131 public void add(Class<?> c, int count, DebugContext debug) {
132 String name = SizeEstimateStatistics.class.getSimpleName() + "_" + c.getSimpleName() + "." + suffix;
133 CounterKey m = counters.computeIfAbsent(name, (n) -> DebugContext.counter(n));
134 m.add(debug, count);
135 }
136 }
137
138 private FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
139 RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
140 FrameMap frameMap = new SPARCFrameMap(getCodeCache(), registerConfigNonNull, this);
141 return new SPARCFrameMapBuilder(frameMap, getCodeCache(), registerConfigNonNull);
142 }
143
144 @Override
145 public LIRGeneratorTool newLIRGenerator(LIRGenerationResult lirGenRes) {
146 return new SPARCHotSpotLIRGenerator(getProviders(), getRuntime().getVMConfig(), lirGenRes);
147 }
148
149 @Override
150 public LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, RegisterConfig registerConfig, StructuredGraph graph, Object stub) {
151 return new HotSpotLIRGenerationResult(compilationId, lir, newFrameMapBuilder(registerConfig), makeCallingConvention(graph, (Stub) stub), stub,
152 config.requiresReservedStackCheck(graph.getMethods()));
153 }
154
155 @Override
156 public NodeLIRBuilderTool newNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen) {
157 return new SPARCHotSpotNodeLIRBuilder(graph, lirGen, new SPARCNodeMatchRules(lirGen));
158 }
159
160 @Override
161 protected void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset) {
162 // Use SPARCAddress to get the final displacement including the stack bias.
163 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
164 SPARCAddress address = new SPARCAddress(sp, -bangOffset);
165 if (SPARCAssembler.isSimm13(address.getDisplacement())) {
166 masm.stx(g0, address);
167 } else {
168 try (ScratchRegister sc = masm.getScratchRegister()) {
169 Register scratch = sc.getRegister();
170 assert isGlobalRegister(scratch) : "Only global (g1-g7) registers are allowed if the frame was not initialized here. Got register " + scratch;
171 masm.setx(address.getDisplacement(), scratch, false);
172 masm.stx(g0, new SPARCAddress(sp, scratch));
207 }
208 }
209
210 if (ZapStackOnMethodEntry.getValue(crb.getOptions())) {
211 final int slotSize = 8;
212 for (int i = 0; i < frameSize / slotSize; ++i) {
213 // 0xC1C1C1C1
214 masm.stx(g0, new SPARCAddress(sp, i * slotSize));
215 }
216 }
217 }
218
219 @Override
220 public void leave(CompilationResultBuilder crb) {
221 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
222 masm.restoreWindow();
223 }
224 }
225
226 @Override
227 public CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenRes, FrameMap frameMap, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
228 HotSpotLIRGenerationResult gen = (HotSpotLIRGenerationResult) lirGenRes;
229 LIR lir = gen.getLIR();
230 assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
231
232 Stub stub = gen.getStub();
233 Assembler masm = new SPARCMacroAssembler(getTarget());
234 // On SPARC we always use stack frames.
235 HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
236 DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget());
237 OptionValues options = lir.getOptions();
238 DebugContext debug = lir.getDebug();
239 CompilationResultBuilder crb = factory.createBuilder(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, dataBuilder, frameContext, options, debug,
240 compilationResult, Register.None);
241 crb.setTotalFrameSize(frameMap.totalFrameSize());
242 crb.setMaxInterpreterFrameSize(gen.getMaxInterpreterFrameSize());
243 StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot();
244 if (deoptimizationRescueSlot != null && stub == null) {
245 crb.compilationResult.setCustomStackAreaOffset(deoptimizationRescueSlot);
246 }
247
248 if (stub != null) {
249 // Even on sparc we need to save floating point registers
250 EconomicSet<Register> destroyedCallerRegisters = gatherDestroyedCallerRegisters(lir);
251 EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = gen.getCalleeSaveInfo();
252 updateStub(stub, destroyedCallerRegisters, calleeSaveInfo, frameMap);
253 }
|