package datapath.graph; import datapath.graph.operations.*; import java.util.HashSet; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; /** * Inserts ShiftRegisters balance the use of operation results in scheduled graphs * @author jh */ public class BalanceOutput extends Optimization { public BalanceOutput(Graph graph) { super(graph); } @Override public void perform() { for (Operation op : graph.getOperations().toArray(new Operation[0])) { balanceUse(op); } } private void balanceUse(Operation op) { Set<Operation> use = op.getUse(); if (use.size() <= 1) { return; } SortedSet<UseEdge> uses = new TreeSet<UseEdge>(); for(Operation x : use) { boolean added = uses.add(new UseEdge(op, x)); assert added; } if(uses.first().distance() == uses.last().distance()) return; // System.out.println("must balance:"+op); // System.out.println(); Set<UseEdge> shortestDistance = edgesWithShortestDistance(uses); int dist = shortestDistance.iterator().next().distance(); uses.removeAll(shortestDistance); Nop nop = new Nop(); for(UseEdge e : uses){ e.getTarget().replace(e.getSource(), nop); } nop.setSchedule(op.getSchedule()+op.getDelay()+dist); nop.setData(op); nop.setExecutionOrdinal(op.getExecutionOrdinal()); graph.addOperation(nop); balanceUse(nop); } private Set<UseEdge> edgesWithShortestDistance(SortedSet<UseEdge> uses){ HashSet<UseEdge> shortest = new HashSet(uses); UseEdge firstLonger = null; for(UseEdge e : uses){ if(e.distance() > uses.first().distance()) { firstLonger = e; break; } } assert firstLonger != null; shortest.removeAll(uses.tailSet(firstLonger)); return shortest; } }