From 554b7a0775a091333e136609b40dcfbb3deef488 Mon Sep 17 00:00:00 2001 From: adam Date: Sun, 7 Sep 2008 07:11:53 +0100 Subject: [PATCH] improvements to LoopFactory --- .../berkeley/fleet/ir/{Loops.java => Context.java} | 137 +++++++++++++------- 1 file changed, 88 insertions(+), 49 deletions(-) rename src/edu/berkeley/fleet/ir/{Loops.java => Context.java} (70%) diff --git a/src/edu/berkeley/fleet/ir/Loops.java b/src/edu/berkeley/fleet/ir/Context.java 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 --- a/src/edu/berkeley/fleet/ir/Loops.java +++ b/src/edu/berkeley/fleet/ir/Context.java @@ -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 loopFactories = new HashSet(); + + 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 instructions = new ArrayList(); /** * 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; 0 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; 0 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); } } -- 1.7.10.4