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 package hat.tools.text;
 26 
 27 import hat.codebuilders.ScopedCodeBuilderContext;
 28 import hat.codebuilders.HATCodeBuilderWithContext;
 29 import hat.dialect.HATBlockThreadIdOp;
 30 import hat.dialect.HATF16ConvOp;
 31 import hat.dialect.HATF16ToFloatConvOp;
 32 import hat.dialect.HATVectorMakeOfOp;
 33 import hat.dialect.HATVectorOfOp;
 34 import hat.dialect.HATVectorOp;
 35 import hat.dialect.HATVectorSelectLoadOp;
 36 import hat.dialect.HATVectorSelectStoreOp;
 37 import hat.dialect.HATF16BinaryOp;
 38 import hat.dialect.HATF16VarLoadOp;
 39 import hat.dialect.HATF16VarOp;
 40 import hat.dialect.HATVectorBinaryOp;
 41 import hat.dialect.HATVectorLoadOp;
 42 import hat.dialect.HATVectorStoreView;
 43 import hat.dialect.HATGlobalThreadIdOp;
 44 import hat.dialect.HATGlobalSizeOp;
 45 import hat.dialect.HATLocalSizeOp;
 46 import hat.dialect.HATLocalThreadIdOp;
 47 import hat.dialect.HATVectorVarLoadOp;
 48 import hat.dialect.HATVectorVarOp;
 49 import hat.optools.OpTk;
 50 import jdk.incubator.code.Op;
 51 import jdk.incubator.code.dialect.java.JavaOp;
 52 import jdk.incubator.code.dialect.java.JavaType;
 53 import jdk.incubator.code.dialect.java.PrimitiveType;
 54 
 55 public class JavaHATCodeBuilder<T extends JavaHATCodeBuilder<T>> extends HATCodeBuilderWithContext<T> {
 56 
 57     @Override
 58     public T type(ScopedCodeBuilderContext buildContext, JavaType javaType) {
 59             try {
 60                 typeName(javaType.resolve(buildContext.lookup).getTypeName());
 61             } catch (ReflectiveOperationException e) {
 62                 throw new RuntimeException(e);
 63             }
 64         return self();
 65     }
 66 
 67 
 68     @Override
 69     public T fieldLoadOp(ScopedCodeBuilderContext buildContext, JavaOp.FieldAccessOp.FieldLoadOp fieldLoadOp) {
 70         if (OpTk.isKernelContextAccess(fieldLoadOp)) {
 71             identifier("kc").dot().fieldName(fieldLoadOp);
 72         } else if (fieldLoadOp.operands().isEmpty() && fieldLoadOp.result().type() instanceof PrimitiveType) { // only primitve fields
 73             var value = OpTk.getStaticFinalPrimitiveValue(buildContext.lookup,fieldLoadOp);
 74             literal(value.toString());
 75         } else {
 76             throw new IllegalStateException("An instance field? I guess - we dont get those in HAT " +fieldLoadOp);
 77         }
 78         return self();
 79     }
 80 
 81     @Override
 82     public T invokeOp(ScopedCodeBuilderContext buildContext, JavaOp.InvokeOp invokeOp) {
 83         if (!invokeOp.operands().isEmpty() && invokeOp.operands().getFirst() instanceof Op.Result instanceResult) {
 84             recurse(buildContext, instanceResult.op());
 85         }
 86         dot().identifier(invokeOp.invokeDescriptor().name());
 87         paren(_ ->
 88                 // why the sublist? is this static vs instance?
 89             separated(  invokeOp.operands().subList(0,invokeOp.operands().size()-1), (_)->commaSpace(),o->
 90                     recurse(buildContext,  ((Op.Result) o).op())
 91             )
 92         );
 93         return self();
 94     }
 95 
 96     @Override
 97     public T privateDeclaration(LocalArrayDeclaration localArrayDeclaration) {
 98         blockComment("/* private declaration !! */");
 99         return self();
100     }
101 
102     @Override
103     public T localDeclaration(LocalArrayDeclaration localArrayDeclaration) {
104         blockComment("/* local declaration !! */");
105         return self();
106     }
107 
108     @Override
109     public T syncBlockThreads() {
110         blockComment("/* group wide barrier!! */");
111         return self();
112     }
113 
114     @Override
115     public T hatGlobalThreadOp(ScopedCodeBuilderContext buildContext, HATGlobalThreadIdOp globalThreadIdOp) {
116         blockInlineComment("Thread ID access");
117         return self();
118     }
119 
120     @Override
121     public T hatGlobalSizeOp(ScopedCodeBuilderContext buildContext, HATGlobalSizeOp hatGlobalThreadIdOp) {
122         blockInlineComment("GlobalSize");
123         return self();
124     }
125 
126     @Override
127     public T hatLocalThreadIdOp(ScopedCodeBuilderContext buildContext, HATLocalThreadIdOp hatLocalThreadIdOp) {
128         blockInlineComment("Local Thread ID");
129         return self();
130     }
131 
132     @Override
133     public T hatLocalSizeOp(ScopedCodeBuilderContext buildContext, HATLocalSizeOp hatLocalSizeOp) {
134         blockInlineComment("Local Size");
135         return self();
136     }
137 
138     @Override
139     public T hatBlockThreadIdOp(ScopedCodeBuilderContext buildContext, HATBlockThreadIdOp hatBlockThreadIdOp) {
140         blockInlineComment("Block ID ");
141         return self();
142     }
143 
144     @Override
145     public T hatVectorVarOp(ScopedCodeBuilderContext buildContext, HATVectorVarOp hatVectorVarOp) {
146         blockComment("Vector Variable Not Implemented");
147         return self();
148     }
149 
150     @Override
151     public T hatVectorStoreOp(ScopedCodeBuilderContext buildContext, HATVectorStoreView hatVectorStoreView) {
152         blockComment("Store Vector Not Implemented");
153         return self();
154     }
155 
156     @Override
157     public T hatBinaryVectorOp(ScopedCodeBuilderContext buildContext, HATVectorBinaryOp hatVectorBinaryOp) {
158         blockComment("Binary Vector Not Implemented");
159         return self();
160     }
161 
162     @Override
163     public T hatVectorLoadOp(ScopedCodeBuilderContext buildContext, HATVectorLoadOp hatVectorLoadOp) {
164         blockComment("Load Vector Not Implemented");
165         return self();
166     }
167 
168     @Override
169     public T hatSelectLoadOp(ScopedCodeBuilderContext buildContext, HATVectorSelectLoadOp hatVSelectLoadOp) {
170         blockComment("Select Vector Not Implemented");
171         return self();
172     }
173 
174     @Override
175     public T hatSelectStoreOp(ScopedCodeBuilderContext buildContext, HATVectorSelectStoreOp hatVSelectStoreOp) {
176         blockComment("Select Vector Not Implemented");
177         return self();
178     }
179 
180     @Override
181     public T hatVectorVarLoadOp(ScopedCodeBuilderContext buildContext, HATVectorVarLoadOp hatVectorVarLoadOp) {
182         blockComment("Vector Variable Not Implemented");
183         return self();
184     }
185 
186     @Override
187     public T hatF16VarOp(ScopedCodeBuilderContext buildContext, HATF16VarOp hatF16VarOp) {
188         blockComment("F16 Variable Not Implemented");
189         return self();
190     }
191 
192     @Override
193     public T hatF16BinaryOp(ScopedCodeBuilderContext buildContext, HATF16BinaryOp hatF16BinaryOp) {
194         blockComment("Binary F16 Op Not Implemented");
195         return self();
196     }
197 
198     @Override
199     public T hatF16VarLoadOp(ScopedCodeBuilderContext buildContext, HATF16VarLoadOp hatF16VarLoadOp) {
200         blockComment("F16 Load Op Not Implemented");
201         return self();
202     }
203 
204     @Override
205     public T hatF16ConvOp(ScopedCodeBuilderContext buildContext, HATF16ConvOp hatF16ConvOp) {
206         blockComment("F16 Conv Op Not Implemented");
207         return self();
208     }
209 
210     @Override
211     public T hatVectorOfOps(ScopedCodeBuilderContext buildContext, HATVectorOfOp hatVectorOp) {
212         blockComment("Vector Of Ops Not Implemented");
213         return self();
214     }
215 
216     @Override
217     public T hatVectorMakeOf(ScopedCodeBuilderContext builderContext, HATVectorMakeOfOp hatVectorMakeOfOp) {
218         blockComment("Vector Make Of Op Not Implemented");
219         return self();
220     }
221 
222     @Override
223     public T hatF16ToFloatConvOp(ScopedCodeBuilderContext builderContext, HATF16ToFloatConvOp hatF16ToFloatConvOp) {
224         blockComment("Float Conv Op Not Implemented");
225         return self();
226     }
227 
228     public T createJava(ScopedCodeBuilderContext buildContext) {
229         buildContext.funcScope(buildContext.funcOp, () -> {
230             typeName(buildContext.funcOp.resultType().toString()).space().funcName(buildContext.funcOp);
231             parenNlIndented(_ -> separated(buildContext.paramTable.list(), (_) -> comma().nl(),
232                     param -> declareParam(buildContext, param)));
233             braceNlIndented(_ -> separated(OpTk.statements(buildContext.funcOp.bodies().getFirst().entryBlock()), (_) -> nl(),
234                     statement -> statement(buildContext, statement))
235             );
236         });
237         return self();
238     }
239 }