if(linear) if(init) System.out.println("GENERATING INIT: "+node+" "+mult); else if(primePump) System.out.println("GENERATING PRIMEPUMP: "+node+" "+mult);
    private static void createSwitchCode(FilterTraceNode node, Trace parent, 					 FilterInfo filterInfo,					 boolean init, boolean primePump, boolean linear,					 RawTile tile,					 RawChip rawChip)     {	int mult, sentItems = 0;		//don't cache align if the only source is a file reader	boolean cacheAlignSource = true;	if (node.getPrevious() instanceof InputTraceNode) {	    OffChipBuffer buf = IntraTraceBuffer.getBuffer((InputTraceNode)node.getPrevious(), 							   node).getNonRedundant();	    if (buf != null && buf.getDest() instanceof OutputTraceNode &&		((OutputTraceNode)buf.getDest()).isFileReader())		cacheAlignSource = false;	}		//don't cache align the dest if the true dest is a file writer	boolean cacheAlignDest = true; 	if (node.getNext() instanceof OutputTraceNode) {	    OutputTraceNode output = (OutputTraceNode)node.getNext();	    if (output.oneOutput() && OffChipBuffer.unnecessary(output) &&		output.getSingleEdge().getDest().isFileWriter() &&		OffChipBuffer.unnecessary(output.getSingleEdge().getDest()))		cacheAlignDest = false;	}			//each trace has 2 off-chip buffers, one for init and primepump(call this init), 	//and one for steady	//so, for the primepump stage we place in the init buffer the items that are consumed by the downstream	//trace in the steady-state, so subtract from the primepump mult the number of multiplicities	//whose items are consumed by the downstream trace in the steady state.	//handle the items that are consumed in the steady-state but produced in the pp stage below, see ppSteadyIt	//now, it is the case that non-endpoints of traces don't have to worry about this	//so, primePumpItemsNotConsumed() will return 0 for them...	if (primePump)	    mult = filterInfo.primePump - (filterInfo.push == 0 ? 0 :					   (filterInfo.primePumpItemsNotConsumed() / filterInfo.push));	else if (init)	    mult = filterInfo.initMult;	else 	    mult = filterInfo.steadyMult;	if(!(init||primePump||!linear)) { //Linear switch code in steadystate	    createLinearSwitchCode(node,init,primePump,mult,tile,rawChip);	    sentItems+=mult;	} else if (SWITCH_COMP && mult > SC_THRESHOLD && !init) {	    assert mult > 1;	    sentItems = filterInfo.push * mult;	    //add code on to send constant from tile, remember to subtract 1 because we 	    //don't have a condition at the header of the loop	    tile.getComputeCode().sendConstToSwitch(mult - 1, (init || primePump));	    //add the code on the switch to receive the constant	    MoveIns moveIns = new MoveIns(SwitchReg.R2, 					  SwitchIPort.CSTO);	    tile.getSwitchCode().appendIns(moveIns, (init || primePump));	    //send the const for the primepump items that are placed in steady buffers	    if (primePump && filterInfo.push > 0 &&		filterInfo.primePumpItemsNotConsumed() / filterInfo.push > 1) {		tile.getComputeCode().sendConstToSwitch		    ((filterInfo.primePumpItemsNotConsumed() / filterInfo.push) - 1,		     (init || primePump));		MoveIns moveIns2 = new MoveIns(SwitchReg.R3, 					       SwitchIPort.CSTO);		tile.getSwitchCode().appendIns(moveIns2, (init || primePump));	    }	    	    //add the label	    Label label = new Label();	    tile.getSwitchCode().appendIns(label, (init || primePump));		    createReceiveCode(0, node, parent, filterInfo, false, primePump, tile, rawChip);	    createSendCode(0, node, parent, filterInfo, false, primePump, tile, rawChip);	    	    generateSwitchLoopTrailer(label, tile, false, primePump);	}	else {	    for (int i = 0; i < mult; i++) {		//append the receive code		createReceiveCode(i, node, parent, filterInfo, init, primePump, tile, rawChip);		//append the send code 		sentItems += createSendCode(i, node, parent, filterInfo, init, primePump, tile, rawChip);	    }	}		//now we must take care of the remaining items on the input tape 	//after the initialization phase if the upstream filter produces more than	//we consume in init	if(init)	    System.out.println("REMAINING ITEMS: "+filterInfo.remaining);	if (init && filterInfo.remaining > 0) {	    appendReceiveInstructions(node, 				      filterInfo.remaining * Util.getTypeSize(node.getFilter().getInputType()),				      filterInfo, init, false, tile, rawChip);	}	//we must add some switch instructions to account for the fact	//that we must transfer cacheline sized chunks in the streaming dram	//do it for the init and the steady state, primepump 	//some sanity checks!	if (primePump)	    assert (sentItems == (filterInfo.totalItemsSent(init, primePump) - 				  filterInfo.primePumpItemsNotConsumed())) :	    "insane";	else	    assert (sentItems == filterInfo.totalItemsSent(init, primePump)) :	    "insane";	//generate code to fill the remainder of the cache line	if (!KjcOptions.magicdram && node.getNext().isOutputTrace() && 	    cacheAlignDest)	    fillCacheLine(node, init, primePump, sentItems);	if (primePump && filterInfo.push > 0 && 	    filterInfo.primePumpItemsNotConsumed() / filterInfo.push > 0) {	    int ppSteadyMult = (filterInfo.primePumpItemsNotConsumed() / filterInfo.push);	    //if(linear) //Linear switch code	    //createLinearSwitchCode(node,init,primePump,ppSteadyMult,tile,rawChip);	    //make sure mult > SC_THRESHOLD because we need to send the const above	    if (SWITCH_COMP && mult > SC_THRESHOLD && ppSteadyMult > 1) {		//add the label		Label label = new Label();		tile.getSwitchCode().appendIns(label, (init || primePump));					//append the receive code		createReceiveCode(0, node, parent, filterInfo, false, primePump, tile, rawChip);		//append the send code 		createSendCode(0, node, parent, filterInfo, false, primePump, tile, rawChip);				//generate the branch back		//add the branch back		BnezdIns branch = new BnezdIns(SwitchReg.R3, SwitchReg.R3, 					       label.getLabel());		tile.getSwitchCode().appendIns(branch, (init || primePump));	    }	    else {		for (int i = 0; i < ppSteadyMult; i++) {		    //append the receive code		    createReceiveCode(i, node, parent, filterInfo, init, primePump, tile, rawChip);		    //append the send code 		    createSendCode(i, node, parent, filterInfo, init, primePump, tile, rawChip);		}	    }	    	    //handle filling the cache line for the steady buffer of the primepump 	    //stage	    if (!KjcOptions.magicdram && node.getNext().isOutputTrace() && cacheAlignDest)		fillCacheLine(node, init, primePump, 			      filterInfo.primePumpItemsNotConsumed());	}	//because all dram transfers must be multiples of cacheline	//generate code to disregard the remainder of the transfer	if (!KjcOptions.magicdram && node.getPrevious().isInputTrace() && cacheAlignSource)	    handleUnneededInput(node, init, primePump, 				filterInfo.totalItemsReceived(init, primePump));    }