if (!schedule.isBottomSchedule()) {  int schedNum = 0; for (; schedNum < schedule.getNumPhases(); schedNum++) { computeBuffersFor(schedule.getSubSched(schedNum)); } } else {  Object workFunc = schedule.getWorkFunc(); Iterator workStream = (Iterator) user2persistent.get(schedule.getWorkStream());   Pair workInfo = pairs.getPair(workFunc, workStream); int numWork = ((Integer) workFunctions.get(workInfo)).intValue();  if (workStream.isFilter() != null) { FilterIter filter = workStream.isFilter(); int peekAmount, popAmount, pushAmount;    if (filter.getWorkFunctionPhase(numWork) == workFunc) {  peekAmount = filter.getPeekPhase(numWork); popAmount = filter.getPopPhase(numWork); pushAmount = filter.getPushPhase(numWork); } else {  ASSERT( filter.getInitFunctionStage(numWork) == workFunc);  peekAmount = filter.getInitPeekStage(numWork); popAmount = filter.getInitPushStage(numWork); pushAmount = filter.getInitPushStage(numWork); }     if (peekAmount > 0) { BufferStatus bufferBefore = (BufferStatus) targetBufferBefore.get(workStream); bufferBefore.peekData(peekAmount); bufferBefore.popData(popAmount); }   if (pushAmount > 0) { BufferStatus bufferAfter = (BufferStatus) targetBufferAfter.get(workStream);  bufferAfter.pushData(pushAmount); } } else if (workStream.isPipeline() != null) { ERROR("Pipeline is not allowed to have any work functions!"); } else if (workStream.isSplitJoin() != null) { SplitJoinIter sj = workStream.isSplitJoin(); int popAmount, pushAmount;     if (sj.getSplitterWork(numWork) == workFunc) {  popAmount = sj.getSplitPop(numWork); pushAmount = 0;   int nChild; int pushWeights[] = sj.getSplitPushWeights(numWork); for (nChild = 0; nChild < sj.getNumChildren(); nChild++) { Iterator firstChild = getFirstStream(sj.getChild(nChild)); BufferStatus bufferBefore = (BufferStatus) targetBufferBefore.get( firstChild); bufferBefore.pushData(pushWeights[nChild]); } } else {  popAmount = 0; pushAmount = sj.getJoinPush(numWork);   int nChild; int popWeights[] = sj.getJoinPopWeights(numWork); for (nChild = 0; nChild < sj.getNumChildren(); nChild++) { Iterator lastChild = getLastStream(sj.getChild(nChild)); BufferStatus bufferAfter = (BufferStatus) targetBufferAfter.get( lastChild); bufferAfter.popData(popWeights[nChild]); } }   if (popAmount > 0) { BufferStatus bufferBefore = (BufferStatus) targetBufferBefore.get(workStream); bufferBefore.popData(popAmount); }   if (pushAmount > 0) { BufferStatus bufferAfter = (BufferStatus) targetBufferAfter.get(workStream);  bufferAfter.pushData(pushAmount); } } else if (workStream.isFeedbackLoop() != null) { FeedbackLoopIter feedbackLoop = workStream.isFeedbackLoop(); Iterator body = feedbackLoop.getBodyChild(); Iterator loop = feedbackLoop.getLoopChild();  int popAmount, pushAmount;     if (feedbackLoop.getSplitterWork(numWork) == workFunc) {  popAmount = 0; pushAmount = feedbackLoop.getSplitPushWeights(numWork)[0];   { BufferStatus bodyBuffer = (BufferStatus) targetBufferAfter.get(getLastStream(body)); bodyBuffer.popData( feedbackLoop.getSplitPop(numWork)); }   { BufferStatus loopBuffer = (BufferStatus) targetBufferBefore.get(getFirstStream(loop)); loopBuffer.pushData( feedbackLoop.getSplitPushWeights(numWork)[1]); }  } else {  popAmount = feedbackLoop.getJoinPopWeights(numWork)[0]; pushAmount = 0;   { BufferStatus bodyBuffer = (BufferStatus) targetBufferBefore.get(getFirstStream(body)); bodyBuffer.pushData( feedbackLoop.getJoinPush(numWork)); }   { BufferStatus loopBuffer = (BufferStatus) targetBufferAfter.get(getLastStream(loop)); loopBuffer.popData( feedbackLoop.getJoinPopWeights(numWork)[1]); } }   if (popAmount > 0) { BufferStatus bufferBefore = (BufferStatus) targetBufferBefore.get(workStream); bufferBefore.popData(popAmount); }   if (pushAmount > 0) { BufferStatus bufferAfter = (BufferStatus) targetBufferAfter.get(workStream);  bufferAfter.pushData(pushAmount); } } else ERROR("stream variable is not a known stream type!"); }
BufferStatus buffer = (BufferStatus) iter.next(); BufferDelta delta = (BufferDelta) map.get(buffer);  buffer.pushData(delta.getBufferExpansion()); buffer.popData(delta.getBufferExpansion() - delta.getBufferDelta());
    public void computeBuffersFor(Schedule schedule)    {        int numExecs = schedule.getNumReps();        for (; numExecs > 0; numExecs--)        {            // is this a schedule that contains other schedules?            if (!schedule.isBottomSchedule())            {                // yes - just run through other schedules!                int schedNum = 0;                for (; schedNum < schedule.getNumPhases(); schedNum++)                {                    computeBuffersFor(schedule.getSubSched(schedNum));                }            }            else            {                // no - this is a bona-fide work function                Object workFunc = schedule.getWorkFunc();                Iterator workStream =                    (Iterator) user2persistent.get(schedule.getWorkStream());                // figure out what object contributed this work function:                Pair workInfo = pairs.getPair(workFunc, workStream);                int numWork =                    ((Integer) workFunctions.get(workInfo)).intValue();                if (workStream.isFilter() != null)                {                    FilterIter filter = workStream.isFilter();                    int peekAmount, popAmount, pushAmount;                    // check if the function is a work or init function                    // and get appropriate peek/pop/push values                    if (filter.getWorkFunctionPhase(numWork) == workFunc)                    {                        // work function                        peekAmount = filter.getPeekPhase(numWork);                        popAmount = filter.getPopPhase(numWork);                        pushAmount = filter.getPushPhase(numWork);                    }                    else                    {                        // init function                        ASSERT(                            filter.getInitFunctionStage(numWork) == workFunc);                        peekAmount = filter.getInitPeekStage(numWork);                        popAmount = filter.getInitPushStage(numWork);                        pushAmount = filter.getInitPushStage(numWork);                    }                    // update the buffers appropriately                    // update buffer before, only if it's used                    if (peekAmount > 0)                    {                        BufferStatus bufferBefore =                            (BufferStatus) targetBufferBefore.get(workStream);                        bufferBefore.peekData(peekAmount);                        bufferBefore.popData(popAmount);                    }                    // update buffer after only if it's used                    if (pushAmount > 0)                    {                        BufferStatus bufferAfter =                            (BufferStatus) targetBufferAfter.get(workStream);                        bufferAfter.pushData(pushAmount);                    }                }                else if (workStream.isPipeline() != null)                {                    ERROR("Pipeline is not allowed to have any work functions!");                }                else if (workStream.isSplitJoin() != null)                {                    SplitJoinIter sj = workStream.isSplitJoin();                    int popAmount, pushAmount;                    // check if the function is a splitter or joiner function                    // and get appropriate pop/push values                    // also update the internal buffers!                    if (sj.getSplitterWork(numWork) == workFunc)                    {                        // splitter function                        popAmount = sj.getSplitPop(numWork);                        pushAmount = 0;                        // push data into the internal splitter buffers                        int nChild;                        int pushWeights[] = sj.getSplitPushWeights(numWork);                        for (nChild = 0;                            nChild < sj.getNumChildren();                            nChild++)                        {                            Iterator firstChild =                                getFirstStream(sj.getChild(nChild));                            BufferStatus bufferBefore =                                (BufferStatus) targetBufferBefore.get(                                    firstChild);                            bufferBefore.pushData(pushWeights[nChild]);                        }                    }                    else                    {                        // joiner function                        popAmount = 0;                        pushAmount = sj.getJoinPush(numWork);                        // push data into the internal joiner buffers                        int nChild;                        int popWeights[] = sj.getJoinPopWeights(numWork);                        for (nChild = 0;                            nChild < sj.getNumChildren();                            nChild++)                        {                            Iterator lastChild =                                getLastStream(sj.getChild(nChild));                            BufferStatus bufferAfter =                                (BufferStatus) targetBufferAfter.get(                                    lastChild);                            bufferAfter.popData(popWeights[nChild]);                        }                    }                    // update buffer before, only if it's used                    if (popAmount > 0)                    {                        BufferStatus bufferBefore =                            (BufferStatus) targetBufferBefore.get(workStream);                        bufferBefore.popData(popAmount);                    }                    // update buffer after only if it's used                    if (pushAmount > 0)                    {                        BufferStatus bufferAfter =                            (BufferStatus) targetBufferAfter.get(workStream);                        bufferAfter.pushData(pushAmount);                    }                }                else if (workStream.isFeedbackLoop() != null)                {                    FeedbackLoopIter feedbackLoop =                        workStream.isFeedbackLoop();                    Iterator body = feedbackLoop.getBodyChild();                    Iterator loop = feedbackLoop.getLoopChild();                    int popAmount, pushAmount;                    // check if the function is a splitter or joiner function                    // and get appropriate pop/push values                    // also update the internal buffers!                    if (feedbackLoop.getSplitterWork(numWork) == workFunc)                    {                        // splitter function                        popAmount = 0;                        pushAmount =                            feedbackLoop.getSplitPushWeights(numWork)[0];                        // pop data from the internal body-splitter buffer                        {                            BufferStatus bodyBuffer =                                (BufferStatus) targetBufferAfter.get(getLastStream(body));                            bodyBuffer.popData(                                feedbackLoop.getSplitPop(numWork));                        }                                                // push data to the internal splitter-loop buffer                        {                            BufferStatus loopBuffer =                                (BufferStatus) targetBufferBefore.get(getFirstStream(loop));                            loopBuffer.pushData(                                feedbackLoop.getSplitPushWeights(numWork)[1]);                        }                                            }                    else                    {                        // joiner function                        popAmount =                            feedbackLoop.getJoinPopWeights(numWork)[0];                        pushAmount = 0;                        // push data to the internal joiner-body buffer                        {                            BufferStatus bodyBuffer =                                (BufferStatus) targetBufferBefore.get(getFirstStream(body));                            bodyBuffer.pushData(                                feedbackLoop.getJoinPush(numWork));                        }                                                // pop data from the internal loop-joiner buffer                        {                            BufferStatus loopBuffer =                                (BufferStatus) targetBufferAfter.get(getLastStream(loop));                            loopBuffer.popData(                                feedbackLoop.getJoinPopWeights(numWork)[1]);                        }                    }                    // update buffer before, only if it's used                    if (popAmount > 0)                    {                        BufferStatus bufferBefore =                            (BufferStatus) targetBufferBefore.get(workStream);                        bufferBefore.popData(popAmount);                    }                    // update buffer after only if it's used                    if (pushAmount > 0)                    {                        BufferStatus bufferAfter =                            (BufferStatus) targetBufferAfter.get(workStream);                        bufferAfter.pushData(pushAmount);                    }                }                else                    ERROR("stream variable is not a known stream type!");            }        }    }