1 /* 2 * Copyright (c) 2005, 2015, 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 package jdk.test.lib.jittester; 25 26 // Production is base class for all elements of the IR-tree. 27 import java.util.ArrayList; 28 import java.util.Collection; 29 import java.util.List; 30 import java.util.Objects; 31 import jdk.test.lib.jittester.loops.For; 32 import jdk.test.lib.jittester.loops.DoWhile; 33 import jdk.test.lib.jittester.loops.While; 34 import jdk.test.lib.jittester.types.TypeKlass; 35 import jdk.test.lib.jittester.visitors.Visitor; 36 37 public abstract class IRNode { 38 private IRNode parent; 39 private final List<IRNode> children = new ArrayList<>(); 40 protected IRNode klass; 41 protected int level; 42 //TODO 43 //private boolean isCFDeviation; 44 45 public abstract <T> T accept(Visitor<T> v); 46 47 public void setKlass(TypeKlass klass) { 48 this.klass = klass; 49 if (Objects.isNull(klass)) { 50 System.out.println(getClass().getName() + " null"); 51 for (StackTraceElement s : Thread.currentThread().getStackTrace()) { 52 System.out.println(s.toString()); 53 } 54 } 55 } 56 57 public void addChild(IRNode child) { 58 children.add(child); 59 if (!Objects.isNull(child)) { 60 child.parent = this; 61 } 62 } 63 64 public void addChildren(List<? extends IRNode> ch) { 65 if (!Objects.isNull(ch)) { 66 children.addAll(ch); 67 for (IRNode c : ch) { 68 if (!Objects.isNull(c)) { 69 c.parent = this; 70 } 71 } 72 } 73 } 74 75 public List<IRNode> getChildren() { 76 return children; 77 } 78 79 public IRNode getChild(int i) { 80 return i < children.size() ? children.get(i) : null; 81 } 82 83 public IRNode getKlass() { 84 return klass; 85 } 86 87 public IRNode getParent() { 88 return parent; 89 } 90 91 public void setChild(int index, IRNode child) { 92 children.set(index, child); 93 if (!Objects.isNull(child)) { 94 child.parent = this; 95 } 96 } 97 98 public boolean removeChild(IRNode l) { 99 return children.remove(l); 100 } 101 102 public boolean removeSelf() { 103 return parent.children.remove(this); 104 } 105 106 public void resizeUpChildren(int size) { 107 for (int i = children.size(); i < size; ++i) { 108 children.add(null); 109 } 110 } 111 112 public void removeAllChildren() { 113 children.clear(); 114 } 115 116 public String getTreeTextView(int indent) { 117 StringBuilder sb = new StringBuilder(); 118 if (level > 0) { 119 for (int i = 0; i < indent; ++i) { 120 sb.append("\t"); 121 } 122 sb.append(getName()) 123 .append(" [") 124 .append(level) 125 .append("]") 126 .append(System.lineSeparator()); 127 } 128 children.stream() 129 .filter(ch -> !Objects.isNull(ch)) 130 .forEach(ch -> sb.append(ch.getTreeTextView(indent + 1))); 131 return sb.toString(); 132 } 133 134 protected IRNode evolve() { 135 throw new Error("Not implemented"); 136 } 137 138 public int getLevel() { 139 return level; 140 } 141 142 public long complexity() { 143 return 0L; 144 } 145 146 @Override 147 public final String toString() { 148 throw new Error("Should be toJavaCode"); 149 } 150 151 public String getName() { 152 return this.getClass().getName(); 153 } 154 155 public static long countDepth(Collection<IRNode> input) { 156 return input.stream() 157 .filter(c -> !Objects.isNull(c)) 158 .mapToLong(IRNode::countDepth) 159 .max().orElse(0L); 160 } 161 162 public long countDepth() { 163 return IRNode.countDepth(children); 164 } 165 166 public List<IRNode> getStackableLeaves() { 167 List<IRNode> result = new ArrayList<>(); 168 children.stream() 169 .filter(c -> !Objects.isNull(c)) 170 .forEach(c -> { 171 if (countDepth() == c.level && (c instanceof Block)) { 172 result.add(c); 173 } else { 174 result.addAll(c.getStackableLeaves()); 175 } 176 }); 177 return result; 178 } 179 180 public List<IRNode> getDeviantBlocks(long depth) { 181 List<IRNode> result = new ArrayList<>(); 182 children.stream() 183 .filter(c -> !Objects.isNull(c)) 184 .forEach(c -> { 185 if (depth == c.level && c.isCFDeviation()) { 186 result.add(c); 187 } else { 188 result.addAll(c.getDeviantBlocks(depth)); 189 } 190 }); 191 return result; 192 } 193 194 // TODO: add field instead this function 195 public boolean isCFDeviation() { 196 return this instanceof If || this instanceof Switch 197 || this instanceof For || this instanceof While 198 || this instanceof DoWhile 199 || (this instanceof Block && this.parent instanceof Block); 200 } 201 }