1 /* 2 * Copyright (c) 2024, 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 oracle.code.triton; 27 28 import java.lang.reflect.code.*; 29 import java.lang.reflect.code.op.*; 30 import java.lang.reflect.code.type.FunctionType; 31 import java.lang.reflect.code.type.JavaType; 32 import java.lang.reflect.code.type.TupleType; 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.function.Consumer; 36 37 public class SCFOps { 38 39 @OpFactory.OpDeclaration(ForOp.NAME) 40 public static final class ForOp extends ExternalizableOp implements Op.Loop { 41 42 public static class Builder { 43 final Body.Builder ancestorBody; 44 final List<Value> range; 45 final FunctionType loopType; 46 47 Builder(Body.Builder ancestorBody, List<Value> range, FunctionType loopType) { 48 this.ancestorBody = ancestorBody; 49 this.range = range; 50 this.loopType = loopType; 51 } 52 53 public ForOp body(Consumer<Block.Builder> c) { 54 Body.Builder body = Body.Builder.of(ancestorBody, loopType); 55 c.accept(body.entryBlock()); 56 return new ForOp(range, body); 57 } 58 59 public ForOp body(CopyContext cc, Consumer<Block.Builder> c) { 60 Body.Builder body = Body.Builder.of(ancestorBody, loopType, cc); 61 c.accept(body.entryBlock()); 62 return new ForOp(range, body); 63 } 64 } 65 66 public static final String NAME = "scf.for"; 67 68 final Body body; 69 70 public ForOp(ExternalizedOp def) { 71 super(def); 72 73 this.body = def.bodyDefinitions().get(0).build(this); 74 } 75 76 ForOp(ForOp that, CopyContext cc, OpTransformer ot) { 77 super(that, cc); 78 79 this.body = that.body.transform(cc, ot).build(this); 80 } 81 82 @Override 83 public ForOp transform(CopyContext cc, OpTransformer ot) { 84 return new ForOp(this, cc, ot); 85 } 86 87 ForOp(List<Value> range, Body.Builder bodyBuilder) { 88 super(NAME, range); 89 90 this.body = bodyBuilder.build(this); 91 } 92 93 @Override 94 public TypeElement resultType() { 95 return body.yieldType(); 96 } 97 98 @Override 99 public List<Body> bodies() { 100 return List.of(body); 101 } 102 103 @Override 104 public Body loopBody() { 105 return body; 106 } 107 } 108 109 @OpFactory.OpDeclaration(YieldOp.NAME) 110 public static class YieldOp extends ExternalizableOp implements Op.Terminating { 111 public static final String NAME = "scf.yield"; 112 113 public YieldOp(ExternalizedOp def) { 114 super(def); 115 } 116 117 YieldOp(YieldOp that, CopyContext cc) { 118 super(that, cc); 119 } 120 121 @Override 122 public YieldOp transform(CopyContext cc, OpTransformer ot) { 123 return new YieldOp(this, cc); 124 } 125 126 YieldOp(List<Value> values) { 127 super(NAME, values); 128 } 129 130 @Override 131 public TypeElement resultType() { 132 return JavaType.VOID; 133 } 134 135 static TypeElement yieldType(List<Value> values) { 136 if (values.size() == 1) { 137 return values.get(0).type(); 138 } else { 139 return TupleType.tupleTypeFromValues(values); 140 } 141 } 142 } 143 144 static public ForOp.Builder for_(Body.Builder ancestorBody, 145 Value start, Value end, Value step, 146 List<Value> iterValues) { 147 TypeElement yieldType = (iterValues.size() == 1) 148 ? iterValues.get(0).type() 149 : TupleType.tupleTypeFromValues(iterValues); 150 151 List<TypeElement> bodyParameterTypes = new ArrayList<>(); 152 bodyParameterTypes.add(start.type()); 153 bodyParameterTypes.addAll(iterValues.stream().map(Value::type).toList()); 154 FunctionType bodyType = FunctionType.functionType(yieldType, bodyParameterTypes); 155 156 List<Value> operands = new ArrayList<>(); 157 operands.addAll(List.of(start, end, step)); 158 operands.addAll(iterValues); 159 return new ForOp.Builder(ancestorBody, operands, bodyType); 160 } 161 162 163 public static final OpFactory FACTORY = OpFactory.OP_FACTORY.get(SCFOps.class); 164 165 static public YieldOp yield_(Value... values) { 166 return yield_(List.of(values)); 167 } 168 169 static public YieldOp yield_(List<Value> values) { 170 return new YieldOp(values); 171 } 172 }