1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.microbenchmarks.lir.trace;
  24 
  25 import org.openjdk.jmh.annotations.Benchmark;
  26 import org.openjdk.jmh.annotations.Level;
  27 import org.openjdk.jmh.annotations.Param;
  28 import org.openjdk.jmh.annotations.Setup;
  29 
  30 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
  31 import org.graalvm.compiler.core.common.alloc.Trace;
  32 import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
  33 import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase;
  34 import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanLifetimeAnalysisPhase;
  35 import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanLifetimeAnalysisPhase.Analyser;
  36 import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase;
  37 import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan;
  38 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  39 import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
  40 import org.graalvm.compiler.lir.phases.AllocationPhase;
  41 import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext;
  42 import org.graalvm.compiler.lir.phases.LIRPhaseSuite;
  43 import org.graalvm.compiler.lir.phases.LIRSuites;
  44 import org.graalvm.compiler.lir.ssi.SSIConstructionPhase;
  45 import org.graalvm.compiler.microbenchmarks.graal.GraalBenchmark;
  46 import org.graalvm.compiler.microbenchmarks.lir.GraalCompilerState;
  47 
  48 import jdk.vm.ci.code.TargetDescription;
  49 
  50 /**
  51  * Benchmarks {@link TraceLinearScan TraceRA} {@link TraceLinearScanLifetimeAnalysisPhase lifetime
  52  * analysis phase}.
  53  */
  54 public class TraceLSRAIntervalBuildingBench extends GraalBenchmark {
  55 
  56     private static class DummyTraceAllocatorPhase extends AllocationPhase {
  57         private TraceLinearScan allocator;
  58 
  59         @Override
  60         @SuppressWarnings("try")
  61         protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
  62             MoveFactory spillMoveFactory = context.spillMoveFactory;
  63             RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig;
  64             TraceBuilderResult resultTraces = context.contextLookup(TraceBuilderResult.class);
  65             TraceLinearScanPhase phase = new TraceLinearScanPhase(target, lirGenRes, spillMoveFactory, registerAllocationConfig, resultTraces, false, null);
  66             for (Trace trace : resultTraces.getTraces()) {
  67                 allocator = phase.createAllocator(trace);
  68                 Analyser a = new TraceLinearScanLifetimeAnalysisPhase.Analyser(allocator, resultTraces);
  69                 a.analyze();
  70             }
  71         }
  72     }
  73 
  74     public abstract static class AllocationState extends GraalCompilerState {
  75 
  76         private static final DummyTraceAllocatorPhase LTA_PHASE = new DummyTraceAllocatorPhase();
  77         private static final SSIConstructionPhase SSI_CONSTRUCTION_PHASE = new SSIConstructionPhase();
  78         private static final TraceBuilderPhase TRACE_BUILDER_PHASE = new TraceBuilderPhase();
  79 
  80         private AllocationContext allocationContext;
  81 
  82         @Override
  83         protected LIRSuites getLIRSuites() {
  84             LIRSuites ls = super.getLIRSuites();
  85             LIRPhaseSuite<AllocationContext> allocationStage = new LIRPhaseSuite<>();
  86             allocationStage.appendPhase(TRACE_BUILDER_PHASE);
  87             allocationStage.appendPhase(SSI_CONSTRUCTION_PHASE);
  88             return new LIRSuites(ls.getPreAllocationOptimizationStage(), allocationStage, ls.getPostAllocationOptimizationStage());
  89         }
  90 
  91         @Setup(Level.Trial)
  92         public void setup() {
  93             initializeMethod();
  94             prepareRequest();
  95             emitFrontEnd();
  96             generateLIR();
  97             preAllocationStage();
  98             // context for all allocation phases
  99             allocationContext = createAllocationContext();
 100             applyLIRPhase(TRACE_BUILDER_PHASE, allocationContext);
 101             applyLIRPhase(SSI_CONSTRUCTION_PHASE, allocationContext);
 102         }
 103 
 104         public TraceLinearScan compile() {
 105             applyLIRPhase(LTA_PHASE, allocationContext);
 106             return LTA_PHASE.allocator;
 107         }
 108 
 109     }
 110 
 111     public static class State extends AllocationState {
 112         @MethodDescString @Param({
 113                         "java.lang.String#equals",
 114                         "java.util.HashMap#computeIfAbsent"
 115         }) public String method;
 116     }
 117 
 118     @Benchmark
 119     public TraceLinearScan buildIntervals(State s) {
 120         return s.compile();
 121     }
 122 }