+ "in);\n  }
+ "in, &__credit_" + src + "_" + selfID +");\n  }
    public void visitFilter(SIRFilter self, SIRFilterIter iter) {        // create code for this filter to include in         // ClusterCodegenerator.generateRunFunction        cleanupCode = new Vector<String>();        //PPAnalyze pp = new PPAnalyze();        //self.getWork().accept(pp);                filter = self;        // RMR { now this is redundant since it is set in the constructor        // selfID = NodeEnumerator.getSIROperatorId(self); // needed by the class        // } RMR        try {            p = new CodegenPrintWriter(new FileWriter("thread" + selfID + ".cpp"));        } catch (IOException e) {            e.printStackTrace();            System.exit(1);        }        method_names = new HashSet<String>();        JMethodDeclaration[] meth = self.getMethods();        for (int i = 0; i < meth.length; i++) {            method_names.add(meth[i].getName());        }        HashSet sendsCreditsTo = LatencyConstraints            .getOutgoingConstraints(self);                // execution can only be restricted in the multi-threaded        // cluster case; in standalone mode, the schedule is fixed, so        // waiting for credits leads to infinite loop        boolean restrictedExecution = (LatencyConstraints.isRestricted(self) &&                                       !KjcOptions.standalone);        boolean sendsCredits = ! sendsCreditsTo.isEmpty();        SIRPortal outgoing[] = SIRPortal.getPortalsWithSender(self);        SIRPortal incoming[] = SIRPortal.getPortalsWithReceiver(self);        Vector<SIRStream> sends_to = new Vector<SIRStream>();        Vector<SIRStream> receives_from = new Vector<SIRStream>();        FlatNode node = NodeEnumerator.getFlatNode(selfID);        if (ClusterBackend.debugPrint)            System.out.println("flat node: " + node);        Integer init_int = (Integer) ClusterBackend.initExecutionCounts            .get(node);        int init_counts;        if (init_int == null) {            init_counts = 0;        } else {            init_counts = init_int.intValue();        }        int steady_counts = ((Integer) ClusterBackend.steadyExecutionCounts                             .get(node)).intValue();        for (int t = 0; t < outgoing.length; t++) {            SIRStream[] receivers = outgoing[t].getReceivers();            for (int i = 0; i < receivers.length; i++) {                sends_to.add(receivers[i]);            }        }        for (int t = 0; t < incoming.length; t++) {            SIRPortalSender[] senders = incoming[t].getSenders();            for (int i = 0; i < senders.length; i++) {                receives_from.add(senders[i].getStream());            }        }        int pop_n, peek_n, push_n;        pop_n = self.getPopInt();        peek_n = self.getPeekInt();        push_n = self.getPushInt();        p.print("// peek: " + peek_n + " pop: " + pop_n + " push " + push_n                + "\n");        p.print("// init counts: " + init_counts + " steady counts: "                + steady_counts + "\n");        p.newLine();        int data = DataEstimate.filterGlobalsSize(self);        CodeEstimate est = CodeEstimate.estimate(self);        // int code = CodeEstimate.estimateCode(self);        // int locals = CodeEstimate.estimateLocals(self);        int code = est.getCodeSize();        int locals = est.getLocalsSize();        if (ClusterBackend.debugPrint)            System.out.println("[globals: " + data + " locals: " + locals                               + " code: " + code + "]");        ClusterCodeGenerator gen = new ClusterCodeGenerator(self, self                                                            .getFields());        // A lot of stuff including printing field initializers.        gen.generatePreamble(this, p);         // +=============================+        // | Method Declarations |        // +=============================+        JMethodDeclaration work = self.getWork();        // visit methods of filter, print the declaration first        setDeclOnly(true);        JMethodDeclaration[] methods = self.getMethods();        for (int i = 0; i < methods.length; i++) {            if (!methods[i].equals(work)) {                methods[i].accept(this);            }        }        p.newLine();        p.print("inline void check_status__" + selfID + "();\n");        if (SIRPortal.getPortalsWithReceiver(filter).length > 0) {             p.print("void check_messages__" + selfID + "();\n");            p.print("void handle_message__" + selfID + "(netsocket *sock);\n");        }        if (sendsCredits) {            p.print("void send_credits__" + selfID + "();\n");        }        p.newLine();        // +=============================+        // | Push / Pop |        // +=============================+        CType input_type = self.getInputType();        CType output_type = self.getOutputType();        Tape in = RegisterStreams.getFilterInStream(self);        Tape out = RegisterStreams.getFilterOutStream(self);        // function prototype for work function        p.print("void " + ClusterUtils.getWorkName(self, selfID)                + "(int);\n\n");        // declarations for input tape, pop, peek.        if (in != null) {            p.print(in.downstreamDeclarationExtern());            p.print(in.downstreamDeclaration());        }                 // declarations for output tape, push.        if (out != null) {            p.print(out.upstreamDeclarationExtern());            p.print(out.upstreamDeclaration());        }        //        else {//            if (!KjcOptions.standalone) {//                // need uninteresting declarations if//                // filter has no predecessor in graph and//                // generating code for cluster WITHOUT standalone//                p.print("inline " + ClusterUtils.CTypeToString(input_type)//                        + " __init_pop_buf__" + selfID + "() {}\n");//                p.print("inline " + ClusterUtils.CTypeToString(input_type)//                        + " __update_pop_buf__" + selfID + "() {}\n");////                p.print("void save_peek_buffer__" + selfID//                        + "(object_write_buffer *buf) {}\n");//                p.print("void load_peek_buffer__" + selfID//                        + "(object_write_buffer *buf) {}\n");////                p.newLine();//            }//        }// W.T.F.  why should filter need even dummy routine to push// onto its input tape?//        if (in != null) {//	    if (! KjcOptions.standalone) {//            p.print("void " + in.push_name() + "("//                    + ClusterUtils.CTypeToString(input_type) + " data) {}\n");//            p.newLine();//	    }//        }        // +=============================+        // | Declare timers |        // +=============================+        // declare profiling timers        if (KjcOptions.profile) {            p.println("extern proc_timer timers[];");        }        p.newLine();        if ((self instanceof SIRFileReader) ||            (self instanceof SIRFileWriter)) {                        if (self instanceof SIRFileReader) { p.println("#include <FileReader.h>"); }            if (self instanceof SIRFileWriter) { p.println("#include <FileWriter.h>"); }                        p.println("int __file_descr__"+selfID+";\n");        }        // +=============================+        // | Method Bodies |        // +=============================+        setDeclOnly(false);        for (int i = 0; i < methods.length; i++) {            if (!methods[i].equals(work))                methods[i].accept(this);            // methods[i].accept(this);        }        if ((self instanceof SIRFileReader) ||            (self instanceof SIRFileWriter)) {                        if (self instanceof SIRFileReader) {                                p.println("void save_file_pointer__"+selfID+"(object_write_buffer *buf)");                p.println("{ buf->write_int(FileReader_getpos(__file_descr__"+selfID+")); }\n");                                p.println("void load_file_pointer__"+selfID+"(object_write_buffer *buf)");                p.println("{ FileReader_setpos(__file_descr__"+selfID+", buf->read_int()); }\n");            }                        if (self instanceof SIRFileWriter) {                                p.println("void save_file_pointer__"+selfID+"(object_write_buffer *buf)");                p.println("{ FileWriter_flush(__file_descr__"+selfID+");");                p.println("  buf->write_int(FileWriter_getpos(__file_descr__"+selfID+")); }\n");                                p.println("void load_file_pointer__"+selfID+"(object_write_buffer *buf)");                p.println("{ FileWriter_setpos(__file_descr__"+selfID+", buf->read_int()); }\n");            }                    } else {                        p.println("void save_file_pointer__"+selfID+"(object_write_buffer *buf) {}");            p.println("void load_file_pointer__"+selfID+"(object_write_buffer *buf) {}");                    }        // +=============================+        // | Work Function (int ____n) |        // +=============================+        boolean printed_BUFFER_MERGE = false;                if (!(self instanceof SIRFileReader) &&            !(self instanceof SIRFileWriter) &&            (in != null && out != null)) {                        if (! printed_BUFFER_MERGE) {                p.println("\n\n#ifdef BUFFER_MERGE\n");                printed_BUFFER_MERGE = true;            }            p.println();            p.println("void "+work.getName()+"__"+selfID+"__mod(int ____n, "+input_type+" *____in, "+output_type+" *____out) {");            p.print("  for (; (0 < ____n); ____n--)\n");                        mod_push_pop = true;            work.getBody().accept(this);            mod_push_pop = false;                        p.println("}\n");                    }                if (!(self instanceof SIRFileReader) &&            !(self instanceof SIRFileWriter) &&            (in != null && out != null)) {                        if (! printed_BUFFER_MERGE) {                p.println("\n\n#ifdef BUFFER_MERGE\n");                printed_BUFFER_MERGE = true;            }            p.println();            p.println("void "+work.getName()+"__"+selfID+"__mod2(int ____n, "+input_type+" *____in, "+output_type+" *____out, int s1, int s2) {");            p.print("  for (; (0 < ____n); (____n--, ____in+=s1, ____out+=s2))\n");                        mod_push_pop = true;            work.getBody().accept(this);            mod_push_pop = false;                        p.println("}\n");                    }                if (printed_BUFFER_MERGE) {        p.println("\n#endif // BUFFER_MERGE\n\n");        }                JBlock block = new JBlock(null, new JStatement[0], null);                JVariableDefinition counter = new JVariableDefinition(null, 0,                                                              CStdType.Integer, "____n", new JIntLiteral(0));                /*         *          * JVariableDefinition tmp = new JVariableDefinition(null, 0,         * CStdType.Integer, "____tmp", new JLocalVariableExpression(null,         * counter)); // int ____tmp = ____n;         *          */        JVariableDefinition iter_counter = new JVariableDefinition(null, 0,                                                                   CStdType.Integer, "__counter_" + selfID, null);        JStatement init = new JEmptyStatement(null, null);        // VariableDeclarationStatement(null, tmp, null);        JExpression decrExpr = new JPostfixExpression(null,                                                      Constants.OPE_POSTDEC, new JLocalVariableExpression(null,                                                                                                          counter));        JExpression incrExpr = new JPostfixExpression(null,                                                      Constants.OPE_POSTINC, new JLocalVariableExpression(null,                                                                                                          iter_counter));        JStatement decr = new JExpressionStatement(null, decrExpr, null);        //JStatement incr = new JExpressionStatement(null, incrExpr, null);        JExpression arr[] = new JExpression[2];        arr[0] = decrExpr;        arr[1] = incrExpr;        JExpressionListStatement list = new JExpressionListStatement(null, arr, null);        JExpression cond = new JRelationalExpression(null, Constants.OPE_LT,                                                     new JIntLiteral(0), new JLocalVariableExpression(null, counter));        if (self instanceof SIRPredefinedFilter) {            BuiltinsCodeGen.predefinedFilterWork((SIRPredefinedFilter) self,                                                 selfID, p);        } else {            block.addStatement(new JForStatement(null, init, cond,                                                  (outgoing.length + incoming.length == 0 ? decr : list),                                                  work.getBody(),                                                 new JavaStyleComment[] {                                                     new JavaStyleComment("FlatIRToCluster work function", true,                                                                          false, false)                                                 }));            // __counter_X = __counter_X + ____n;            /*             * block.addStatement(new JExpressionStatement( null, new             * JAssignmentExpression (null, new JLocalVariableExpression (null,             * iter_counter), new JAddExpression(null, new             * JLocalVariableExpression (null, iter_counter), new             * JLocalVariableExpression (null, counter))), null));             *              *              */            JFormalParameter param = new JFormalParameter(null, 0,                                                          CStdType.Integer, "____n", true);            JFormalParameter params[] = new JFormalParameter[1];            params[0] = param;            JMethodDeclaration work_n = new JMethodDeclaration(null,                                                               at.dms.kjc.Constants.ACC_PUBLIC, CStdType.Void, work                                                               .getName(), params, CClassType.EMPTY, block, null,                                                               null);            work_n.accept(this);        }        // +=============================+        // | Check Messages |        // +=============================+        if (SIRPortal.getPortalsWithReceiver(filter).length > 0) {                p.print("\nvoid check_messages__" + selfID + "() {\n");        p.print("  message *msg, *last = NULL;\n");        if (restrictedExecution) {            p.print("  while (__credit_" + selfID + " <= __counter_" + selfID                    + ") {\n");        }        if (! KjcOptions.standalone) {             //p.print("#ifndef __CLUSTER_STANDALONE\n");            {                Iterator i = receives_from.iterator();                while (i.hasNext()) {                    int src = NodeEnumerator.getSIROperatorId((SIRStream) i.next());                    p.print("  while (__msg_sock_" + src + "_" + selfID                            + "in->data_available()) {\n    handle_message__"                            + selfID + "(__msg_sock_" + src + "_" + selfID                            + "in);\n  } // if\n");                }            }            //p.print("#endif // __CLUSTER_STANDALONE\n");        }        if (restrictedExecution) {            p.print("  } // while \n");        }        p.print("  for (msg = __msg_stack_" + selfID                + "; msg != NULL; msg = msg->next) {\n");        p.print("    if (msg->execute_at == __counter_" + selfID + ") {\n");        SIRPortal[] portals = SIRPortal.getPortalsWithReceiver(self);        // this block will need to be adjusted to receive from        // multiple portals of different types (different interfaces)        if (portals.length > 0) {            CClass pclass = portals[0].getPortalType().getCClass();            CMethod pmethods[] = pclass.getMethods();            for (int i = 0; i < pmethods.length; i++) {                CMethod portal_method = pmethods[i];                CType portal_method_params[] = portal_method.getParameters();                String method_name = portal_method.getIdent();                int length = method_name.length();                if (!method_name.startsWith("<") && !method_name.endsWith(">")) {                    p.print("      if (msg->method_id == " + i + ") {\n");                    for (int t = 0; t < methods.length; t++) {                        String thread_method_name = methods[t].getName();                        if (thread_method_name.startsWith(method_name)                            && thread_method_name.charAt(length) == '_'                            && thread_method_name.charAt(length + 1) == '_') {                            int param_count = methods[t].getParameters().length;                            // declare variables for parameters                            for (int a = 0; a < param_count; a++) {                                p.print("        ");                                printDecl(portal_method_params[a], "p"+a);                                p.print(";\n");                            }                            // assign to parameters                            for (int a = 0; a < param_count; a++) {                                if (portal_method_params[a].isArrayType()) {                                    // read arrays by passing array pointer and length                                    CArrayType arrType = (CArrayType)portal_method_params[a];                                    p.print("        msg->get_" + arrType.getBaseType()                                            + "_array_param((" + arrType.getBaseType() + "*)p" + a + ", " + arrType.getTotalNumElements() + ");\n");                                } else {                                    // read primitives by calling function and assigning result                                     p.print("        p" + a                                            + " = msg->get_"                                             + portal_method_params[a] + "_param();\n");                                }                            }                            p.print("        " + thread_method_name + "__"                                    + selfID + "(");                            for (int a = 0; a < param_count; a++) {                                if (a > 0)                                    p.print(", ");                                p.print("p" + a);                            }                            p.print(");\n");                        }                    }                    p.print("      }\n");                }            }            p.print("      if (last != NULL) { \n");            p.print("        last->next = msg->next;\n");            p.print("      } else {\n");            p.print("        __msg_stack_" + selfID + " = msg->next;\n");            p.print("      }\n");            p.print("      delete msg;\n");        }        p.print("    } else if (msg->execute_at > __counter_" + selfID + ") {\n");        p.print("      last = msg;\n");        p.print("    } else { // msg->execute_at < __counter_" + selfID + "\n");        p.print("      message::missed_delivery();\n");        p.print("    }");        p.print("  } // for \n");        p.print("}\n");        // +=============================+        // | Handle Message |        // +=============================+        p.print("\nvoid handle_message__" + selfID + "(netsocket *sock) {\n");        p.print("  int size = sock->read_int();\n");        if (restrictedExecution) {            p.print("  if (size == -1) { // a credit message received\n");            p.print("    __credit_" + selfID + " = sock->read_int();\n");            p.print("    return;\n");            p.print("  }\n");        }        p.print("  int index = sock->read_int();\n");        p.print("  int iteration = sock->read_int();\n");        p            .print("  //fprintf(stderr,\"Message receieved! thread: "                   + selfID                   + ", method_index: %d excute at iteration: %d\\n\", index, iteration);\n");        p.print("  message *msg = new message(size, index, iteration);\n");        p.print("  msg->read_params(sock);\n");        p.print("  __msg_stack_" + selfID                + " = msg->push_on_stack(__msg_stack_" + selfID + ");\n");        p.print("}\n");        }        // +=============================+        // | Send Credits |        // +=============================+        if (sendsCredits) {        Iterator constrIter;        constrIter = sendsCreditsTo.iterator();        while (constrIter.hasNext()) {            LatencyConstraint constraint = (LatencyConstraint) constrIter                .next();            int receiver = NodeEnumerator.getSIROperatorId(constraint                                                           .getReceiver());            int sourcePhase = constraint.getSourceSteadyExec();            p.print("int __init_" + selfID + "_" + receiver + " = "                    + constraint.getSourceInit() + ";\n");            p.print("int __source_phase_" + selfID + "_" + receiver + " = "                    + sourcePhase + ";\n");            p.print("int __dest_phase_" + selfID + "_" + receiver + " = "                    + constraint.getDestSteadyExec() + ";\n");            p.print("int __current_" + selfID + "_" + receiver + " = 0;\n");            p.print("int __dest_offset_" + selfID + "_" + receiver + " = 0;\n");            p.print("int __dependency_" + selfID + "_" + receiver + "[] = {");            int y;            for (y = 0; y < sourcePhase - 1; y++) {                p.print(constraint.getDependencyData(y) + ",");            }            p.print(constraint.getDependencyData(y) + "};\n");            p.newLine();        }        p.print("\ninline void send_credits__" + selfID + "() {\n");        p.print("  int tmp;\n");        // HashSet sendsCreditsTo =        // LatencyConstraints.getOutgoingConstraints(self);        // boolean restrictedExecution = LatencyConstraints.isRestricted(self);        // boolean sendsCredits;        constrIter = sendsCreditsTo.iterator();        while (constrIter.hasNext()) {            LatencyConstraint constraint = (LatencyConstraint) constrIter                .next();            int receiver = NodeEnumerator.getSIROperatorId(constraint                                                           .getReceiver());            if (LatencyConstraints.isMessageDirectionDownstream(self,                                                                constraint.getReceiver())) {                // message and credit is sent downstream                p.print("  if (__counter_" + selfID + " > __init_" + selfID                        + "_" + receiver + ") {\n");                p.print("    tmp = __dependency_" + selfID + "_" + receiver                        + "[__current_" + selfID + "_" + receiver + "];\n");                p.print("    if (tmp > 0) {\n");                p.print("      __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(-1);\n");                p.print("      __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(tmp + __dest_offset_" + selfID + "_"                        + receiver + ");\n");                p.print("    }\n");                p.print("    __current_" + selfID + "_" + receiver                        + " = (__current_" + selfID + "_" + receiver                        + " + 1) % __source_phase_" + selfID + "_" + receiver                        + ";\n");                p                    .print("    if (__current_" + selfID + "_" + receiver                           + " == 0) __dest_offset_" + selfID + "_"                           + receiver + " += __dest_phase_" + selfID + "_"                           + receiver + ";\n");                p.print("  }\n");            } else {                // message and credit is sent upstream                p.print("  if (__counter_" + selfID + " == 0) {\n");                p.print("    __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(-1);\n");                p.print("    __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(__init_" + selfID + "_" + receiver                        + ");\n");                p.print("  } else {\n");                p.print("    tmp = __dependency_" + selfID + "_" + receiver                        + "[__current_" + selfID + "_" + receiver + "];\n");                p.print("    if (tmp > 0) {\n");                p.print("      __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(-1);\n");                p.print("      __msg_sock_" + selfID + "_" + receiver                        + "out->write_int(tmp + __dest_offset_" + selfID + "_"                        + receiver + ");\n");                p.print("    }\n");                p.print("    __current_" + selfID + "_" + receiver                        + " = (__current_" + selfID + "_" + receiver                        + " + 1) % __source_phase_" + selfID + "_" + receiver                        + ";\n");                p                    .print("    if (__current_" + selfID + "_" + receiver                           + " == 0) __dest_offset_" + selfID + "_"                           + receiver + " += __dest_phase_" + selfID + "_"                           + receiver + ";\n");                p.print("  }\n");            }        }        p.print("}\n");        }                // +=============================+        // | Cluster Main |        // +=============================+        Vector run =             gen.generateRunFunction(filter.getInit().getName() + "__"                                    + selfID,                                     ClusterUtils.getWorkName(filter, selfID),                                    cleanupCode);        for (int i = 0; i < run.size(); i++) {            p.print(run.elementAt(i).toString());        }        p.close();    }