1 /* 2 * Copyright (c) 2014, 2019, 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 24 25 package org.graalvm.compiler.lir.gen; 26 27 import jdk.internal.vm.compiler.collections.EconomicMap; 28 import jdk.internal.vm.compiler.collections.Equivalence; 29 import org.graalvm.compiler.core.common.CompilationIdentifier; 30 import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity; 31 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; 32 import org.graalvm.compiler.debug.DebugContext; 33 import org.graalvm.compiler.lir.LIR; 34 import org.graalvm.compiler.lir.LIRInstruction; 35 import org.graalvm.compiler.lir.framemap.FrameMap; 36 import org.graalvm.compiler.lir.framemap.FrameMapBuilder; 37 38 import jdk.vm.ci.code.CallingConvention; 39 import jdk.vm.ci.code.RegisterConfig; 40 41 public class LIRGenerationResult { 42 43 private final LIR lir; 44 private final FrameMapBuilder frameMapBuilder; 45 private FrameMap frameMap; 46 private final RegisterAllocationConfig registerAllocationConfig; 47 private final CallingConvention callingConvention; 48 /** 49 * Records whether the code being generated makes at least one foreign call. 50 */ 51 private boolean hasForeignCall; 52 /** 53 * Unique identifier of this compilation. 54 */ 55 private CompilationIdentifier compilationId; 56 57 /** 58 * Stores comments about a {@link LIRInstruction} , e.g., which phase created it. 59 */ 60 private EconomicMap<LIRInstruction, String> comments; 61 62 public LIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, RegisterAllocationConfig registerAllocationConfig, CallingConvention callingConvention) { 63 this.lir = lir; 64 this.frameMapBuilder = frameMapBuilder; 65 this.registerAllocationConfig = registerAllocationConfig; 66 this.callingConvention = callingConvention; 67 this.compilationId = compilationId; 68 } 69 70 public RegisterAllocationConfig getRegisterAllocationConfig() { 71 return registerAllocationConfig; 72 } 73 74 /** 75 * Adds a comment to a {@link LIRInstruction}. Existing comments are replaced. 76 */ 77 public final void setComment(LIRInstruction op, String comment) { 78 DebugContext debug = lir.getDebug(); 79 if (debug.isDumpEnabled(DebugContext.BASIC_LEVEL)) { 80 if (comments == null) { 81 comments = EconomicMap.create(Equivalence.IDENTITY); 82 } 83 comments.put(op, comment); 84 } 85 } 86 87 /** 88 * Gets the comment attached to a {@link LIRInstruction}. 89 */ 90 public final String getComment(LIRInstruction op) { 91 if (comments == null) { 92 return null; 93 } 94 return comments.get(op); 95 } 96 97 /** 98 * Returns the incoming calling convention for the parameters of the method that is compiled. 99 */ 100 public CallingConvention getCallingConvention() { 101 return callingConvention; 102 } 103 104 /** 105 * Returns the {@link FrameMapBuilder} for collecting the information to build a 106 * {@link FrameMap}. 107 * 108 * This method can only be used prior calling {@link #buildFrameMap}. 109 */ 110 public final FrameMapBuilder getFrameMapBuilder() { 111 assert frameMap == null : "getFrameMapBuilder() can only be used before calling buildFrameMap()!"; 112 return frameMapBuilder; 113 } 114 115 /** 116 * Creates a {@link FrameMap} out of the {@link FrameMapBuilder}. This method should only be 117 * called once. After calling it, {@link #getFrameMapBuilder()} can no longer be used. 118 * 119 * @see FrameMapBuilder#buildFrameMap 120 */ 121 public void buildFrameMap() { 122 assert frameMap == null : "buildFrameMap() can only be called once!"; 123 frameMap = frameMapBuilder.buildFrameMap(this); 124 } 125 126 /** 127 * Returns the {@link FrameMap} associated with this {@link LIRGenerationResult}. 128 * 129 * This method can only be called after {@link #buildFrameMap}. 130 */ 131 public FrameMap getFrameMap() { 132 assert frameMap != null : "getFrameMap() can only be used after calling buildFrameMap()!"; 133 return frameMap; 134 } 135 136 public final RegisterConfig getRegisterConfig() { 137 return frameMapBuilder.getRegisterConfig(); 138 } 139 140 public LIR getLIR() { 141 return lir; 142 } 143 144 /** 145 * Determines whether the code being generated makes at least one foreign call. 146 */ 147 public boolean hasForeignCall() { 148 return hasForeignCall; 149 } 150 151 public final void setForeignCall(boolean hasForeignCall) { 152 this.hasForeignCall = hasForeignCall; 153 } 154 155 public String getCompilationUnitName() { 156 if (compilationId == null || compilationId == CompilationIdentifier.INVALID_COMPILATION_ID) { 157 return "<unknown>"; 158 } 159 return compilationId.toString(Verbosity.NAME); 160 } 161 162 /** 163 * Returns a unique identifier of the current compilation. 164 */ 165 public CompilationIdentifier getCompilationId() { 166 return compilationId; 167 } 168 }