improvements to LoopFactory
authoradam <adam@megacz.com>
Sun, 7 Sep 2008 06:11:53 +0000 (07:11 +0100)
committeradam <adam@megacz.com>
Sun, 7 Sep 2008 06:11:53 +0000 (07:11 +0100)
src/edu/berkeley/fleet/ir/Context.java [moved from src/edu/berkeley/fleet/ir/Loops.java with 70% similarity]

similarity index 70%
rename from src/edu/berkeley/fleet/ir/Loops.java
rename to src/edu/berkeley/fleet/ir/Context.java
index 339e593..e4b0fe6 100644 (file)
@@ -1,4 +1,4 @@
-package edu.berkeley.fleet;
+package edu.berkeley.fleet.ir;
 import java.util.*;
 import java.net.*;
 import edu.berkeley.fleet.two.*;
@@ -9,60 +9,76 @@ import edu.berkeley.fleet.api.Instruction.Set.*;
 import static edu.berkeley.fleet.util.BitManipulations.*;
 import static edu.berkeley.fleet.two.FleetTwoFleet.SHIFT;
 
-// EXPERIMENTAL.  Do not use.
-
-// FEATURE: official definition of what a nonblocking instruction is
-
 /**
+ *  A Context is a collection of Loops which obey these rules:
  *
- *  A helper class for building loops of instructions.
- *
- *  This class abstracts away:
- *    - The maximum size of a loop
- *    - The maximum length of a "one shot" instruction sequence
- *    - The looping/oneshot bit
- *    - The outer loop counter
- *    - The inner loop counter (opportunities to use it are auto-detected)
- *
- *  It also performs various optimizations and provides a more
- *  convenient way of managing the predicate/interruptible fields.
- *
- *  To get the most compact coding, the components of a Move should be
- *  performed in this order when possible, with no intervening commands:
- *
- *    1. recvToken()
- *    2. recv()/collect()
- *    3. sendToken()
- *    4. deliver()/send()
- *
+ *    - There is a designated entry point loop which is invoked when the Context is loaded
+ *    - Loops in a Context may only invoke other Loops in the same Context
+ *    - A Context has exclusive control of all docks mentioned by any of its Loops
+ *    - A Context does not exit until all of its Loops have exited.
  */
