compiler/resolution/lowerIterators.cpp
/// \param call A for loop block primitive.
\param call A for loop block primitive.
\ param call A for loop block primitive .
static void
expandRecursiveIteratorInline(ForLoop* forLoop)
{
  SET_LINENO(forLoop);
  FnSymbol*  parent            = toFnSymbol(forLoop->parentSymbol);
  FnSymbol*  loopBodyFn        = new FnSymbol(astr("_rec_iter_loop_", parent->name));
  Symbol*    index             = forLoop->indexGet()->symbol();
  ArgSymbol* indexArg          = new ArgSymbol(blankIntentForType(index->type), "_index", index->type);
  FnSymbol*  loopBodyFnWrapper = new FnSymbol(astr("_rec_iter_loop_wrapper_", parent->name));
  loopBodyFn->insertFormalAtTail(indexArg);
  forLoop->insertBefore(new DefExpr(loopBodyFn));
  parent->defPoint->insertBefore(new DefExpr(loopBodyFnWrapper));
  ftableVec.push_back(loopBodyFnWrapper);
  ftableMap[loopBodyFnWrapper] = ftableVec.size()-1;
   insert a call to the iterator function (using iterator as a
   placeholder); build a call to loopBodyFn which will be
   removed later and its arguments passed to the iteratorFn (we
   build this to capture the actual arguments that should be
   passed to it when this function is flattened)
  Symbol*    ic             = forLoop->iteratorGet()->symbol();
  FnSymbol*  iterator       = getTheIteratorFn(ic);
  CallExpr*  iteratorFnCall = new CallExpr(iterator, ic, new_IntSymbol(ftableMap[loopBodyFnWrapper]));
   replace function in iteratorFnCall with iterator function once that is created
  CallExpr*  loopBodyFnCall = new CallExpr(loopBodyFn, gVoid);
   use and remove loopBodyFnCall later
   We expect this call to cause the loop body function to be converted like a
   "normal" iterator function body.
  forLoop->insertBefore(loopBodyFnCall);
  forLoop->insertBefore(iteratorFnCall);
   Copy the body of forLoop into the (new) loop body function
   and remove forLoop.
  loopBodyFn->insertAtTail(forLoop->copyBody());
  forLoop->remove();
   Now populate the loop body function.
   Load the index arg.
  loopBodyFn->insertAtHead(new CallExpr(PRIM_MOVE, index, indexArg));
  loopBodyFn->insertAtHead(index->defPoint->remove());
   Return nothing (void).
  loopBodyFn->insertAtTail(new CallExpr(PRIM_RETURN, gVoid));
  loopBodyFn->retType = dtVoid;
   Move the loop body function out to the module level.
  flattenNestedFunction(loopBodyFn);
  FnSymbol* iteratorFn = iteratorFnMap.get(iterator);
  if (!iteratorFn) {
    iteratorFn = createIteratorFn(iterator,
                                  iteratorFnCall,
                                  index,
                                  loopBodyFnCall,
                                  loopBodyFnWrapper,
                                  ic);
    iteratorFnMap.put(iterator, iteratorFn);
  } else {
    iteratorFnCall->baseExpr->replace(new SymExpr(iteratorFn));
    bundleLoopBodyFnArgsForIteratorFnCall(iteratorFnCall, loopBodyFnCall, loopBodyFnWrapper);
    Symbol* argBundleTmp = newTemp("argBundleTmp", iteratorFn->getFormal(3)->type);
    iteratorFnCall->insertBefore(new DefExpr(argBundleTmp));
    iteratorFnCall->insertBefore(new CallExpr(PRIM_MOVE,
                                              argBundleTmp,
                                              new CallExpr(PRIM_CAST,
                                                           argBundleTmp->type->symbol,
                                                           iteratorFnCall->get(3)->remove())));
    iteratorFnCall->insertAtTail(argBundleTmp);
  }
}
static void expandRecursiveIteratorInline ( ForLoop * forLoop ) { SET_LINENO ( forLoop ) ; FnSymbol * parent = toFnSymbol ( forLoop -> parentSymbol ) ; FnSymbol * loopBodyFn = new FnSymbol ( astr ( " " , parent -> name ) ) ; Symbol * index = forLoop -> indexGet ( ) -> symbol ( ) ; ArgSymbol * indexArg = new ArgSymbol ( blankIntentForType ( index -> type ) , " " , index -> type ) ; FnSymbol * loopBodyFnWrapper = new FnSymbol ( astr ( " " , parent -> name ) ) ; loopBodyFn -> insertFormalAtTail ( indexArg ) ; forLoop -> insertBefore ( new DefExpr ( loopBodyFn ) ) ; parent -> defPoint -> insertBefore ( new DefExpr ( loopBodyFnWrapper ) ) ; ftableVec . push_back ( loopBodyFnWrapper ) ; ftableMap [ loopBodyFnWrapper ] = ftableVec . size ( ) - 1 ; Symbol * ic = forLoop -> iteratorGet ( ) -> symbol ( ) ; FnSymbol * iterator = getTheIteratorFn ( ic ) ; CallExpr * iteratorFnCall = new CallExpr ( iterator , ic , new_IntSymbol ( ftableMap [ loopBodyFnWrapper ] ) ) ; CallExpr * loopBodyFnCall = new CallExpr ( loopBodyFn , gVoid ) ; forLoop -> insertBefore ( loopBodyFnCall ) ; forLoop -> insertBefore ( iteratorFnCall ) ; loopBodyFn -> insertAtTail ( forLoop -> copyBody ( ) ) ; forLoop -> remove ( ) ; loopBodyFn -> insertAtHead ( new CallExpr ( PRIM_MOVE , index , indexArg ) ) ; loopBodyFn -> insertAtHead ( index -> defPoint -> remove ( ) ) ; loopBodyFn -> insertAtTail ( new CallExpr ( PRIM_RETURN , gVoid ) ) ; loopBodyFn -> retType = dtVoid ; flattenNestedFunction ( loopBodyFn ) ; FnSymbol * iteratorFn = iteratorFnMap . get ( iterator ) ; if ( ! iteratorFn ) { iteratorFn = createIteratorFn ( iterator , iteratorFnCall , index , loopBodyFnCall , loopBodyFnWrapper , ic ) ; iteratorFnMap . put ( iterator , iteratorFn ) ; } else { iteratorFnCall -> baseExpr -> replace ( new SymExpr ( iteratorFn ) ) ; bundleLoopBodyFnArgsForIteratorFnCall ( iteratorFnCall , loopBodyFnCall , loopBodyFnWrapper ) ; Symbol * argBundleTmp = newTemp ( " " , iteratorFn -> getFormal ( 3 ) -> type ) ; iteratorFnCall -> insertBefore ( new DefExpr ( argBundleTmp ) ) ; iteratorFnCall -> insertBefore ( new CallExpr ( PRIM_MOVE , argBundleTmp , new CallExpr ( PRIM_CAST , argBundleTmp -> type -> symbol , iteratorFnCall -> get ( 3 ) -> remove ( ) ) ) ) ; iteratorFnCall -> insertAtTail ( argBundleTmp ) ; } }
\param call A for loop block primitive.
\ param call A for loop block primitive .
// create a nested function for the loop body (call->parentExpr), and then transform // the iterator into a function that takes this nested function as an argument // The index is passed to the loop body function as its first argument. // The recursive iterator loop wrapper is ... . // // insert a call to the iterator function (using iterator as a // placeholder); build a call to loopBodyFn which will be // removed later and its arguments passed to the iteratorFn (we // build this to capture the actual arguments that should be // passed to it when this function is flattened) // // replace function in iteratorFnCall with iterator function once that is created // use and remove loopBodyFnCall later // We expect this call to cause the loop body function to be converted like a // "normal" iterator function body. // Copy the body of forLoop into the (new) loop body function // and remove forLoop. // Now populate the loop body function. // Load the index arg. // Return nothing (void). // Move the loop body function out to the module level.