1 /* 2 * Copyright (c) 2008, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.scenario.effect.compiler.backend.sw.me; 27 28 import com.sun.scenario.effect.compiler.model.Function; 29 import com.sun.scenario.effect.compiler.model.Type; 30 import com.sun.scenario.effect.compiler.model.Variable; 31 import com.sun.scenario.effect.compiler.tree.*; 32 import static com.sun.scenario.effect.compiler.backend.sw.me.MEBackend.getFieldIndex; 33 import static com.sun.scenario.effect.compiler.backend.sw.me.MEBackend.getSuffix; 34 35 /** 36 */ 37 class METreeScanner extends TreeScanner { 38 39 private final String funcName; 40 private final StringBuilder sb = new StringBuilder(); 41 42 private boolean inVectorOp = false; 43 private int vectorIndex = 0; 44 private boolean inFieldSelect = false; 45 private char selectedField = 'x'; 46 47 METreeScanner() { 48 this(null); 49 } 50 51 METreeScanner(String funcName) { 52 this.funcName = funcName; 53 } 54 55 private void output(String s) { 56 sb.append(s); 57 } 58 59 String getResult() { 60 return (sb != null) ? sb.toString() : null; 61 } 62 63 @Override 64 public void visitArrayAccessExpr(ArrayAccessExpr e) { 65 if (e.getExpr() instanceof VariableExpr && 66 e.getIndex() instanceof VariableExpr) 67 { 68 VariableExpr ve = (VariableExpr)e.getExpr(); 69 VariableExpr ie = (VariableExpr)e.getIndex(); 70 output(ve.getVariable().getName()); 71 output("_arr[" + ie.getVariable().getName()); 72 output(" * " + ve.getVariable().getType().getNumFields()); 73 output(" + " + getFieldIndex(selectedField) + "]"); 74 } else { 75 throw new InternalError("Array access only supports variable expr/index (for now)"); 76 } 77 } 78 79 @Override 80 public void visitBinaryExpr(BinaryExpr e) { 81 scan(e.getLeft()); 82 output(" " + e.getOp() + " "); 83 scan(e.getRight()); 84 } 85 86 @Override 87 public void visitBreakStmt(BreakStmt s) { 88 output("break;"); 89 } 90 91 @Override 92 public void visitCallExpr(CallExpr e) { 93 Function func = e.getFunction(); 94 output(func.getName() + "_res"); 95 if (func.getReturnType().isVector()) { 96 // TODO: this needs more thought 97 if (inFieldSelect) { 98 output(getSuffix(getFieldIndex(selectedField))); 99 } else if (inVectorOp) { 100 output(getSuffix(vectorIndex)); 101 } else { 102 throw new InternalError("TBD"); 103 } 104 } 105 } 106 107 @Override 108 public void visitCompoundStmt(CompoundStmt s) { 109 output("{\n"); 110 super.visitCompoundStmt(s); 111 output("}\n"); 112 } 113 114 @Override 115 public void visitContinueStmt(ContinueStmt s) { 116 output("continue;"); 117 } 118 119 @Override 120 public void visitDeclStmt(DeclStmt s) { 121 super.visitDeclStmt(s); 122 } 123 124 @Override 125 public void visitDiscardStmt(DiscardStmt s) { 126 // TODO: not yet implemented 127 } 128 129 @Override 130 public void visitDoWhileStmt(DoWhileStmt s) { 131 output("do "); 132 scan(s.getStmt()); 133 output(" while ("); 134 scan(s.getExpr()); 135 output(");"); 136 } 137 138 @Override 139 public void visitExprStmt(ExprStmt s) { 140 Expr expr = s.getExpr(); 141 142 outputPreambles(expr); 143 144 Type t = expr.getResultType(); 145 if (t.isVector()) { 146 inVectorOp = true; 147 for (int i = 0; i < t.getNumFields(); i++) { 148 vectorIndex = i; 149 scan(s.getExpr()); 150 output(";\n"); 151 } 152 inVectorOp = false; 153 } else { 154 scan(s.getExpr()); 155 output(";\n"); 156 } 157 } 158 159 @Override 160 public void visitFieldSelectExpr(FieldSelectExpr e) { 161 if (e.getFields().length() == 1) { 162 selectedField = e.getFields().charAt(0); 163 } else { 164 int index = inVectorOp ? vectorIndex : 0; 165 selectedField = e.getFields().charAt(index); 166 } 167 inFieldSelect = true; 168 scan(e.getExpr()); 169 inFieldSelect = false; 170 } 171 172 @Override 173 public void visitForStmt(ForStmt s) { 174 output("for ("); 175 scan(s.getInit()); 176 scan(s.getCondition()); 177 output(";"); 178 scan(s.getExpr()); 179 output(")"); 180 scan(s.getStmt()); 181 } 182 183 @Override 184 public void visitFuncDef(FuncDef d) { 185 if (d.getFunction().getName().equals("main")) { 186 scan(d.getStmt()); 187 } else { 188 // TODO: this is a hacky approach to saving func defs, which 189 // will be inlined later at point of use)... 190 MEBackend.putFuncDef(d); 191 } 192 } 193 194 @Override 195 public void visitGlueBlock(GlueBlock b) { 196 MEBackend.addGlueBlock(b.getText()); 197 } 198 199 @Override 200 public void visitLiteralExpr(LiteralExpr e) { 201 output(e.getValue().toString()); 202 if (e.getValue() instanceof Float) { 203 output("f"); 204 } 205 } 206 207 @Override 208 public void visitParenExpr(ParenExpr e) { 209 output("("); 210 scan(e.getExpr()); 211 output(")"); 212 } 213 214 @Override 215 public void visitProgramUnit(ProgramUnit p) { 216 super.visitProgramUnit(p); 217 } 218 219 @Override 220 public void visitReturnStmt(ReturnStmt s) { 221 Expr expr = s.getExpr(); 222 if (expr == null) { 223 throw new InternalError("Empty return not yet implemented"); 224 } 225 if (funcName == null) { 226 throw new RuntimeException("Return statement not expected"); 227 } 228 229 Type t = expr.getResultType(); 230 if (t.isVector()) { 231 inVectorOp = true; 232 for (int i = 0; i < t.getNumFields(); i++) { 233 vectorIndex = i; 234 output(funcName + "_res" + getSuffix(i) + " = "); 235 scan(s.getExpr()); 236 output(";\n"); 237 } 238 inVectorOp = false; 239 } else { 240 output(funcName + "_res = "); 241 scan(s.getExpr()); 242 output(";\n"); 243 } 244 } 245 246 @Override 247 public void visitSelectStmt(SelectStmt s) { 248 output("if ("); 249 scan(s.getIfExpr()); 250 output(")"); 251 scan(s.getThenStmt()); 252 Stmt e = s.getElseStmt(); 253 if (e != null) { 254 output(" else "); 255 scan(e); 256 } 257 } 258 259 @Override 260 public void visitUnaryExpr(UnaryExpr e) { 261 output(e.getOp().toString()); 262 scan(e.getExpr()); 263 } 264 265 @Override 266 public void visitVarDecl(VarDecl d) { 267 Variable var = d.getVariable(); 268 if (var.getQualifier() != null) { 269 // these will be declared separately outside the loop body 270 return; 271 } 272 273 outputPreambles(d); 274 275 Type t = var.getType(); 276 if (t.isVector()) { 277 inVectorOp = true; 278 for (int i = 0; i < t.getNumFields(); i++) { 279 output(t.getBaseType().toString() + " "); 280 output(var.getName() + getSuffix(i)); 281 Expr init = d.getInit(); 282 if (init != null) { 283 output(" = "); 284 vectorIndex = i; 285 scan(init); 286 } 287 output(";\n"); 288 } 289 inVectorOp = false; 290 } else { 291 output(t.toString() + " " + var.getName()); 292 Expr init = d.getInit(); 293 if (init != null) { 294 output(" = "); 295 scan(init); 296 } 297 output(";\n"); 298 } 299 } 300 301 @Override 302 public void visitVariableExpr(VariableExpr e) { 303 Variable var = e.getVariable(); 304 output(var.getName()); 305 if (var.isParam()) { 306 output("_tmp"); 307 } 308 if (var.getType().isVector()) { 309 if (inFieldSelect) { 310 output(getSuffix(getFieldIndex(selectedField))); 311 } else if (inVectorOp) { 312 output(getSuffix(vectorIndex)); 313 } else { 314 throw new InternalError("TBD"); 315 } 316 } 317 } 318 319 @Override 320 public void visitVectorCtorExpr(VectorCtorExpr e) { 321 // TODO: this will likely work for simple variables and literals, 322 // but we need something more for embedded function calls, etc... 323 scan(e.getParams().get(vectorIndex)); 324 } 325 326 @Override 327 public void visitWhileStmt(WhileStmt s) { 328 output("while ("); 329 scan(s.getCondition()); 330 output(")"); 331 scan(s.getStmt()); 332 } 333 334 private void outputPreambles(Tree tree) { 335 MECallScanner scanner = new MECallScanner(); 336 scanner.scan(tree); 337 String res = scanner.getResult(); 338 if (res != null) { 339 output(scanner.getResult()); 340 } 341 } 342 }