001/* 002 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.hotspot.meta; 024 025import static com.oracle.graal.compiler.common.GraalOptions.*; 026import jdk.internal.jvmci.hotspot.*; 027import jdk.internal.jvmci.options.*; 028import jdk.internal.jvmci.options.DerivedOptionValue.*; 029 030import com.oracle.graal.graphbuilderconf.*; 031import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.DebugInfoMode; 032import com.oracle.graal.hotspot.*; 033import com.oracle.graal.hotspot.phases.*; 034import com.oracle.graal.java.*; 035import com.oracle.graal.lir.phases.*; 036import com.oracle.graal.nodes.*; 037import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 038import com.oracle.graal.phases.*; 039import com.oracle.graal.phases.common.*; 040import com.oracle.graal.phases.common.AddressLoweringPhase.AddressLowering; 041import com.oracle.graal.phases.tiers.*; 042 043/** 044 * HotSpot implementation of {@link SuitesProvider}. 045 */ 046public class HotSpotSuitesProvider implements SuitesProvider { 047 048 protected final DerivedOptionValue<Suites> defaultSuites; 049 protected final PhaseSuite<HighTierContext> defaultGraphBuilderSuite; 050 private final DerivedOptionValue<LIRSuites> defaultLIRSuites; 051 protected final HotSpotGraalRuntimeProvider runtime; 052 053 private final AddressLowering addressLowering; 054 private final SuitesProvider defaultSuitesProvider; 055 056 private class SuitesSupplier implements OptionSupplier<Suites> { 057 058 private static final long serialVersionUID = -3444304453553320390L; 059 060 public Suites get() { 061 return createSuites(); 062 } 063 064 } 065 066 private class LIRSuitesSupplier implements OptionSupplier<LIRSuites> { 067 068 private static final long serialVersionUID = -1558586374095874299L; 069 070 public LIRSuites get() { 071 return createLIRSuites(); 072 } 073 074 } 075 076 public HotSpotSuitesProvider(SuitesProvider defaultSuitesProvider, HotSpotGraalRuntimeProvider runtime, AddressLowering addressLowering) { 077 this.runtime = runtime; 078 this.addressLowering = addressLowering; 079 this.defaultSuitesProvider = defaultSuitesProvider; 080 this.defaultGraphBuilderSuite = createGraphBuilderSuite(); 081 this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); 082 this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); 083 } 084 085 public Suites getDefaultSuites() { 086 return defaultSuites.getValue(); 087 } 088 089 public PhaseSuite<HighTierContext> getDefaultGraphBuilderSuite() { 090 return defaultGraphBuilderSuite; 091 } 092 093 public Suites createSuites() { 094 Suites ret = defaultSuitesProvider.createSuites(); 095 096 if (ImmutableCode.getValue()) { 097 // lowering introduces class constants, therefore it must be after lowering 098 ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset, runtime.getConfig().useCompressedOops ? runtime.getConfig().getOopEncoding() : null)); 099 if (VerifyPhases.getValue()) { 100 ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase()); 101 } 102 } 103 104 ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase(runtime.getConfig())); 105 if (VerifyPhases.getValue()) { 106 ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase()); 107 } 108 109 ret.getLowTier().findPhase(ExpandLogicPhase.class).add(new AddressLoweringPhase(addressLowering)); 110 111 return ret; 112 } 113 114 protected PhaseSuite<HighTierContext> createGraphBuilderSuite() { 115 PhaseSuite<HighTierContext> suite = defaultSuitesProvider.getDefaultGraphBuilderSuite().copy(); 116 assert appendGraphEncoderTest(suite); 117 return suite; 118 } 119 120 /** 121 * When assertions are enabled, we encode and decode every parsed graph, to ensure that the 122 * encoding and decoding process work correctly. The decoding performs canonicalization during 123 * decoding, so the decoded graph can be different than the encoded graph - we cannot check them 124 * for equality here. However, the encoder {@link GraphEncoder#verifyEncoding verifies the 125 * encoding itself}, i.e., performs a decoding without canoncialization and checks the graphs 126 * for equality. 127 */ 128 private boolean appendGraphEncoderTest(PhaseSuite<HighTierContext> suite) { 129 suite.appendPhase(new BasePhase<HighTierContext>("VerifyEncodingDecoding") { 130 @Override 131 protected void run(StructuredGraph graph, HighTierContext context) { 132 EncodedGraph encodedGraph = GraphEncoder.encodeSingleGraph(graph, runtime.getTarget().arch); 133 134 SimplifyingGraphDecoder graphDecoder = new SimplifyingGraphDecoder(context.getMetaAccess(), context.getConstantReflection(), context.getStampProvider(), !ImmutableCode.getValue(), 135 runtime.getTarget().arch); 136 StructuredGraph targetGraph = new StructuredGraph(graph.method(), AllowAssumptions.YES); 137 graphDecoder.decode(targetGraph, encodedGraph); 138 } 139 }); 140 return true; 141 } 142 143 /** 144 * Modifies the {@link GraphBuilderConfiguration} to build extra 145 * {@linkplain DebugInfoMode#Simple debug info} if the VM 146 * {@linkplain CompilerToVM#shouldDebugNonSafepoints() requests} it. 147 * 148 * @param gbs the current graph builder suite 149 * @return a possibly modified graph builder suite 150 */ 151 public static PhaseSuite<HighTierContext> withSimpleDebugInfoIfRequested(PhaseSuite<HighTierContext> gbs) { 152 if (HotSpotGraalRuntime.runtime().getCompilerToVM().shouldDebugNonSafepoints()) { 153 PhaseSuite<HighTierContext> newGbs = gbs.copy(); 154 GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous(); 155 GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig(); 156 GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig.withDebugInfoMode(DebugInfoMode.Simple)); 157 newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase); 158 return newGbs; 159 } 160 return gbs; 161 } 162 163 public LIRSuites getDefaultLIRSuites() { 164 return defaultLIRSuites.getValue(); 165 } 166 167 public LIRSuites createLIRSuites() { 168 LIRSuites suites = defaultSuitesProvider.createLIRSuites(); 169 String profileInstructions = HotSpotBackend.Options.ASMInstructionProfiling.getValue(); 170 if (profileInstructions != null) { 171 suites.getPostAllocationOptimizationStage().appendPhase(new HotSpotInstructionProfiling(profileInstructions)); 172 } 173 return suites; 174 } 175}