-public class Loops {
-
-    public static abstract class Loop {
-        private final Dock dock;
-        private final String friendlyName;
-        private final int count;
+public class Context {
+
+    private HashSet<LoopFactory> loopFactories = new HashSet<LoopFactory>();
+
+    public Context() { }
+
+    /**
+     *
+     *  A helper class for building loops of instructions.
+     *
+     *  This class abstracts away:
+     *    - The maximum size of a loop
+     *    - The maximum length of a "one shot" instruction sequence
+     *    - The looping/oneshot bit
+     *    - The outer loop counter
+     *    - The inner loop counter (opportunities to use it are auto-detected)
+     *
+     *  It also performs various optimizations and provides a more
+     *  convenient way of managing the predicate/interruptible fields.
+     *
+     *  To get the most compact coding, the components of a Move should be
+     *  performed in this order when possible, with no intervening commands:
+     *
+     *    1. recvToken()
+     *    2. recv()/collect()
+     *    3. sendToken()
+     *    4. deliver()/send()
+     *
+     */
+    public class LoopFactory {
+        public final Dock dock;
+        public final String friendlyName;
+        public final int count;
         private Predicate predicate = Predicate.Default;
-        private Loop next = null;
+        private LoopFactory next = null;
         private ArrayList<Instruction> instructions = new ArrayList<Instruction>();
 
         /**
          *  Creates a new loop.
-         *   @dock the dock at which to execute the instructions
-         *   @friendlyName a descriptive string for debugging the compiler
-         *   @prev a loop for which this is the successor loop (if any)
-         *   @count the number of times to execute this loop; <tt>0</tt> means continue until torpedoed
+         *   @arg dock         the dock at which to execute the instructions
+         *   @arg friendlyName a descriptive string for debugging the compiler
+         *   @arg prev         a loop for which this is the successor loop (if any)
+         *   @arg count        the number of times to execute this loop; <tt>0</tt> means continue until torpedoed
          */
-        public Loop(Dock dock, int count, String friendlyName, Loop prev) {
+        public LoopFactory(Dock dock, int count) { this(dock, count, dock.toString(), null); }
+        public LoopFactory(Dock dock, int count, String friendlyName) { this(dock, count, friendlyName, null); }
+        public LoopFactory(Dock dock, int count, String friendlyName, LoopFactory prev) {
             this.dock = dock;
             this.count = count;
             this.friendlyName = friendlyName;
-            if (prev.getNext() != null) throw new RuntimeException();
-            prev.setNext(this);
+            Context.this.loopFactories.add(this);
+            if (prev != null) {
+                if (prev.getNext() != null) throw new RuntimeException();
+                prev.setNext(this);
+            }
         }
 
-        public Loop getNext() { return next; }
-        public void setNext(Loop next) { this.next = next; }
+        public LoopFactory getNext() { return next; }
+        public void setNext(LoopFactory next) {
+            if (this.next != null) throw new RuntimeException("attempt to setNext() twice");
+            this.next = next;
+        }
 
 
         // Building Loops //////////////////////////////////////////////////////////////////////////////
@@ -193,11 +209,22 @@ public class Loops {
                                                  newFlagB));
         }
 
+        // FIXME: what if we're using an ILC-loop?
+        /** abort the loop immediately (if predicate is met) */
+        public void abort() {
+            flush_pending();
+            instructions.add(new Instruction.Set(dock,
+                                                 count!=1,
+                                                 predicate,
+                                                 SetDest.OuterLoopCounter,
+                                                 0));
+        }
 
         // Emitting Code //////////////////////////////////////////////////////////////////////////////
 
         void optimize() {
             flush_pending();
+            // FEATURE: find loops of 1 instruction, use ILC
             // FEATURE: find sequences of >2 adjacent identical instructions, replace with use of ILC
             // FEATURE: after optimizing, find single-instruction loops, replace with use of ILC
             // FEATURE: consider doing loop unrolling if two copies of the loop fit in the instruction buffer...
@@ -240,17 +267,27 @@ public class Loops {
                 ic.add(i);
             }
 
-            if (count!=1) {
+            if (count==1) {
+                if (numInstructionsNotIncludingNonblockingPrefix > dock.getInstructionFifoSize())
+                    throw new RuntimeException("instruction sequence is too long for instruction fifo");
+            } else {
+                if (count != 0) {
+                    ic.add(new Instruction.Set(dock, true, Predicate.Default, SetDest.OuterLoopCounter, SetSource.Decrement));
+                    if (blockingInstructionEncountered)
+                        numInstructionsNotIncludingNonblockingPrefix++;
+                    loopSize++;
+                }
                 ic.add(new Instruction.Tail(dock));
                 if (loopSize > dock.getInstructionFifoSize())
                     throw new RuntimeException("instruction loop is too long for instruction fifo");
-            } else {
-                if (numInstructionsNotIncludingNonblockingPrefix > dock.getInstructionFifoSize())
-                    throw new RuntimeException("instruction sequence is too long for instruction fifo");
             }
 
-            if (next != null)
-                throw new RuntimeException("no support for successor loops yet");
+            if (next != null) {
+                if (count != 1) throw new RuntimeException("no support for successor loops when count!=1 yet");
+                // FIXME: must include check based on reduced FIFO capacity
+                // FIXME: review this
+                next.emit(ic);
+            }
         }
 
         void warn(String warning) {
@@ -259,9 +296,11 @@ public class Loops {
 
         // Helpers //////////////////////////////////////////////////////////////////////////////
 
-        public void recvData() { recv(true, false); }
+        public void recvWord() { recv(true, false); }
+        public void recvPath() { recv(false, true); }
         public void recvPacket() { recv(true, true); }
-        public void collectData() { collect(true, false); }
+        public void collectWord() { collect(true, false); }
+        public void collectPath() { collect(false, true); }
         public void collectPacket() { collect(true, true); }
 
     }