]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / analysis / LoopAnalysis.java
index 34f6578e33e847619a4ed6c3c62c090d9f0d2399..db74fc32cd78293f093b70874b3a41d7403c2ebc 100644 (file)
@@ -1,89 +1,89 @@
-package org.simantics.scl.compiler.internal.codegen.analysis;\r
-\r
-import org.simantics.scl.compiler.common.names.Name;\r
-import org.simantics.scl.compiler.common.names.Names;\r
-import org.simantics.scl.compiler.constants.SCLConstant;\r
-import org.simantics.scl.compiler.internal.codegen.references.Val;\r
-import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public class LoopAnalysis {\r
-\r
-    /**\r
-     * Checks if it is possible to return to the loop after exiting \r
-     * before exiting the function where the block belongs to.\r
-     */\r
-    private static boolean isLoopingBlock(SSABlock block) {\r
-        THashSet<SSABlock> handled = new THashSet<SSABlock>();\r
-        for(SSABlock succBlock : block.getExit().getSuccessors())\r
-            if(isLoopingBlock(block, handled, succBlock))\r
-                return true;\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Checks if it is possible to execute block more than once without visiting\r
-     * the breaker block. It is assumed that breaker is a dominator of the block.\r
-     */\r
-    public static boolean isLoopingBlockWithBreaker(SSABlock block, SSABlock breaker) {\r
-        SSAFunction function = block.getParent();\r
-        \r
-        if(function == block.getParent()) {            \r
-            THashSet<SSABlock> handled = new THashSet<SSABlock>();\r
-            handled.add(breaker);\r
-            for(SSABlock succBlock : block.getExit().getSuccessors())\r
-                if(isLoopingBlock(block, handled, succBlock))\r
-                    return true;\r
-            return false;\r
-        }\r
-        else {\r
-            if(isLoopingBlock(block))\r
-                return false;\r
-            Val functionTarget = function.getTarget();\r
-            if(functionTarget.hasMoreThanOneOccurences())\r
-                return false;\r
-            ValRef occ = functionTarget.getOccurrence();\r
-            if(occ == null)\r
-                return false;\r
-            ValRefBinder occParent = occ.getParent();\r
-            if(!(occParent instanceof LetApply))\r
-                return true; // Not necessarily the right answer, but we don't try to analyse further\r
-            LetApply apply = (LetApply)occParent;\r
-            if(!isAppliedAtMostOnce(apply, occ, function))\r
-                return true;\r
-            return isLoopingBlockWithBreaker(apply.getParent(), breaker);\r
-        }\r
-    }    \r
-    \r
-    private static boolean isAppliedAtMostOnce(LetApply apply, ValRef funRef, SSAFunction function) {\r
-        ValRef applyFunctionRef = apply.getFunction();\r
-        if(funRef == applyFunctionRef) {            \r
-            return apply.getParameters().length == function.getArity();\r
-        }\r
-        Val applyFunction = applyFunctionRef.getBinding();\r
-        if(!(applyFunction instanceof SCLConstant))\r
-            return false; // Not necessarily the right answer\r
-        Name name = ((SCLConstant)applyFunction).getName();\r
-        if(name == Names.Prelude_build)\r
-            return true;\r
-        return false;\r
-    }\r
-\r
-    private static boolean isLoopingBlock(SSABlock originalBlock,\r
-            THashSet<SSABlock> handled, SSABlock block) {\r
-        if(!handled.add(block))\r
-            return false;\r
-        if(block == originalBlock)\r
-            return true;\r
-        for(SSABlock succBlock : block.getExit().getSuccessors())\r
-            if(isLoopingBlock(originalBlock, handled, succBlock))\r
-                return true;\r
-        return false;\r
-    }\r
-    \r
-}\r
+package org.simantics.scl.compiler.internal.codegen.analysis;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.constants.SCLConstant;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+
+import gnu.trove.set.hash.THashSet;
+
+public class LoopAnalysis {
+
+    /**
+     * Checks if it is possible to return to the loop after exiting 
+     * before exiting the function where the block belongs to.
+     */
+    private static boolean isLoopingBlock(SSABlock block) {
+        THashSet<SSABlock> handled = new THashSet<SSABlock>();
+        for(SSABlock succBlock : block.getExit().getSuccessors())
+            if(isLoopingBlock(block, handled, succBlock))
+                return true;
+        return false;
+    }
+
+    /**
+     * Checks if it is possible to execute block more than once without visiting
+     * the breaker block. It is assumed that breaker is a dominator of the block.
+     */
+    public static boolean isLoopingBlockWithBreaker(SSABlock block, SSABlock breaker) {
+        SSAFunction function = block.getParent();
+        
+        if(function == block.getParent()) {            
+            THashSet<SSABlock> handled = new THashSet<SSABlock>();
+            handled.add(breaker);
+            for(SSABlock succBlock : block.getExit().getSuccessors())
+                if(isLoopingBlock(block, handled, succBlock))
+                    return true;
+            return false;
+        }
+        else {
+            if(isLoopingBlock(block))
+                return false;
+            Val functionTarget = function.getTarget();
+            if(functionTarget.hasMoreThanOneOccurences())
+                return false;
+            ValRef occ = functionTarget.getOccurrence();
+            if(occ == null)
+                return false;
+            ValRefBinder occParent = occ.getParent();
+            if(!(occParent instanceof LetApply))
+                return true; // Not necessarily the right answer, but we don't try to analyse further
+            LetApply apply = (LetApply)occParent;
+            if(!isAppliedAtMostOnce(apply, occ, function))
+                return true;
+            return isLoopingBlockWithBreaker(apply.getParent(), breaker);
+        }
+    }    
+    
+    private static boolean isAppliedAtMostOnce(LetApply apply, ValRef funRef, SSAFunction function) {
+        ValRef applyFunctionRef = apply.getFunction();
+        if(funRef == applyFunctionRef) {            
+            return apply.getParameters().length == function.getArity();
+        }
+        Val applyFunction = applyFunctionRef.getBinding();
+        if(!(applyFunction instanceof SCLConstant))
+            return false; // Not necessarily the right answer
+        Name name = ((SCLConstant)applyFunction).getName();
+        if(name == Names.Prelude_build)
+            return true;
+        return false;
+    }
+
+    private static boolean isLoopingBlock(SSABlock originalBlock,
+            THashSet<SSABlock> handled, SSABlock block) {
+        if(!handled.add(block))
+            return false;
+        if(block == originalBlock)
+            return true;
+        for(SSABlock succBlock : block.getExit().getSuccessors())
+            if(isLoopingBlock(originalBlock, handled, succBlock))
+                return true;
+        return false;
+    }
+    
+}