/** * Get code for a joiner. If code not yet made then makes it. * * @param joiner * @param backEndBits * @return */ public static CodeStoreHelper getJoinerCode(InputSliceNode joiner, BackEndFactory backEndBits) { CodeStoreHelper joiner_code = CodeStoreHelper.findHelperForSliceNode(joiner); if (joiner_code == null) { joiner_code = backEndBits.getCodeStoreHelper(joiner); if (backEndBits.sliceNeedsJoinerCode(joiner.getParent())) { makeJoinerCode(joiner, backEndBits, joiner_code); } if (backEndBits.sliceNeedsJoinerWorkFunction(joiner.getParent())) { makeJoinerWork(joiner, backEndBits, joiner_code); } CodeStoreHelper.addHelperForSliceNode(joiner, joiner_code); } return joiner_code; }
/** * Make a work function for a joiner * * @param joiner the InputSliceNode that we are generating code for. * @param backEndBits way to refer to other portions of backend * @param joiner_code place to put code */ public static void makeJoinerWork( InputSliceNode joiner, BackEndFactory backEndBits, CodeStoreHelper joiner_code) { JMethodDeclaration joinerWork; // the work function will need a temporary variable ALocalVariable t = ALocalVariable.makeTmp(joiner.getEdgeToNext().getType()); Channel downstream = backEndBits.getChannel(joiner.getEdgeToNext()); // the body of the work method JBlock body = new JBlock(); if (backEndBits.sliceNeedsJoinerCode(joiner.getParent())) { // There should be generated code for the joiner // state machine in the CodeStoreHelper as the only method. // // generated code is // T tmp; // tmp = joiner_code(); // push(tmp); // // TODO: inline the joiner code at the call site, // if inlining, delete joiner code after inlining leaving // only this method in the helper. assert joiner_code.getMethods().length == 1; JMethodDeclaration callable_joiner = joiner_code.getMethods()[0]; body.addStatement(t.getDecl()); body.addStatement( new JExpressionStatement( new JAssignmentExpression( t.getRef(), new JMethodCallExpression(callable_joiner.getName(), new JExpression[0])))); body.addStatement( new JExpressionStatement( new JMethodCallExpression( downstream.pushMethodName(), new JExpression[] {t.getRef()}))); } else { // slice does not need joiner code, so just transfer from upstream // to downstream buffer. // // generated code is // T tmp; // tmp = pop(); // push(tmp); // assert joiner.getWidth() == 1; Channel upstream = backEndBits.getChannel(joiner.getSingleEdge()); body.addStatement(t.getDecl()); body.addStatement( new JExpressionStatement( new JAssignmentExpression( t.getRef(), new JMethodCallExpression(upstream.popMethodName(), new JExpression[0])))); body.addStatement( new JExpressionStatement( new JMethodCallExpression( downstream.pushMethodName(), new JExpression[] {t.getRef()}))); } joinerWork = new JMethodDeclaration( CStdType.Void, "_joinerWork_" + joiner.getNextFilter().getFilter().getName(), JFormalParameter.EMPTY, body); joiner_code.setWorkMethod(joinerWork); joiner_code.addMethod(joinerWork); }