1 /*
  2  * Copyright (c) 2026, 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 import jdk.incubator.code.*;
 25 import jdk.incubator.code.analysis.SSA;
 26 import jdk.incubator.code.dialect.java.JavaOp;
 27 import org.junit.jupiter.api.Assertions;
 28 import org.junit.jupiter.api.Test;
 29 
 30 import java.util.List;
 31 import java.util.function.IntBinaryOperator;
 32 import java.util.function.IntUnaryOperator;
 33 
 34 /*
 35  * @test
 36  * @modules jdk.incubator.code
 37  * @enablePreview
 38  * @run junit TestCompareCodeItems
 39  */
 40 
 41 public class TestCompareCodeItems {
 42 
 43     @Reflect
 44     IntBinaryOperator f = (a, b) -> {
 45         IntUnaryOperator u = v ->
 46                 v + ((a > b) ? a : b + 42);
 47         int sum = 0;
 48         for (int i = 0; i < 10; i++) {
 49             sum += u.applyAsInt(i) + 42;
 50             if (sum instanceof byte _) {
 51                 // Increment sum if it fits in a byte
 52                 sum++;
 53             }
 54         }
 55         return sum;
 56     };
 57 
 58     @Test
 59     public void testCompareCodeElements() {
 60         JavaOp.LambdaOp op = Op.ofLambda(f).orElseThrow().op();
 61 
 62         testCompareCodeElements(op);
 63         op = op.transform(CodeContext.create(), CodeTransformer.LOWERING_TRANSFORMER);
 64         testCompareCodeElements(op);
 65     }
 66 
 67     void testCompareCodeElements(Op op) {
 68         List<CodeElement<?, ?>> l = op.elements().toList();
 69 
 70         for (int i = 0; i < l.size(); i++) {
 71             for (int j = 0; j < l.size(); j++) {
 72                 CodeElement<?, ?> a = l.get(i);
 73                 CodeElement<?, ?> b = l.get(j);
 74                 Assertions.assertEquals(CodeElement.compare(a, b), Integer.compare(i, j));
 75             }
 76         }
 77     }
 78 
 79     @Test
 80     public void testCompareCodeElementsDifferentModels() {
 81         JavaOp.LambdaOp op1 = Op.ofLambda(f).orElseThrow().op();
 82         JavaOp.LambdaOp op2 = op1.transform(CodeContext.create(), CodeTransformer.COPYING_TRANSFORMER);
 83 
 84         testCompareCodeElements(op1, op2);
 85     }
 86 
 87     void testCompareCodeElements(Op op1, Op op2) {
 88         List<CodeElement<?, ?>> l1 = op1.elements().toList();
 89         List<CodeElement<?, ?>> l2 = op2.elements().toList();
 90 
 91         for (int i = 0; i < l1.size(); i++) {
 92             for (int j = 0; j < l2.size(); j++) {
 93                 CodeElement<?, ?> a = l1.get(i);
 94                 CodeElement<?, ?> b = l2.get(j);
 95                 Assertions.assertThrows(IllegalArgumentException.class, () -> CodeElement.compare(a, b));
 96             }
 97         }
 98     }
 99 
100 
101     @Test
102     public void testCompareValues() {
103         JavaOp.LambdaOp op = Op.ofLambda(f).orElseThrow().op();
104 
105         testCompareValues(op);
106         op = op.transform(CodeContext.create(), CodeTransformer.LOWERING_TRANSFORMER);
107         testCompareValues(op);
108         op = SSA.transform(op);
109         testCompareValues(op);
110     }
111 
112     void testCompareValues(Op op) {
113         List<Value> l = op.elements().<Value>mapMulti((e, c) -> {
114             if (e instanceof Block b) {
115                 b.parameters().forEach(c);
116             } else if (e instanceof Op o) {
117                 if (o.result() != null) {
118                     c.accept(o.result());
119                 }
120             }
121         }).toList();
122 
123         for (int i = 0; i < l.size(); i++) {
124             for (int j = 0; j < l.size(); j++) {
125                 Value a = l.get(i);
126                 Value b = l.get(j);
127                 Assertions.assertEquals(Value.compare(a, b), CodeElement.compare(a.declaringElement(), b.declaringElement()));
128             }
129         }
130     }
131 }