src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java

Print this page




  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.core;
  24 
  25 import java.util.Collection;
  26 import java.util.List;
  27 
  28 import org.graalvm.compiler.code.CompilationResult;
  29 import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
  30 import org.graalvm.compiler.core.common.GraalOptions;
  31 import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder;
  32 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
  33 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  34 import org.graalvm.compiler.core.common.util.CompilationAlarm;
  35 import org.graalvm.compiler.core.target.Backend;
  36 import org.graalvm.compiler.debug.Debug;
  37 import org.graalvm.compiler.debug.Debug.Scope;
  38 import org.graalvm.compiler.debug.DebugCloseable;
  39 import org.graalvm.compiler.debug.DebugCounter;
  40 import org.graalvm.compiler.debug.DebugTimer;
  41 import org.graalvm.compiler.debug.GraalError;
  42 import org.graalvm.compiler.debug.MethodFilter;
  43 import org.graalvm.compiler.debug.internal.method.MethodMetricsRootScopeInfo;
  44 import org.graalvm.compiler.lir.LIR;
  45 import org.graalvm.compiler.lir.alloc.OutOfRegistersException;
  46 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
  47 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
  48 import org.graalvm.compiler.lir.framemap.FrameMap;
  49 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  50 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  51 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  52 import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
  53 import org.graalvm.compiler.lir.phases.LIRSuites;
  54 import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
  55 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
  56 import org.graalvm.compiler.nodes.StructuredGraph;
  57 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  58 import org.graalvm.compiler.nodes.cfg.Block;
  59 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  60 import org.graalvm.compiler.phases.OptimisticOptimizations;
  61 import org.graalvm.compiler.phases.PhaseSuite;
  62 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
  63 import org.graalvm.compiler.phases.tiers.HighTierContext;


  68 import org.graalvm.compiler.phases.util.Providers;
  69 import org.graalvm.util.EconomicSet;
  70 
  71 import jdk.vm.ci.code.RegisterConfig;
  72 import jdk.vm.ci.code.TargetDescription;
  73 import jdk.vm.ci.code.site.ConstantReference;
  74 import jdk.vm.ci.code.site.DataPatch;
  75 import jdk.vm.ci.meta.Assumptions;
  76 import jdk.vm.ci.meta.JavaConstant;
  77 import jdk.vm.ci.meta.JavaKind;
  78 import jdk.vm.ci.meta.ProfilingInfo;
  79 import jdk.vm.ci.meta.ResolvedJavaField;
  80 import jdk.vm.ci.meta.ResolvedJavaMethod;
  81 import jdk.vm.ci.meta.VMConstant;
  82 
  83 /**
  84  * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}.
  85  */
  86 public class GraalCompiler {
  87 
  88     private static final DebugTimer CompilerTimer = Debug.timer("GraalCompiler");
  89     private static final DebugTimer FrontEnd = Debug.timer("FrontEnd");
  90     private static final DebugTimer BackEnd = Debug.timer("BackEnd");
  91     private static final DebugTimer EmitLIR = Debug.timer("EmitLIR");
  92     private static final DebugTimer EmitCode = Debug.timer("EmitCode");
  93 
  94     /**
  95      * Encapsulates all the inputs to a {@linkplain GraalCompiler#compile(Request) compilation}.
  96      */
  97     public static class Request<T extends CompilationResult> {
  98         public final StructuredGraph graph;
  99         public final ResolvedJavaMethod installedCodeOwner;
 100         public final Providers providers;
 101         public final Backend backend;
 102         public final PhaseSuite<HighTierContext> graphBuilderSuite;
 103         public final OptimisticOptimizations optimisticOpts;
 104         public final ProfilingInfo profilingInfo;
 105         public final Suites suites;
 106         public final LIRSuites lirSuites;
 107         public final T compilationResult;
 108         public final CompilationResultBuilderFactory factory;
 109 
 110         /**
 111          * @param graph the graph to be compiled
 112          * @param installedCodeOwner the method the compiled code will be associated with once


 150      * Requests compilation of a given graph.
 151      *
 152      * @param graph the graph to be compiled
 153      * @param installedCodeOwner the method the compiled code will be associated with once
 154      *            installed. This argument can be null.
 155      * @return the result of the compilation
 156      */
 157     public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
 158                     PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, Suites suites, LIRSuites lirSuites, T compilationResult,
 159                     CompilationResultBuilderFactory factory) {
 160         return compile(new Request<>(graph, installedCodeOwner, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, compilationResult, factory));
 161     }
 162 
 163     /**
 164      * Services a given compilation request.
 165      *
 166      * @return the result of the compilation
 167      */
 168     @SuppressWarnings("try")
 169     public static <T extends CompilationResult> T compile(Request<T> r) {
 170         try (Scope s = MethodMetricsRootScopeInfo.createRootScopeIfAbsent(r.installedCodeOwner);
 171                         CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(r.graph.getOptions())) {
 172             assert !r.graph.isFrozen();
 173             try (Scope s0 = Debug.scope("GraalCompiler", r.graph, r.providers.getCodeCache()); DebugCloseable a = CompilerTimer.start()) {
 174                 emitFrontEnd(r.providers, r.backend, r.graph, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.suites);
 175                 emitBackEnd(r.graph, null, r.installedCodeOwner, r.backend, r.compilationResult, r.factory, null, r.lirSuites);
 176             } catch (Throwable e) {
 177                 throw Debug.handle(e);
 178             }
 179             checkForRequestedCrash(r.graph);
 180             return r.compilationResult;
 181         }
 182     }
 183 
 184     /**
 185      * Checks whether the {@link GraalCompilerOptions#CrashAt} option indicates that the compilation
 186      * of {@code graph} should result in an exception.
 187      *
 188      * @param graph a graph currently being compiled
 189      * @throws RuntimeException if the value of {@link GraalCompilerOptions#CrashAt} matches
 190      *             {@code graph.method()} or {@code graph.name}
 191      */
 192     private static void checkForRequestedCrash(StructuredGraph graph) {
 193         String methodPattern = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
 194         if (methodPattern != null) {
 195             String crashLabel = null;
 196             if (graph.name != null && graph.name.contains(methodPattern)) {
 197                 crashLabel = graph.name;


 200                 ResolvedJavaMethod method = graph.method();
 201                 MethodFilter[] filters = MethodFilter.parse(methodPattern);
 202                 for (MethodFilter filter : filters) {
 203                     if (filter.matches(method)) {
 204                         crashLabel = method.format("%H.%n(%p)");
 205                     }
 206                 }
 207             }
 208             if (crashLabel != null) {
 209                 throw new RuntimeException("Forced crash after compiling " + crashLabel);
 210             }
 211         }
 212     }
 213 
 214     /**
 215      * Builds the graph, optimizes it.
 216      */
 217     @SuppressWarnings("try")
 218     public static void emitFrontEnd(Providers providers, TargetProvider target, StructuredGraph graph, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts,
 219                     ProfilingInfo profilingInfo, Suites suites) {
 220         try (Scope s = Debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start()) {

 221             HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts);
 222             if (graph.start().next() == null) {
 223                 graphBuilderSuite.apply(graph, highTierContext);
 224                 new DeadCodeEliminationPhase(DeadCodeEliminationPhase.Optionality.Optional).apply(graph);
 225                 Debug.dump(Debug.BASIC_LEVEL, graph, "After parsing");
 226             } else {
 227                 Debug.dump(Debug.INFO_LEVEL, graph, "initial state");
 228             }
 229 
 230             suites.getHighTier().apply(graph, highTierContext);
 231             graph.maybeCompress();
 232             Debug.dump(Debug.BASIC_LEVEL, graph, "After high tier");
 233 
 234             MidTierContext midTierContext = new MidTierContext(providers, target, optimisticOpts, profilingInfo);
 235             suites.getMidTier().apply(graph, midTierContext);
 236             graph.maybeCompress();
 237             Debug.dump(Debug.BASIC_LEVEL, graph, "After mid tier");
 238 
 239             LowTierContext lowTierContext = new LowTierContext(providers, target);
 240             suites.getLowTier().apply(graph, lowTierContext);
 241             Debug.dump(Debug.BASIC_LEVEL, graph, "After low tier");
 242 
 243             Debug.dump(Debug.BASIC_LEVEL, graph.getLastSchedule(), "Final HIR schedule");
 244         } catch (Throwable e) {
 245             throw Debug.handle(e);
 246         } finally {
 247             graph.checkCancellation();
 248         }
 249     }
 250 
 251     @SuppressWarnings("try")
 252     public static <T extends CompilationResult> void emitBackEnd(StructuredGraph graph, Object stub, ResolvedJavaMethod installedCodeOwner, Backend backend, T compilationResult,
 253                     CompilationResultBuilderFactory factory, RegisterConfig registerConfig, LIRSuites lirSuites) {
 254         try (Scope s = Debug.scope("BackEnd", graph.getLastSchedule()); DebugCloseable a = BackEnd.start()) {

 255             LIRGenerationResult lirGen = null;
 256             lirGen = emitLIR(backend, graph, stub, registerConfig, lirSuites);
 257             try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) {
 258                 int bytecodeSize = graph.method() == null ? 0 : graph.getBytecodeSize();
 259                 compilationResult.setHasUnsafeAccess(graph.hasUnsafeAccess());
 260                 emitCode(backend, graph.getAssumptions(), graph.method(), graph.getMethods(), graph.getFields(), bytecodeSize, lirGen, compilationResult, installedCodeOwner, factory);
 261             } catch (Throwable e) {
 262                 throw Debug.handle(e);
 263             }
 264         } catch (Throwable e) {
 265             throw Debug.handle(e);
 266         } finally {
 267             graph.checkCancellation();
 268         }
 269     }
 270 
 271     @SuppressWarnings("try")
 272     public static LIRGenerationResult emitLIR(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites) {
 273         String registerPressure = GraalOptions.RegisterPressure.getValue(graph.getOptions());
 274         String[] allocationRestrictedTo = registerPressure == null ? null : registerPressure.split(",");
 275         try {
 276             return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo);
 277         } catch (OutOfRegistersException e) {
 278             if (allocationRestrictedTo != null) {
 279                 allocationRestrictedTo = null;
 280                 return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo);
 281             }
 282             /* If the re-execution fails we convert the exception into a "hard" failure */
 283             throw new GraalError(e);
 284         } finally {
 285             graph.checkCancellation();
 286         }
 287     }
 288 
 289     @SuppressWarnings("try")
 290     private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites,
 291                     String[] allocationRestrictedTo) {
 292         try (Scope ds = Debug.scope("EmitLIR"); DebugCloseable a = EmitLIR.start()) {

 293             assert !graph.hasValueProxies();
 294             ScheduleResult schedule = graph.getLastSchedule();
 295             Block[] blocks = schedule.getCFG().getBlocks();
 296             Block startBlock = schedule.getCFG().getStartBlock();
 297             assert startBlock != null;
 298             assert startBlock.getPredecessorCount() == 0;
 299 
 300             AbstractBlockBase<?>[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock);
 301             AbstractBlockBase<?>[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock);
 302             LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions());
 303 
 304             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
 305             LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub);
 306             LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes);
 307             NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
 308 
 309             // LIR generation
 310             LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
 311             new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
 312 
 313             try (Scope s = Debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
 314                 // Dump LIR along with HIR (the LIR is looked up from context)
 315                 Debug.dump(Debug.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
 316                 LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
 317                 return result;
 318             } catch (Throwable e) {
 319                 throw Debug.handle(e);
 320             }
 321         } catch (Throwable e) {
 322             throw Debug.handle(e);
 323         } finally {
 324             graph.checkCancellation();
 325         }
 326     }
 327 
 328     protected static <T extends CompilationResult> String getCompilationUnitName(StructuredGraph graph, T compilationResult) {
 329         if (compilationResult != null && compilationResult.getName() != null) {
 330             return compilationResult.getName();
 331         }
 332         ResolvedJavaMethod method = graph.method();
 333         if (method == null) {
 334             return "<unknown>";
 335         }
 336         return method.format("%H.%n(%p)");
 337     }
 338 
 339     public static LIRGenerationResult emitLowLevel(TargetDescription target, LIRGenerationResult lirGenRes, LIRGeneratorTool lirGen, LIRSuites lirSuites,
 340                     RegisterAllocationConfig registerAllocationConfig) {

 341         PreAllocationOptimizationContext preAllocOptContext = new PreAllocationOptimizationContext(lirGen);
 342         lirSuites.getPreAllocationOptimizationStage().apply(target, lirGenRes, preAllocOptContext);
 343         Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After PreAllocationOptimizationStage");
 344 
 345         AllocationContext allocContext = new AllocationContext(lirGen.getSpillMoveFactory(), registerAllocationConfig);
 346         lirSuites.getAllocationStage().apply(target, lirGenRes, allocContext);
 347         Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After AllocationStage");
 348 
 349         PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(lirGen);
 350         lirSuites.getPostAllocationOptimizationStage().apply(target, lirGenRes, postAllocOptContext);
 351         Debug.dump(Debug.BASIC_LEVEL, lirGenRes.getLIR(), "After PostAllocationOptimizationStage");
 352 
 353         return lirGenRes;
 354     }
 355 
 356     @SuppressWarnings("try")
 357     public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods, EconomicSet<ResolvedJavaField> accessedFields,
 358                     int bytecodeSize, LIRGenerationResult lirGenRes,
 359                     CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) {
 360         try (DebugCloseable a = EmitCode.start()) {

 361             FrameMap frameMap = lirGenRes.getFrameMap();
 362             CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory);
 363             backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner);
 364             if (assumptions != null && !assumptions.isEmpty()) {
 365                 compilationResult.setAssumptions(assumptions.toArray());
 366             }
 367             if (rootMethod != null) {
 368                 compilationResult.setMethods(rootMethod, inlinedMethods);
 369                 compilationResult.setFields(accessedFields);
 370                 compilationResult.setBytecodeSize(bytecodeSize);
 371             }
 372             crb.finish();
 373             if (Debug.isCountEnabled()) {
 374                 List<DataPatch> ldp = compilationResult.getDataPatches();
 375                 JavaKind[] kindValues = JavaKind.values();
 376                 DebugCounter[] dms = new DebugCounter[kindValues.length];
 377                 for (int i = 0; i < dms.length; i++) {
 378                     dms[i] = Debug.counter("DataPatches-%s", kindValues[i]);
 379                 }
 380 
 381                 for (DataPatch dp : ldp) {
 382                     JavaKind kind = JavaKind.Illegal;
 383                     if (dp.reference instanceof ConstantReference) {
 384                         VMConstant constant = ((ConstantReference) dp.reference).getConstant();
 385                         if (constant instanceof JavaConstant) {
 386                             kind = ((JavaConstant) constant).getJavaKind();
 387                         }
 388                     }
 389                     dms[kind.ordinal()].add(1);
 390                 }
 391 
 392                 Debug.counter("CompilationResults").increment();
 393                 Debug.counter("CodeBytesEmitted").add(compilationResult.getTargetCodeSize());
 394                 Debug.counter("InfopointsEmitted").add(compilationResult.getInfopoints().size());
 395                 Debug.counter("DataPatches").add(ldp.size());
 396                 Debug.counter("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size());
 397             }
 398 
 399             Debug.dump(Debug.BASIC_LEVEL, compilationResult, "After code generation");
 400         }
 401     }
 402 }


  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.core;
  24 
  25 import java.util.Collection;
  26 import java.util.List;
  27 
  28 import org.graalvm.compiler.code.CompilationResult;
  29 import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
  30 import org.graalvm.compiler.core.common.GraalOptions;
  31 import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder;
  32 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
  33 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  34 import org.graalvm.compiler.core.common.util.CompilationAlarm;
  35 import org.graalvm.compiler.core.target.Backend;
  36 import org.graalvm.compiler.debug.CounterKey;

  37 import org.graalvm.compiler.debug.DebugCloseable;
  38 import org.graalvm.compiler.debug.DebugContext;

  39 import org.graalvm.compiler.debug.GraalError;
  40 import org.graalvm.compiler.debug.MethodFilter;
  41 import org.graalvm.compiler.debug.TimerKey;
  42 import org.graalvm.compiler.lir.LIR;
  43 import org.graalvm.compiler.lir.alloc.OutOfRegistersException;
  44 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
  45 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
  46 import org.graalvm.compiler.lir.framemap.FrameMap;
  47 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  48 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  49 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  50 import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
  51 import org.graalvm.compiler.lir.phases.LIRSuites;
  52 import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
  53 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
  54 import org.graalvm.compiler.nodes.StructuredGraph;
  55 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  56 import org.graalvm.compiler.nodes.cfg.Block;
  57 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  58 import org.graalvm.compiler.phases.OptimisticOptimizations;
  59 import org.graalvm.compiler.phases.PhaseSuite;
  60 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
  61 import org.graalvm.compiler.phases.tiers.HighTierContext;


  66 import org.graalvm.compiler.phases.util.Providers;
  67 import org.graalvm.util.EconomicSet;
  68 
  69 import jdk.vm.ci.code.RegisterConfig;
  70 import jdk.vm.ci.code.TargetDescription;
  71 import jdk.vm.ci.code.site.ConstantReference;
  72 import jdk.vm.ci.code.site.DataPatch;
  73 import jdk.vm.ci.meta.Assumptions;
  74 import jdk.vm.ci.meta.JavaConstant;
  75 import jdk.vm.ci.meta.JavaKind;
  76 import jdk.vm.ci.meta.ProfilingInfo;
  77 import jdk.vm.ci.meta.ResolvedJavaField;
  78 import jdk.vm.ci.meta.ResolvedJavaMethod;
  79 import jdk.vm.ci.meta.VMConstant;
  80 
  81 /**
  82  * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}.
  83  */
  84 public class GraalCompiler {
  85 
  86     private static final TimerKey CompilerTimer = DebugContext.timer("GraalCompiler").doc("Time spent in compilation (excludes code installation).");
  87     private static final TimerKey FrontEnd = DebugContext.timer("FrontEnd").doc("Time spent processing HIR.");
  88     private static final TimerKey EmitLIR = DebugContext.timer("EmitLIR").doc("Time spent generating LIR from HIR.");
  89     private static final TimerKey EmitCode = DebugContext.timer("EmitCode").doc("Time spent generating machine code from LIR.");
  90     private static final TimerKey BackEnd = DebugContext.timer("BackEnd").doc("Time spent in EmitLIR and EmitCode.");
  91 
  92     /**
  93      * Encapsulates all the inputs to a {@linkplain GraalCompiler#compile(Request) compilation}.
  94      */
  95     public static class Request<T extends CompilationResult> {
  96         public final StructuredGraph graph;
  97         public final ResolvedJavaMethod installedCodeOwner;
  98         public final Providers providers;
  99         public final Backend backend;
 100         public final PhaseSuite<HighTierContext> graphBuilderSuite;
 101         public final OptimisticOptimizations optimisticOpts;
 102         public final ProfilingInfo profilingInfo;
 103         public final Suites suites;
 104         public final LIRSuites lirSuites;
 105         public final T compilationResult;
 106         public final CompilationResultBuilderFactory factory;
 107 
 108         /**
 109          * @param graph the graph to be compiled
 110          * @param installedCodeOwner the method the compiled code will be associated with once


 148      * Requests compilation of a given graph.
 149      *
 150      * @param graph the graph to be compiled
 151      * @param installedCodeOwner the method the compiled code will be associated with once
 152      *            installed. This argument can be null.
 153      * @return the result of the compilation
 154      */
 155     public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
 156                     PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, Suites suites, LIRSuites lirSuites, T compilationResult,
 157                     CompilationResultBuilderFactory factory) {
 158         return compile(new Request<>(graph, installedCodeOwner, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, compilationResult, factory));
 159     }
 160 
 161     /**
 162      * Services a given compilation request.
 163      *
 164      * @return the result of the compilation
 165      */
 166     @SuppressWarnings("try")
 167     public static <T extends CompilationResult> T compile(Request<T> r) {
 168         DebugContext debug = r.graph.getDebug();
 169         try (CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(r.graph.getOptions())) {
 170             assert !r.graph.isFrozen();
 171             try (DebugContext.Scope s0 = debug.scope("GraalCompiler", r.graph, r.providers.getCodeCache()); DebugCloseable a = CompilerTimer.start(debug)) {
 172                 emitFrontEnd(r.providers, r.backend, r.graph, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.suites);
 173                 emitBackEnd(r.graph, null, r.installedCodeOwner, r.backend, r.compilationResult, r.factory, null, r.lirSuites);
 174             } catch (Throwable e) {
 175                 throw debug.handle(e);
 176             }
 177             checkForRequestedCrash(r.graph);
 178             return r.compilationResult;
 179         }
 180     }
 181 
 182     /**
 183      * Checks whether the {@link GraalCompilerOptions#CrashAt} option indicates that the compilation
 184      * of {@code graph} should result in an exception.
 185      *
 186      * @param graph a graph currently being compiled
 187      * @throws RuntimeException if the value of {@link GraalCompilerOptions#CrashAt} matches
 188      *             {@code graph.method()} or {@code graph.name}
 189      */
 190     private static void checkForRequestedCrash(StructuredGraph graph) {
 191         String methodPattern = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
 192         if (methodPattern != null) {
 193             String crashLabel = null;
 194             if (graph.name != null && graph.name.contains(methodPattern)) {
 195                 crashLabel = graph.name;


 198                 ResolvedJavaMethod method = graph.method();
 199                 MethodFilter[] filters = MethodFilter.parse(methodPattern);
 200                 for (MethodFilter filter : filters) {
 201                     if (filter.matches(method)) {
 202                         crashLabel = method.format("%H.%n(%p)");
 203                     }
 204                 }
 205             }
 206             if (crashLabel != null) {
 207                 throw new RuntimeException("Forced crash after compiling " + crashLabel);
 208             }
 209         }
 210     }
 211 
 212     /**
 213      * Builds the graph, optimizes it.
 214      */
 215     @SuppressWarnings("try")
 216     public static void emitFrontEnd(Providers providers, TargetProvider target, StructuredGraph graph, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts,
 217                     ProfilingInfo profilingInfo, Suites suites) {
 218         DebugContext debug = graph.getDebug();
 219         try (DebugContext.Scope s = debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start(debug)) {
 220             HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts);
 221             if (graph.start().next() == null) {
 222                 graphBuilderSuite.apply(graph, highTierContext);
 223                 new DeadCodeEliminationPhase(DeadCodeEliminationPhase.Optionality.Optional).apply(graph);
 224                 debug.dump(DebugContext.BASIC_LEVEL, graph, "After parsing");
 225             } else {
 226                 debug.dump(DebugContext.INFO_LEVEL, graph, "initial state");
 227             }
 228 
 229             suites.getHighTier().apply(graph, highTierContext);
 230             graph.maybeCompress();
 231             debug.dump(DebugContext.BASIC_LEVEL, graph, "After high tier");
 232 
 233             MidTierContext midTierContext = new MidTierContext(providers, target, optimisticOpts, profilingInfo);
 234             suites.getMidTier().apply(graph, midTierContext);
 235             graph.maybeCompress();
 236             debug.dump(DebugContext.BASIC_LEVEL, graph, "After mid tier");
 237 
 238             LowTierContext lowTierContext = new LowTierContext(providers, target);
 239             suites.getLowTier().apply(graph, lowTierContext);
 240             debug.dump(DebugContext.BASIC_LEVEL, graph, "After low tier");
 241 
 242             debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "Final HIR schedule");
 243         } catch (Throwable e) {
 244             throw debug.handle(e);
 245         } finally {
 246             graph.checkCancellation();
 247         }
 248     }
 249 
 250     @SuppressWarnings("try")
 251     public static <T extends CompilationResult> void emitBackEnd(StructuredGraph graph, Object stub, ResolvedJavaMethod installedCodeOwner, Backend backend, T compilationResult,
 252                     CompilationResultBuilderFactory factory, RegisterConfig registerConfig, LIRSuites lirSuites) {
 253         DebugContext debug = graph.getDebug();
 254         try (DebugContext.Scope s = debug.scope("BackEnd", graph.getLastSchedule()); DebugCloseable a = BackEnd.start(debug)) {
 255             LIRGenerationResult lirGen = null;
 256             lirGen = emitLIR(backend, graph, stub, registerConfig, lirSuites);
 257             try (DebugContext.Scope s2 = debug.scope("CodeGen", lirGen, lirGen.getLIR())) {
 258                 int bytecodeSize = graph.method() == null ? 0 : graph.getBytecodeSize();
 259                 compilationResult.setHasUnsafeAccess(graph.hasUnsafeAccess());
 260                 emitCode(backend, graph.getAssumptions(), graph.method(), graph.getMethods(), graph.getFields(), bytecodeSize, lirGen, compilationResult, installedCodeOwner, factory);
 261             } catch (Throwable e) {
 262                 throw debug.handle(e);
 263             }
 264         } catch (Throwable e) {
 265             throw debug.handle(e);
 266         } finally {
 267             graph.checkCancellation();
 268         }
 269     }
 270 
 271     @SuppressWarnings("try")
 272     public static LIRGenerationResult emitLIR(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites) {
 273         String registerPressure = GraalOptions.RegisterPressure.getValue(graph.getOptions());
 274         String[] allocationRestrictedTo = registerPressure == null ? null : registerPressure.split(",");
 275         try {
 276             return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo);
 277         } catch (OutOfRegistersException e) {
 278             if (allocationRestrictedTo != null) {
 279                 allocationRestrictedTo = null;
 280                 return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo);
 281             }
 282             /* If the re-execution fails we convert the exception into a "hard" failure */
 283             throw new GraalError(e);
 284         } finally {
 285             graph.checkCancellation();
 286         }
 287     }
 288 
 289     @SuppressWarnings("try")
 290     private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites,
 291                     String[] allocationRestrictedTo) {
 292         DebugContext debug = graph.getDebug();
 293         try (DebugContext.Scope ds = debug.scope("EmitLIR"); DebugCloseable a = EmitLIR.start(debug)) {
 294             assert !graph.hasValueProxies();
 295             ScheduleResult schedule = graph.getLastSchedule();
 296             Block[] blocks = schedule.getCFG().getBlocks();
 297             Block startBlock = schedule.getCFG().getStartBlock();
 298             assert startBlock != null;
 299             assert startBlock.getPredecessorCount() == 0;
 300 
 301             AbstractBlockBase<?>[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock);
 302             AbstractBlockBase<?>[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock);
 303             LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions(), graph.getDebug());
 304 
 305             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
 306             LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub);
 307             LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes);
 308             NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
 309 
 310             // LIR generation
 311             LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
 312             new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
 313 
 314             try (DebugContext.Scope s = debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
 315                 // Dump LIR along with HIR (the LIR is looked up from context)
 316                 debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
 317                 LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
 318                 return result;
 319             } catch (Throwable e) {
 320                 throw debug.handle(e);
 321             }
 322         } catch (Throwable e) {
 323             throw debug.handle(e);
 324         } finally {
 325             graph.checkCancellation();
 326         }
 327     }
 328 
 329     protected static <T extends CompilationResult> String getCompilationUnitName(StructuredGraph graph, T compilationResult) {
 330         if (compilationResult != null && compilationResult.getName() != null) {
 331             return compilationResult.getName();
 332         }
 333         ResolvedJavaMethod method = graph.method();
 334         if (method == null) {
 335             return "<unknown>";
 336         }
 337         return method.format("%H.%n(%p)");
 338     }
 339 
 340     public static LIRGenerationResult emitLowLevel(TargetDescription target, LIRGenerationResult lirGenRes, LIRGeneratorTool lirGen, LIRSuites lirSuites,
 341                     RegisterAllocationConfig registerAllocationConfig) {
 342         DebugContext debug = lirGenRes.getLIR().getDebug();
 343         PreAllocationOptimizationContext preAllocOptContext = new PreAllocationOptimizationContext(lirGen);
 344         lirSuites.getPreAllocationOptimizationStage().apply(target, lirGenRes, preAllocOptContext);
 345         debug.dump(DebugContext.BASIC_LEVEL, lirGenRes.getLIR(), "After PreAllocationOptimizationStage");
 346 
 347         AllocationContext allocContext = new AllocationContext(lirGen.getSpillMoveFactory(), registerAllocationConfig);
 348         lirSuites.getAllocationStage().apply(target, lirGenRes, allocContext);
 349         debug.dump(DebugContext.BASIC_LEVEL, lirGenRes.getLIR(), "After AllocationStage");
 350 
 351         PostAllocationOptimizationContext postAllocOptContext = new PostAllocationOptimizationContext(lirGen);
 352         lirSuites.getPostAllocationOptimizationStage().apply(target, lirGenRes, postAllocOptContext);
 353         debug.dump(DebugContext.BASIC_LEVEL, lirGenRes.getLIR(), "After PostAllocationOptimizationStage");
 354 
 355         return lirGenRes;
 356     }
 357 
 358     @SuppressWarnings("try")
 359     public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods, EconomicSet<ResolvedJavaField> accessedFields,
 360                     int bytecodeSize, LIRGenerationResult lirGenRes,
 361                     CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) {
 362         DebugContext debug = lirGenRes.getLIR().getDebug();
 363         try (DebugCloseable a = EmitCode.start(debug)) {
 364             FrameMap frameMap = lirGenRes.getFrameMap();
 365             CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory);
 366             backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner);
 367             if (assumptions != null && !assumptions.isEmpty()) {
 368                 compilationResult.setAssumptions(assumptions.toArray());
 369             }
 370             if (rootMethod != null) {
 371                 compilationResult.setMethods(rootMethod, inlinedMethods);
 372                 compilationResult.setFields(accessedFields);
 373                 compilationResult.setBytecodeSize(bytecodeSize);
 374             }
 375             crb.finish();
 376             if (debug.isCountEnabled()) {
 377                 List<DataPatch> ldp = compilationResult.getDataPatches();
 378                 JavaKind[] kindValues = JavaKind.values();
 379                 CounterKey[] dms = new CounterKey[kindValues.length];
 380                 for (int i = 0; i < dms.length; i++) {
 381                     dms[i] = DebugContext.counter("DataPatches-%s", kindValues[i]);
 382                 }
 383 
 384                 for (DataPatch dp : ldp) {
 385                     JavaKind kind = JavaKind.Illegal;
 386                     if (dp.reference instanceof ConstantReference) {
 387                         VMConstant constant = ((ConstantReference) dp.reference).getConstant();
 388                         if (constant instanceof JavaConstant) {
 389                             kind = ((JavaConstant) constant).getJavaKind();
 390                         }
 391                     }
 392                     dms[kind.ordinal()].add(debug, 1);
 393                 }
 394 
 395                 DebugContext.counter("CompilationResults").increment(debug);
 396                 DebugContext.counter("CodeBytesEmitted").add(debug, compilationResult.getTargetCodeSize());
 397                 DebugContext.counter("InfopointsEmitted").add(debug, compilationResult.getInfopoints().size());
 398                 DebugContext.counter("DataPatches").add(debug, ldp.size());
 399                 DebugContext.counter("ExceptionHandlersEmitted").add(debug, compilationResult.getExceptionHandlers().size());
 400             }
 401 
 402             debug.dump(DebugContext.BASIC_LEVEL, compilationResult, "After code generation");
 403         }
 404     }
 405 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File