]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / analysis / StatementBrowser.java
index 8de2c37c8f1925fa33f156a4b4fb9c34425dad56..2855e88ac4f7944f1acb164c820c25025090278a 100644 (file)
-package org.simantics.scl.compiler.internal.codegen.analysis;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\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.continuations.ContRef;\r
-import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\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.SSAStatement;\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.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public abstract class StatementBrowser {\r
-\r
-    THashSet<SSABlock> visited;\r
-    THashMap<SSABlock,SSAStatement> loopPos;\r
-    SSAStatement fromStatement;\r
-    SSABlock fromBlock;\r
-    \r
-    boolean stopBrowse = false;\r
-    \r
-    protected void stopBrowse() {\r
-        stopBrowse = true;\r
-    }\r
-    \r
-    public boolean isStopped() {\r
-        return stopBrowse;\r
-    }\r
-    \r
-    /**\r
-     * Browses all statements that are potentially executed\r
-     * between from and to.\r
-     */\r
-    public void browseBetween(SSAStatement from, SSAStatement to) {\r
-        SSABlock toBlock = to.getParent();\r
-        if(from.getParent() == toBlock) {\r
-            for(SSAStatement cur = from.getNext(); cur != to; cur = cur.getNext()) {\r
-                if(cur == null)\r
-                    dominationError();\r
-                visitStatement(cur);\r
-                if(stopBrowse)\r
-                    return;\r
-            }\r
-        }\r
-        else {\r
-            for(SSAStatement cur = to.getPrev(); cur != null; cur = cur.getPrev()) {\r
-                visitStatement(cur);\r
-                if(stopBrowse)\r
-                    return;\r
-            }\r
-\r
-            visited = new THashSet<SSABlock>();            \r
-            fromStatement = from;\r
-            fromBlock = from.getParent();\r
-            \r
-            loopPos = new THashMap<SSABlock,SSAStatement>();\r
-            loopPos.put(toBlock, to);\r
-\r
-            browsePredecessors(toBlock);            \r
-        }\r
-    }\r
-    \r
-    private void browseBetweenRec(SSAStatement to) {\r
-        SSABlock toBlock = to.getParent();\r
-        if(fromBlock == toBlock) {\r
-            for(SSAStatement cur = fromStatement.getNext(); cur != to; cur = cur.getNext()) {\r
-                if(cur == null)\r
-                    dominationError();\r
-                visitStatement(cur);\r
-                if(stopBrowse)\r
-                    return;\r
-            }\r
-        }\r
-        else {\r
-            for(SSAStatement cur = to.getPrev(); cur != null; cur = cur.getPrev()) {\r
-                visitStatement(cur);\r
-                if(stopBrowse)\r
-                    return;\r
-            }\r
-            loopPos.put(toBlock, to);\r
-            browsePredecessors(to.getParent());            \r
-        }\r
-    }\r
-    \r
-    private void browsePredecessors(SSABlock block) {\r
-        for(ContRef contRef = block.getOccurrence(); contRef != null; contRef = contRef.getNext()) {\r
-            browse(contRef.getParent().getParent());\r
-            if(stopBrowse)\r
-                return;\r
-        }\r
-    }    \r
-    \r
-    private void browse(SSABlock block) {\r
-        if(!visited.add(block))\r
-            return;\r
-        if(block == fromBlock) {\r
-            for(SSAStatement cur = fromStatement.getNext(); cur != null; cur = cur.getNext()) {\r
-                visitStatement(cur);\r
-                if(stopBrowse)\r
-                    return;\r
-            }\r
-            return;\r
-        }\r
-        if(loopPos.contains(block)) {\r
-            handleLoop(block, loopPos.get(block));\r
-            return;\r
-        }\r
-        for(SSAStatement cur = block.getFirstStatement(); cur != null; cur = cur.getNext()) {\r
-            visitStatement(cur);\r
-            if(stopBrowse)\r
-                return;\r
-        }\r
-        browsePredecessors(block);\r
-        if(stopBrowse)\r
-            return;\r
-        if(block.getPrev() == null) {\r
-            SSAFunction function = block.getParent();\r
-            if(function == fromBlock.getParent())\r
-                dominationError();\r
-            Val functionTarget = function.getTarget();\r
-            if(functionTarget instanceof BoundVar)\r
-                browseFunction((BoundVar)functionTarget, function.getArity());\r
-            else\r
-                dominationError();\r
-        }\r
-    }\r
-    \r
-    private static void dominationError() {\r
-        throw new InternalCompilerError("Statement 'from' does not dominate the statement 'to'.");\r
-    }\r
-\r
-    protected void browseFunction(BoundVar function, int arity) {\r
-        for(ValRef cur = function.getOccurrence(); cur != null; cur = cur.getNext()) {\r
-            ValRefBinder binder = cur.getParent();\r
-            if(binder instanceof LetApply)\r
-                browseApply((LetApply)binder, cur, arity);\r
-            else\r
-                unanalyzedBrowse();\r
-            if(stopBrowse)\r
-                return;\r
-        }\r
-    }\r
-    \r
-    private static boolean callsOnlyOnce(Name name, int arity) {\r
-        if(name == Names.Prelude_build)\r
-            return arity == 1;\r
-        else\r
-            return false;\r
-    }\r
-    \r
-    protected void browseApply(LetApply apply, ValRef functionRef, int arity) {\r
-        ValRef applyFunctionRef = apply.getFunction(); \r
-        if(applyFunctionRef == functionRef) {\r
-            if(apply.getParameters().length == arity)\r
-                browseBetweenRec(apply);\r
-            else\r
-                unanalyzedBrowse();\r
-        }\r
-        else {\r
-            Val applyFunction = applyFunctionRef.getBinding();\r
-            if(!(applyFunction instanceof SCLConstant)) {\r
-                unanalyzedBrowse();\r
-                return;\r
-            }\r
-            Name name = ((SCLConstant)applyFunction).getName();\r
-            if(callsOnlyOnce(name, arity))\r
-                browseBetweenRec(apply);\r
-            else\r
-                unanalyzedBrowse();\r
-        }\r
-    }\r
-    \r
-    protected void unanalyzedBrowse() {\r
-    }\r
-\r
-    protected void visitStatement(SSAStatement statement) {        \r
-    }\r
-    \r
-    protected void handleLoop(SSABlock block, SSAStatement recursiveStatement) {\r
-        for(SSAStatement cur = recursiveStatement; cur != null; cur = cur.getNext()) {\r
-            visitStatement(cur);\r
-            if(stopBrowse)\r
-                return;\r
-        }\r
-    }\r
-    \r
-    public boolean doesAlwaysReach() {\r
-        for(SSABlock block : visited)\r
-            for(SSABlock successor : block.getExit().getSuccessors())\r
-                if(!visited.contains(successor))\r
-                    return false;\r
-        return true;\r
-    }\r
-    \r
-}\r
+package org.simantics.scl.compiler.internal.codegen.analysis;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+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.continuations.ContRef;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+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.SSAStatement;
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+public abstract class StatementBrowser {
+
+    THashSet<SSABlock> visited;
+    THashMap<SSABlock,SSAStatement> loopPos;
+    SSAStatement fromStatement;
+    SSABlock fromBlock;
+    
+    boolean stopBrowse = false;
+    
+    protected void stopBrowse() {
+        stopBrowse = true;
+    }
+    
+    public boolean isStopped() {
+        return stopBrowse;
+    }
+    
+    /**
+     * Browses all statements that are potentially executed
+     * between from and to.
+     */
+    public void browseBetween(SSAStatement from, SSAStatement to) {
+        SSABlock toBlock = to.getParent();
+        if(from.getParent() == toBlock) {
+            for(SSAStatement cur = from.getNext(); cur != to; cur = cur.getNext()) {
+                if(cur == null)
+                    dominationError();
+                visitStatement(cur);
+                if(stopBrowse)
+                    return;
+            }
+        }
+        else {
+            for(SSAStatement cur = to.getPrev(); cur != null; cur = cur.getPrev()) {
+                visitStatement(cur);
+                if(stopBrowse)
+                    return;
+            }
+
+            visited = new THashSet<SSABlock>();            
+            fromStatement = from;
+            fromBlock = from.getParent();
+            
+            loopPos = new THashMap<SSABlock,SSAStatement>();
+            loopPos.put(toBlock, to);
+
+            browsePredecessors(toBlock);            
+        }
+    }
+    
+    private void browseBetweenRec(SSAStatement to) {
+        SSABlock toBlock = to.getParent();
+        if(fromBlock == toBlock) {
+            for(SSAStatement cur = fromStatement.getNext(); cur != to; cur = cur.getNext()) {
+                if(cur == null)
+                    dominationError();
+                visitStatement(cur);
+                if(stopBrowse)
+                    return;
+            }
+        }
+        else {
+            for(SSAStatement cur = to.getPrev(); cur != null; cur = cur.getPrev()) {
+                visitStatement(cur);
+                if(stopBrowse)
+                    return;
+            }
+            loopPos.put(toBlock, to);
+            browsePredecessors(to.getParent());            
+        }
+    }
+    
+    private void browsePredecessors(SSABlock block) {
+        for(ContRef contRef = block.getOccurrence(); contRef != null; contRef = contRef.getNext()) {
+            browse(contRef.getParent().getParent());
+            if(stopBrowse)
+                return;
+        }
+    }    
+    
+    private void browse(SSABlock block) {
+        if(!visited.add(block))
+            return;
+        if(block == fromBlock) {
+            for(SSAStatement cur = fromStatement.getNext(); cur != null; cur = cur.getNext()) {
+                visitStatement(cur);
+                if(stopBrowse)
+                    return;
+            }
+            return;
+        }
+        if(loopPos.contains(block)) {
+            handleLoop(block, loopPos.get(block));
+            return;
+        }
+        for(SSAStatement cur = block.getFirstStatement(); cur != null; cur = cur.getNext()) {
+            visitStatement(cur);
+            if(stopBrowse)
+                return;
+        }
+        browsePredecessors(block);
+        if(stopBrowse)
+            return;
+        if(block.getPrev() == null) {
+            SSAFunction function = block.getParent();
+            if(function == fromBlock.getParent())
+                dominationError();
+            Val functionTarget = function.getTarget();
+            if(functionTarget instanceof BoundVar)
+                browseFunction((BoundVar)functionTarget, function.getArity());
+            else
+                dominationError();
+        }
+    }
+    
+    private static void dominationError() {
+        throw new InternalCompilerError("Statement 'from' does not dominate the statement 'to'.");
+    }
+
+    protected void browseFunction(BoundVar function, int arity) {
+        for(ValRef cur = function.getOccurrence(); cur != null; cur = cur.getNext()) {
+            ValRefBinder binder = cur.getParent();
+            if(binder instanceof LetApply)
+                browseApply((LetApply)binder, cur, arity);
+            else
+                unanalyzedBrowse();
+            if(stopBrowse)
+                return;
+        }
+    }
+    
+    private static boolean callsOnlyOnce(Name name, int arity) {
+        if(name == Names.Prelude_build)
+            return arity == 1;
+        else
+            return false;
+    }
+    
+    protected void browseApply(LetApply apply, ValRef functionRef, int arity) {
+        ValRef applyFunctionRef = apply.getFunction(); 
+        if(applyFunctionRef == functionRef) {
+            if(apply.getParameters().length == arity)
+                browseBetweenRec(apply);
+            else
+                unanalyzedBrowse();
+        }
+        else {
+            Val applyFunction = applyFunctionRef.getBinding();
+            if(!(applyFunction instanceof SCLConstant)) {
+                unanalyzedBrowse();
+                return;
+            }
+            Name name = ((SCLConstant)applyFunction).getName();
+            if(callsOnlyOnce(name, arity))
+                browseBetweenRec(apply);
+            else
+                unanalyzedBrowse();
+        }
+    }
+    
+    protected void unanalyzedBrowse() {
+    }
+
+    protected void visitStatement(SSAStatement statement) {        
+    }
+    
+    protected void handleLoop(SSABlock block, SSAStatement recursiveStatement) {
+        for(SSAStatement cur = recursiveStatement; cur != null; cur = cur.getNext()) {
+            visitStatement(cur);
+            if(stopBrowse)
+                return;
+        }
+    }
+    
+    public boolean doesAlwaysReach() {
+        for(SSABlock block : visited)
+            for(SSABlock successor : block.getExit().getSuccessors())
+                if(!visited.contains(successor))
+                    return false;
+        return true;
+    }
+    
+}