1 /*
  2  * Copyright (c) 2024 Intel Corporation. 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 intel.code.spirv;
 27 
 28 import java.util.List;
 29 import java.lang.reflect.code.Block;
 30 import java.lang.reflect.code.Body;
 31 import java.lang.reflect.code.Op;
 32 import java.lang.reflect.code.Value;
 33 import java.lang.reflect.code.CopyContext;
 34 import java.lang.reflect.code.OpTransformer;
 35 import java.lang.reflect.code.TypeElement;
 36 import java.lang.reflect.code.type.MethodRef;
 37 import java.lang.reflect.code.type.FieldRef;
 38 import java.lang.reflect.code.type.FunctionType;
 39 import java.lang.reflect.code.type.JavaType;
 40 
 41 public class SpirvOps {
 42     private static final String NAME_PREFIX = "spirv.";
 43 
 44     public static final class ModuleOp extends SpirvOp {
 45         public static final String OPNAME = NAME_PREFIX + "module";
 46 
 47         private final String name;
 48 
 49         public ModuleOp(String moduleName) {
 50             super(OPNAME);
 51             this.name = moduleName;
 52         }
 53 
 54         public ModuleOp(ModuleOp that, CopyContext cc) {
 55             super(that, cc);
 56             this.name = that.name;
 57         }
 58 
 59         @Override
 60         public ModuleOp transform(CopyContext cc, OpTransformer ot) {
 61             return new ModuleOp(this, cc);
 62         }
 63     }
 64 
 65     public static final class LoadOp extends SpirvOp {
 66         public static final String OPNAME = NAME_PREFIX + "load";
 67 
 68         public LoadOp(TypeElement resultType, List<Value> operands) {
 69             super(OPNAME, resultType, operands);
 70         }
 71 
 72         public LoadOp(LoadOp that, CopyContext cc) {
 73             super(that, cc);
 74         }
 75 
 76         @Override
 77         public LoadOp transform(CopyContext cc, OpTransformer ot) {
 78             return new LoadOp(this, cc);
 79         }
 80     }
 81 
 82     public static final class FieldLoadOp extends SpirvOp {
 83         public static final String OPNAME = NAME_PREFIX + "fieldload";
 84         private final FieldRef fieldDesc;
 85 
 86         public FieldLoadOp(TypeElement resultType, FieldRef fieldRef, List<Value> operands) {
 87             super(OPNAME, resultType, operands);
 88             this.fieldDesc = fieldRef;
 89         }
 90 
 91         public FieldLoadOp(FieldLoadOp that, CopyContext cc) {
 92             super(that, cc);
 93             this.fieldDesc = that.fieldDesc;
 94         }
 95 
 96         @Override
 97         public FieldLoadOp transform(CopyContext cc, OpTransformer ot) {
 98             return new FieldLoadOp(this, cc);
 99         }
100 
101         public FieldRef fieldDescriptor() {
102             return fieldDesc;
103         }
104     }
105 
106     public static final class StoreOp extends SpirvOp {
107         public static final String NAME = NAME_PREFIX + "store";
108 
109         public StoreOp(Value dest, Value value) {
110             super(NAME, JavaType.VOID, List.of(dest, value));
111         }
112 
113         public StoreOp(StoreOp that, CopyContext cc) {
114             super(that, cc);
115         }
116 
117         @Override
118         public StoreOp transform(CopyContext cc, OpTransformer ot) {
119             return new StoreOp(this, cc);
120         }
121     }
122 
123     public static final class CallOp extends SpirvOp {
124         public static final String OPNAME = NAME_PREFIX + "call";
125         private MethodRef descriptor;
126 
127         public CallOp(MethodRef descriptor, List<Value> operands) {
128             super(nameString(descriptor), descriptor.type().returnType(), operands);
129             this.descriptor = descriptor;
130         }
131 
132         public CallOp(CallOp that, CopyContext cc) {
133             super(that, cc);
134         }
135 
136         @Override
137         public CallOp transform(CopyContext cc, OpTransformer ot) {
138             return new CallOp(this, cc);
139         }
140 
141         public MethodRef callDescriptor() {
142             return descriptor;
143         }
144 
145         private static String nameString(MethodRef descriptor) {
146             return OPNAME + " @" + descriptor.refType() + "::" + descriptor.name();
147         }
148     }
149 
150     public static final class ArrayLengthOp extends SpirvOp {
151         public static final String NAME = NAME_PREFIX + "arraylength";
152 
153         public ArrayLengthOp(TypeElement resultType, List<Value> operands) {
154             super(NAME, resultType, operands);
155         }
156 
157         public ArrayLengthOp(ArrayLengthOp that, CopyContext cc) {
158             super(that, cc);
159         }
160 
161         @Override
162         public ArrayLengthOp transform(CopyContext cc, OpTransformer ot) {
163             return new ArrayLengthOp(this, cc);
164         }
165     }
166 
167     public static final class ConstantOp extends SpirvOp {
168         public static final String OPNAME = NAME_PREFIX + "constant";
169         private final Object value;
170 
171         public ConstantOp(TypeElement resultType, Object value) {
172                 super(OPNAME, resultType, List.of());
173                 this.value = value;
174         }
175 
176         public ConstantOp(ConstantOp that, CopyContext cc) {
177             super(that, cc);
178             this.value = that.value;
179         }
180 
181         @Override
182         public ConstantOp transform(CopyContext cc, OpTransformer ot) {
183             return new ConstantOp(this, cc);
184         }
185 
186         public Object value() {
187             return value;
188         }
189     }
190 
191     public static final class ConvertOp extends SpirvOp {
192         public static final String OPNAME = NAME_PREFIX + "sconvert";
193 
194         public ConvertOp(TypeElement resultType, List<Value> operands) {
195                 super(OPNAME, resultType, operands);
196         }
197 
198         public ConvertOp(ConvertOp that, CopyContext cc) {
199             super(that, cc);
200         }
201 
202         @Override
203         public ConvertOp transform(CopyContext cc, OpTransformer ot) {
204             return new ConvertOp(this, cc);
205         }
206     }
207 
208     public static final class IAddOp extends SpirvOp {
209         public static final String NAME = NAME_PREFIX + "iadd";
210 
211         public IAddOp(TypeElement resultType, List<Value> operands) {
212                 super(NAME, resultType, operands);
213         }
214 
215         public IAddOp(IAddOp that, CopyContext cc) {
216             super(that, cc);
217         }
218 
219         @Override
220         public IAddOp transform(CopyContext cc, OpTransformer ot) {
221             return new IAddOp(this, cc);
222         }
223     }
224 
225     public static final class FAddOp extends SpirvOp {
226         public static final String NAME = NAME_PREFIX + "fadd";
227 
228         public FAddOp(TypeElement resultType, List<Value> operands) {
229                 super(NAME, resultType, operands);
230         }
231 
232         public FAddOp(FAddOp that, CopyContext cc) {
233             super(that, cc);
234         }
235 
236         @Override
237         public FAddOp transform(CopyContext cc, OpTransformer ot) {
238             return new FAddOp(this, cc);
239         }
240     }
241 
242     public static final class ISubOp extends SpirvOp {
243         public static final String NAME = NAME_PREFIX + "isub";
244 
245         public ISubOp(TypeElement resultType, List<Value> operands) {
246                 super(NAME, resultType, operands);
247         }
248 
249         public ISubOp(ISubOp that, CopyContext cc) {
250             super(that, cc);
251         }
252 
253         @Override
254         public ISubOp transform(CopyContext cc, OpTransformer ot) {
255             return new ISubOp(this, cc);
256         }
257     }
258 
259     public static final class FSubOp extends SpirvOp {
260         public static final String NAME = NAME_PREFIX + "fsub";
261 
262         public FSubOp(TypeElement resultType, List<Value> operands) {
263                 super(NAME, resultType, operands);
264         }
265 
266         public FSubOp(FSubOp that, CopyContext cc) {
267             super(that, cc);
268         }
269 
270         @Override
271         public FSubOp transform(CopyContext cc, OpTransformer ot) {
272             return new FSubOp(this, cc);
273         }
274     }
275 
276     public static final class IMulOp extends SpirvOp {
277         public static final String NAME = NAME_PREFIX + "imul";
278 
279         public IMulOp(TypeElement resultType, List<Value> operands) {
280                 super(NAME, resultType, operands);
281         }
282 
283         public IMulOp(IMulOp that, CopyContext cc) {
284             super(that, cc);
285         }
286 
287         @Override
288         public IMulOp transform(CopyContext cc, OpTransformer ot) {
289             return new IMulOp(this, cc);
290         }
291     }
292 
293     public static final class FMulOp extends SpirvOp {
294         public static final String NAME = NAME_PREFIX + "fmul";
295 
296         public FMulOp(TypeElement resultType, List<Value> operands) {
297                 super(NAME, resultType, operands);
298         }
299 
300         public FMulOp(FMulOp that, CopyContext cc) {
301             super(that, cc);
302         }
303 
304         @Override
305         public FMulOp transform(CopyContext cc, OpTransformer ot) {
306             return new FMulOp(this, cc);
307         }
308     }
309 
310     public static final class IDivOp extends SpirvOp {
311         public static final String NAME = NAME_PREFIX + "idiv";
312 
313         public IDivOp(TypeElement resultType, List<Value> operands) {
314                 super(NAME, resultType, operands);
315         }
316 
317         public IDivOp(IDivOp that, CopyContext cc) {
318             super(that, cc);
319         }
320 
321         @Override
322         public IDivOp transform(CopyContext cc, OpTransformer ot) {
323             return new IDivOp(this, cc);
324         }
325     }
326 
327     public static final class FDivOp extends SpirvOp {
328         public static final String NAME = NAME_PREFIX + "fdiv";
329 
330         public FDivOp(TypeElement resultType, List<Value> operands) {
331                 super(NAME, resultType, operands);
332         }
333 
334         public FDivOp(FDivOp that, CopyContext cc) {
335             super(that, cc);
336         }
337 
338         @Override
339         public FDivOp transform(CopyContext cc, OpTransformer ot) {
340             return new FDivOp(this, cc);
341         }
342     }
343 
344     public static final class ModOp extends SpirvOp {
345         public static final String NAME = NAME_PREFIX + "mod";
346 
347         public ModOp(TypeElement resultType, List<Value> operands) {
348                 super(NAME, resultType, operands);
349         }
350 
351         public ModOp(ModOp that, CopyContext cc) {
352             super(that, cc);
353         }
354 
355         @Override
356         public ModOp transform(CopyContext cc, OpTransformer ot) {
357             return new ModOp(this, cc);
358         }
359     }
360 
361     public static final class IEqualOp extends SpirvOp {
362         public static final String NAME = NAME_PREFIX + "iequal";
363 
364         public IEqualOp(TypeElement resultType, List<Value> operands) {
365                 super(NAME, resultType, operands);
366         }
367 
368         public IEqualOp(IEqualOp that, CopyContext cc) {
369             super(that, cc);
370         }
371 
372         @Override
373         public IEqualOp transform(CopyContext cc, OpTransformer ot) {
374             return new IEqualOp(this, cc);
375         }
376     }
377 
378     public static final class FEqualOp extends SpirvOp {
379         public static final String NAME = NAME_PREFIX + "fequal";
380 
381         public FEqualOp(TypeElement resultType, List<Value> operands) {
382                 super(NAME, resultType, operands);
383         }
384 
385         public FEqualOp(FEqualOp that, CopyContext cc) {
386             super(that, cc);
387         }
388 
389         @Override
390         public FEqualOp transform(CopyContext cc, OpTransformer ot) {
391             return new FEqualOp(this, cc);
392         }
393     }
394 
395     public static final class INotEqualOp extends SpirvOp {
396         public static final String NAME = NAME_PREFIX + "inotequal";
397 
398         public INotEqualOp(TypeElement resultType, List<Value> operands) {
399                 super(NAME, resultType, operands);
400         }
401 
402         public INotEqualOp(INotEqualOp that, CopyContext cc) {
403             super(that, cc);
404         }
405 
406         @Override
407         public INotEqualOp transform(CopyContext cc, OpTransformer ot) {
408             return new INotEqualOp(this, cc);
409         }
410     }
411 
412 
413     public static final class FNotEqualOp extends SpirvOp {
414         public static final String NAME = NAME_PREFIX + "fnotequal";
415 
416         public FNotEqualOp(TypeElement resultType, List<Value> operands) {
417                 super(NAME, resultType, operands);
418         }
419 
420         public FNotEqualOp(FNotEqualOp that, CopyContext cc) {
421             super(that, cc);
422         }
423 
424         @Override
425         public FNotEqualOp transform(CopyContext cc, OpTransformer ot) {
426             return new FNotEqualOp(this, cc);
427         }
428     }
429 
430     public static final class LtOp extends SpirvOp {
431         public static final String NAME = NAME_PREFIX + "lt";
432 
433         public LtOp(TypeElement resultType, List<Value> operands) {
434                 super(NAME, resultType, operands);
435         }
436 
437         public LtOp(LtOp that, CopyContext cc) {
438             super(that, cc);
439         }
440 
441         @Override
442         public LtOp transform(CopyContext cc, OpTransformer ot) {
443             return new LtOp(this, cc);
444         }
445     }
446 
447     public static final class BranchOp extends SpirvOp implements Op.BlockTerminating {
448         public static final String NAME = NAME_PREFIX + "br";
449         private final Block.Reference successor;
450 
451         public BranchOp(Block.Reference successor) {
452             super(NAME, JavaType.VOID, List.of());
453             this.successor = successor;
454         }
455 
456         public BranchOp(BranchOp that, CopyContext cc) {
457             super(that, cc);
458             this.successor = that.successor;
459         }
460 
461         @Override
462         public BranchOp transform(CopyContext cc, OpTransformer ot) {
463             return new BranchOp(this, cc);
464         }
465 
466         public Block branch() {
467             return successor.targetBlock();
468         }
469 
470         @Override
471         public List<Block.Reference> successors() {
472             return List.of(successor);
473         }
474     }
475 
476     public static final class ConditionalBranchOp extends SpirvOp implements Op.BlockTerminating {
477         public static final String NAME = NAME_PREFIX + "brcond";
478         private final Block.Reference trueBlock;
479         private final Block.Reference falseBlock;
480 
481         public ConditionalBranchOp(Block.Reference trueBlock, Block.Reference falseBlock, List<Value> operands) {
482                 super(NAME, JavaType.VOID, operands);
483                 this.trueBlock = trueBlock;
484                 this.falseBlock = falseBlock;
485         }
486 
487         public ConditionalBranchOp(ConditionalBranchOp that, CopyContext cc) {
488             super(that, cc);
489             this.trueBlock = that.trueBlock;
490             this.falseBlock = that.falseBlock;
491         }
492 
493         @Override
494         public ConditionalBranchOp transform(CopyContext cc, OpTransformer ot) {
495             return new ConditionalBranchOp(this, cc);
496         }
497 
498         public Block trueBranch() {
499             return trueBlock.targetBlock();
500         }
501 
502         public Block falseBranch() {
503             return falseBlock.targetBlock();
504         }
505 
506         @Override
507         public List<Block.Reference> successors() {
508             return List.of(trueBlock, falseBlock);
509         }
510     }
511 
512     public static final class VariableOp extends SpirvOp {
513         public static final String OPNAME = NAME_PREFIX + "variable";
514         private final String varName;
515         private final TypeElement varType;
516 
517         public VariableOp(String varName, TypeElement type, TypeElement varType) {
518             super(OPNAME + " @" + varName, type, List.of());
519             this.varName = varName;
520             this.varType = varType;
521         }
522 
523         public VariableOp(VariableOp that, CopyContext cc) {
524             super(that, cc);
525             this.varName = that.varName;
526             this.varType = that.varType;
527         }
528 
529         @Override
530         public VariableOp transform(CopyContext cc, OpTransformer ot) {
531             return new VariableOp(this, cc);
532         }
533 
534         public TypeElement varType() {
535             return varType;
536         }
537 
538         public String varName() {
539             return varName;
540         }
541     }
542 
543     public static final class CompositeExtractOp extends SpirvOp {
544         public static final String OPNAME = NAME_PREFIX + "compositeExtract";
545 
546         public CompositeExtractOp(TypeElement resultType, List<Value> operands) {
547                 super(OPNAME, resultType, operands);
548         }
549 
550         public CompositeExtractOp(CompositeExtractOp that, CopyContext cc) {
551             super(that, cc);
552         }
553 
554         @Override
555         public CompositeExtractOp transform(CopyContext cc, OpTransformer ot) {
556             return new CompositeExtractOp(this, cc);
557         }
558     }
559 
560     public static final class InBoundAccessChainOp extends SpirvOp {
561         public static final String OPNAME = NAME_PREFIX + "inBoundAccessChain";
562 
563         public InBoundAccessChainOp(TypeElement resultType, List<Value> operands) {
564                 super(OPNAME, resultType, operands);
565         }
566 
567         public InBoundAccessChainOp(InBoundAccessChainOp that, CopyContext cc) {
568             super(that, cc);
569         }
570 
571         @Override
572         public InBoundAccessChainOp transform(CopyContext cc, OpTransformer ot) {
573             return new InBoundAccessChainOp(this, cc);
574         }
575     }
576 
577     public static final class ReturnOp extends SpirvOp implements Op.Terminating {
578         public static final String OPNAME = "return";
579 
580         public ReturnOp(TypeElement resultType, List<Value> operands) {
581             super(OPNAME, resultType, operands);
582         }
583 
584         public ReturnOp(ReturnOp that, CopyContext cc) {
585             super(that, cc);
586         }
587 
588         @Override
589         public ReturnOp transform(CopyContext cc, OpTransformer ot) {
590             return new ReturnOp(this, cc);
591         }
592     }
593 
594     public static final class FunctionParameterOp extends SpirvOp {
595         public static final String OPNAME = NAME_PREFIX + "function parameter";
596 
597         public FunctionParameterOp(TypeElement resultType, List<Value> operands) {
598             super(OPNAME, resultType, operands);
599         }
600 
601         public FunctionParameterOp(FunctionParameterOp that, CopyContext cc) {
602             super(that, cc);
603         }
604 
605         @Override
606         public FunctionParameterOp transform(CopyContext cc, OpTransformer ot) {
607             return new FunctionParameterOp(this, cc);
608         }
609     }
610 
611     public static final class FuncOp extends SpirvOp implements Op.Invokable {
612         public static enum Control {
613             INLINE,
614             DONTINLINE,
615             PURE,
616             CONST,
617             NONE
618         }
619 
620         public static final String OPNAME = NAME_PREFIX + "function";
621         private final String functionName;
622         private final FunctionType functionType;
623         private final Body body;
624 
625 
626         public FuncOp(String name, FunctionType functionType, Body.Builder builder) {
627             super(OPNAME + "_" + name);
628             this.functionName = name;
629             this.functionType = functionType;
630             this.body = builder.build(this);
631         }
632 
633         public FuncOp(FuncOp that, CopyContext cc) {
634             super(that, cc);
635             this.functionName = that.functionName;
636             this.functionType = that.functionType;
637             this.body = that.body;
638         }
639 
640         @Override
641         public FuncOp transform(CopyContext cc, OpTransformer ot) {
642             return new FuncOp(this, cc);
643         }
644 
645         @Override
646         public Body body() {
647             return body;
648         }
649 
650         public String functionName() {
651             return functionName;
652         }
653 
654         @Override
655         public List<Body> bodies() {
656             return List.of(body);
657         }
658 
659         @Override
660         public FunctionType invokableType() {
661             return functionType;
662         }
663     }
664 }