(refs #7218) Sort labels by integer values when generating switch 14/514/1
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 12 May 2017 10:22:50 +0000 (13:22 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 12 May 2017 10:22:50 +0000 (13:22 +0300)
Change-Id: Ic6acb6241151f3d178e4c5bdf9c4fac5424b6100

bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Switch.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching6.scl [new file with mode: 0644]

index 27f853e0283b3d714757f4d3369cab4379cf470d..386199d838d3cfd0e60cb1faea0375bb45791e21 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.scl.compiler.internal.codegen.ssa.exits;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 import org.objectweb.asm.Label;
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
@@ -26,6 +27,8 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.TIntObjectHashMap;
+
 public class Switch extends SSAExit implements ValRefBinder {
 
     ValRef scrutinee;
@@ -60,14 +63,19 @@ public class Switch extends SSAExit implements ValRefBinder {
         int defaultId;
         for(defaultId=0;defaultId<branches.length-1&&branches[defaultId].constructor!=null;++defaultId);
         int[] values = new int[defaultId];
-        Label[] labels = new Label[defaultId];
         Cont[] continuations = new Cont[defaultId+1];
+        TIntObjectHashMap<Label> labelMap = new TIntObjectHashMap<Label>(defaultId); 
         for(int i=0;i<defaultId;++i) {
-            values[i] = ((IntegerConstant)branches[i].constructor).getValue();
+            int value = ((IntegerConstant)branches[i].constructor).getValue();
+            values[i] = value;
             Cont cont = branches[i].cont.getBinding();
-            labels[i] = mb.getLabel(cont);
+            labelMap.put(value,  mb.getLabel(cont));
             continuations[i] = cont;
         }
+        Arrays.sort(values);
+        Label[] labels = new Label[defaultId];
+        for(int i=0;i<defaultId;++i)
+            labels[i] = labelMap.get(values[i]);
         Label defaultLabel;
         {
             Cont cont = branches[defaultId].cont.getBinding();
index 4701e2586e961465e9a9a6c95085b984eb8111a2..dc2c775241574595b88c5f36ccdf75e8610782c6 100644 (file)
@@ -147,6 +147,7 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void Matching2() { test(); }
     @Test public void Matching4() { test(); }
     @Test public void Matching5() { test(); }
+    @Test public void Matching6() { test(); }
     @Test public void MatchingWithMissingParameter() { test(); }
     @Test public void MatchingWithoutTypeAnnotations() { test(); }
     @Test public void MaximumBy() { test(); }
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching6.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Matching6.scl
new file mode 100644 (file)
index 0000000..f4f7cc4
--- /dev/null
@@ -0,0 +1,9 @@
+import "Prelude"
+
+main = do 
+    match 1+1 :: Integer with
+        2 -> 2
+        0 -> 0
+        1 -> 1
+--
+2
\ No newline at end of file