1 /* 2 * Copyright (c) 2009, 2011, 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.core.gen; 24 25 import static org.graalvm.compiler.core.gen.InstructionPrinter.InstructionLineColumn.BCI; 26 import static org.graalvm.compiler.core.gen.InstructionPrinter.InstructionLineColumn.END; 27 import static org.graalvm.compiler.core.gen.InstructionPrinter.InstructionLineColumn.INSTRUCTION; 28 import static org.graalvm.compiler.core.gen.InstructionPrinter.InstructionLineColumn.USE; 29 import static org.graalvm.compiler.core.gen.InstructionPrinter.InstructionLineColumn.VALUE; 30 31 import org.graalvm.compiler.debug.LogStream; 32 import org.graalvm.compiler.nodes.StateSplit; 33 import org.graalvm.compiler.nodes.ValueNode; 34 import org.graalvm.compiler.nodes.ValueNodeUtil; 35 36 /** 37 * A utility for {@linkplain #printInstruction(ValueNode) printing} a node as an expression or 38 * statement. 39 */ 40 public class InstructionPrinter { 41 42 /** 43 * The columns printed in a tabulated instruction 44 * {@linkplain InstructionPrinter#printInstructionListing(ValueNode) listing}. 45 */ 46 public enum InstructionLineColumn { 47 /** 48 * The instruction's bytecode index. 49 */ 50 BCI(2, "bci"), 51 52 /** 53 * The instruction's use count. 54 */ 55 USE(7, "use"), 56 57 /** 58 * The instruction as a value. 59 */ 60 VALUE(12, "tid"), 61 62 /** 63 * The instruction formatted as an expression or statement. 64 */ 65 INSTRUCTION(19, "instr"), 66 67 END(60, ""); 68 69 final int position; 70 final String label; 71 72 InstructionLineColumn(int position, String label) { 73 this.position = position; 74 this.label = label; 75 } 76 77 /** 78 * Prints this column's label to a given stream after padding the stream with '_' characters 79 * until its {@linkplain LogStream#position() position} is equal to this column's position. 80 * 81 * @param out the print stream 82 */ 83 public void printLabel(LogStream out) { 84 out.fillTo(position + out.indentationLevel(), '_'); 85 out.print(label); 86 } 87 88 /** 89 * Prints space characters to a given stream until its {@linkplain LogStream#position() 90 * position} is equal to this column's position. 91 * 92 * @param out the print stream 93 */ 94 public void advance(LogStream out) { 95 out.fillTo(position + out.indentationLevel(), ' '); 96 } 97 } 98 99 private final LogStream out; 100 101 public InstructionPrinter(LogStream out) { 102 this.out = out; 103 } 104 105 public LogStream out() { 106 return out; 107 } 108 109 /** 110 * Prints a header for the tabulated data printed by {@link #printInstructionListing(ValueNode)} 111 * . 112 */ 113 public void printInstructionListingHeader() { 114 BCI.printLabel(out); 115 USE.printLabel(out); 116 VALUE.printLabel(out); 117 INSTRUCTION.printLabel(out); 118 END.printLabel(out); 119 out.println(); 120 } 121 122 /** 123 * Prints an instruction listing on one line. The instruction listing is composed of the columns 124 * specified by {@link InstructionLineColumn}. 125 * 126 * @param instruction the instruction to print 127 */ 128 public void printInstructionListing(ValueNode instruction) { 129 int indentation = out.indentationLevel(); 130 out.fillTo(BCI.position + indentation, ' ').print(0).fillTo(USE.position + indentation, ' ').print("0").fillTo(VALUE.position + indentation, ' ').print( 131 ValueNodeUtil.valueString(instruction)).fillTo( 132 INSTRUCTION.position + indentation, ' '); 133 printInstruction(instruction); 134 if (instruction instanceof StateSplit) { 135 out.print(" [state: " + ((StateSplit) instruction).stateAfter() + "]"); 136 } 137 out.println(); 138 } 139 140 public void printInstruction(ValueNode node) { 141 out.print(node.toString()); 142 } 143 }