C-DVM - detailed design (beginning)

C-DVM compiler. Detailed design (continuation)
* 22 June 2000 *


3 Compilation of C-DVM constructs

The parser builds an internal representation of a program. The unparser restores an external representation of a tree. Compilation itself is performed by numerous semantic functions. The main semantic function is the function ISWF. It is invoked by the parser twice for a node. Specific semantic actions depend on the node code (i.e. the code of the syntactic rule.) The first (downward) invocation is performed, when the parser attempts to apply some syntactic rule, i.e. before syntactic construct is parsed. In the main that is context verification. (Note that before a statement or a declaration parsing DVM-directive, preceding it, has been already parsed. In such case the function Allowed is invoked to verify the directive, statement and context compatibility.) Error message is issued if:

Besides context verification the following actions may be performed:

The second (and the last -- upward) invocation is performed when (and if) the rule is successfully matched. At that time a corresponding semantic function is invoked, which checks parsed construct validity, and builds necessary output subtree. This is described below for every C-DVM construct.

3.1 Data distribution

3.1.1 DISTRIBUTE directive

Context and syntax.

    DVM( ["*"] DISTRIBUTE [ format...] [ ONTO target ]
            [ ; SHADOW-clause ] [ ; TEMPLATE-clause ] )
            C-declaration ;

Proposed compiler output.

    long array-id [ rank+1 ];

Note. Source declaration is substituted. All the other information from the declaration and directive should be used later in generating other constructions and recognizing of references to distributed data.

Implementation.

The function  wfDISTRIBUTE()  verifies only the distribution format. Other parts of the directive have been already processed. Compatibility with context and correctness of declaration will be verified later by the functions Allowed, ISWFdcltr and ISWFdecl. A reference to the declaration is stored in the declaration list of the current visibility scope by the function addDecl.

The function  crHandler(dd,decl)  changes the type and declarator of array by ones of RTL's array handler.

3.1.2 GENBLOCK distribution format

Context and syntax.

    DVM(DISTRIBUTE ... "[" GENBLOCK( int-array ) "]"... )
    DVM(REDISTRIBUTE ... "[" GENBLOCK( int-array ) "]"... )

Proposed compiler output.

    DVM_GENBLOCK(am,ps,k,gbs);

Note. The macro is generated not at the point of DISTRIBUTE directive, but in a sequence of (explicit or implicit) array creation.

Implementation.

The function  wfGENBLOCK()  verifies the parameter of GENBLOCK distribution format and issues a message if

Required subtrees are built by the function  mk_genblock. It uses the function GENaxis(N) to create a comma-list of addresses of GENBLOCK arrays.

3.1.3 ONTO clause

Context and syntax.

    DVM(DISTRIBUTE ... ONTO target ... )

Proposed compiler output.

    DVM_ONTO(ps,k,ls,hs)

Note. The macro is generated not at the point of DISTRIBUTE directive, but in a sequence of (explicit or implicit) array creation. It creates a processors subsystem which will be used instead of the current one (default).

Implementation.

The function  wfONTO  verifies an ONTO-target and issues a message if

Required subtrees are built and kept as attribute "ONTO" for later use by the function  crONTO.

3.1.4 REDISTRIBUTE directive

Context and syntax.

    DVM(REDISTRIBUTE array format... [ NEW ] ) ;

Proposed compiler output.

    DVM_REDISTRIBUTE(amv,ps,k,axs,new);

Note. The executable directive is converted to the statement.

Implementation.

The function  wfREDISTRIBUTE  verifies an array and issues a message if

Required subtrees are built by the function  mk_alloc2, if distribution format was not specified in array declaration. The function  wfREDISTRIBUTE  uses also subtrees, built for ONTO and GENBLOCK.

3.1.5 ALIGN directive

Context and syntax.

    DVM(["*"] ALIGN [ "["dummy-var"]"... ]
            WITH base "["align-expr"]"...
            [ ; SHADOW-clause ] )
            C-declaration ;

Proposed compiler output.

    long array-id [ rank+1 ];

Note. Source declaration is substituted. All the other information from the declaration and directive should be used later in generating of other constructions and recognizing of references to distributed data.

Implementation.

The function  wfDVMind  verifies dummy-var list and issues a message if duplicated variables found. The function  wfDVMbind  verifies align-expr list and issues a message if

The function  wfDVMbase  verifies base and issues a message if

Compatibility with context and correctness of the declaration will be verified later by the functions Allowed, ISWFdcltr and ISWFdecl. A reference to the declaration is stored in the declaration list of the current visibility scope by the function addDecl.

The function  crHandler(dd,decl)  changes the type and declarator of array by ones of RTL's array handler.

3.1.6 REALIGN directive

Context and syntax.

    DVM( REALIGN array "["dummy-var"]"...
            WITH base "["align-expr"]"... ) ;

Proposed compiler output.

    DVM_REALIGN(arr,base,k,i,a,b,new);

Note. The executable directive is converted to the statement.

Implementation.

The function  wfREALIGN  verifies an array and issues a message if

Other parts of the directive are verified as for ALIGN directive.

Required subtrees are built by the function  wfREALIGN.

3.1.7 TEMPLATE clause

Context and syntax.

    DVM(DISTRIBUTE ... ; TEMPLATE [ "["size"]"... ] )
            void * template-id ;

Proposed compiler output.

    AMViewRef template-id;

Note.  Source declaration is substituted. Distribution formats will be used in the template creation. If size is specified the creation will be implicit.

Implementation.

The function  ISWFdcltr  verifies (besides all) that the template-id is declared as void *, and issues a message otherwise. The function  wfTEMPLATE  verifies a TEMPLATE subdirective parameter and issues a message if ranks mismatch.

The function  crRef(N,type)  changes the type "void*" by the RTL type "AMViewRef".

3.1.8 CREATE_TEMPLATE directive

Context and syntax.

    DVM(CREATE_TEMPLATE template-id "["size"]"... ) ;

Proposed compiler output.

    DVM_CREATE_TEMPLATE(am,t,r,di);
    DVM_DISTRIBUTE(amv,ps,k,axs);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLX_CRTEMP  verifies the directive and issues a message if

Required subtrees are built by the function  mk_templ(amv,dims,dir).

3.2 Distribution of computations (loops and tasks)

3.2.1 PARALLEL directive

Context and syntax.

    DVM ( PARALLEL "["loop-var"]"...
        ON base "["align_expr"]"...
        [ ; sub-directives]...)
        loop-nest

Proposed compiler output.

    {
        [ dvm_create_rg ]
    DVM_PARALLEL(n,r);
        [ other sub-directives... ]
    DVM_DO_ON((n,r,vs,ls,hs,ss,base,rb,is,as,bs);
        [ dvm_reduction or dvm_reduction20 ]
    {
    DVM_DOPL(n)
    loop-headers DVM_FOR...
    {
        loop-body
    }
    }
        [ end_reduction ]
    DVM_END_PARALLEL(n);
    }

Implementation.

The core of the directive are verified as for ALIGN directive. The function  wfDVMvar  verifies the loop-var list comparing it with loop headers and issues a message if it consists of not all loop variables or contains them in other order.

Required subtrees are built by the function  pLoop. It also inserts subtrees built for subdirectives into appropriate place in a paralle loop shell.

3.2.2 ACROSS clause

Context and syntax.

    DVM ( PARALLEL ... ; ACROSS array "["widths"]"... )

Proposed compiler output.

     dvm_parallel ... sub_directives
    DVM_ACROSS(loopid, (
        DVM_ACROSS_SH(a,k,ls,hs,corner)  // for each renewee
        ...
        ))
    { dvm_dopl
      loop-headers...
      loop-body
    }
    DVM_END_ACROSS()
    [ end_reduction ]
    dvm_end_parallel

Implementation.

The function  wfDVMshw()  verifies shadow edge width list and issues a message if:

The function  wfDVMshad()  verifies renewee and issues a message if CORNER is used for 1-D array (warning).

Required subtrees are built by the function  wfACROSS. Final tree building is performed by the function Ploop, after the loop is entirely parsed. It inserts early created subtree into appropriate point of a parallel loop shell.

3.2.3 PROCESSORS directive and NUMBER_OF_PROCESSORS() function

Context and syntax.

    DVM(PROCESSORS "["dim"]"...) void * proc_id ;

Proposed compiler output.

    PSRef proc_id;
    ...
    DVM_PROCESSORS(Iproc_id),r,dims);

Note.  Source declaration is substituted. The macro is generated not at the point of declaration, but in a sequence of implicit actions.

Implementation.

The function  ISWFdcltr  verifies (besides all) that the proc-id is declared as void *, and issues a message otherwise. The function  ISWFdclr  also builds a tree for the macro DVM_PROCESSORS and keeps it using function addIMloc in temporary local or global list. Statements will be inserted in appropriate place by functions genIMglob or genIMloc.

The function  crRef(N,type)  changes the type "void*" by the RTL type "PSRef".

3.2.4 TASK directive

Context and syntax.

    DVM(TASK) void * task-id "["size"]"

Proposed compiler output.

    AMViewRef AMV_task-id;
    PSRef  task-id [ size ]={0};
    ...
    DVM_TASK(task-id,n);

Note.  Source declaration is substituted. The macro is generated not at the point of declaration, but in a sequence of implicit actions.

Implementation.

The function  ISWFdcltr  verifies (besides all) that the task-id is declared as void *, and issues a message otherwise. The function  ISWFdclr  also builds a tree for the macro DVM_TASK and keeps it using function addIMloc in temporary local or global list. Statements will be inserted in appropriate place by functions genIMglob or genIMloc.

The function  crRef(N,type)  changes the type "void*" by the RTL type "PSRef" and creates a declaration of AM-representation variable AMV_.... The function  crAMVdcltrs(N)  creates a declarator for it.

3.2.5 MAP directive

Context and syntax.

    DVM(MAP task-id"["task_ind"]" ONTO proc-section );

Proposed compiler output.

    DVM_MAP(task,ind, [ DVM_ONTO(ps,k,ls,hs) ]) ;

Note.  The executable directive is converted to the statement.

Implementation.

Required subtrees are built by the function  wfMAP, using the tree built for the ONTO clause.

3.2.6 TASK_REGION directive

Context and syntax.

    DVM(TASK_REGION task-id)
    {
        ON-block... |  ON-loop
    }

Proposed compiler output.

    {DVM_TASKREGION(no,task);
    ...
    }

Implementation.

The function  wfTASKREGION  verifies compound statement. All their statements must be an ON-blocks or it should consist of single statement - ON-loop. Then the function builds required subtree including statements for a REDUCTION sub-directive, and for the debugger (-dx option).

3.2.7 ON-block construct

Context and syntax.

    DVM(ON task-id "["task-ind"]")
    {   C-statements   }

Proposed compiler output.

    if(DVM_RUN(task,ind))
        { statements
        DVM_STOP();
        }

Implementation.

The function  wfLXItask  verifies task-id and issues a message if it is not defined or not specified as a TASK.

Required subtrees are built by the function  mkRUNAM().

3.2.8 ON-loop construct

Context and syntax.

    DVM(PARALLEL "["var"]" ON task-id "["var"]")
    DO(var, ..., ..., ...)
        {   C-statements   }

Proposed compiler output.

    for(var=0; ...)
    if(DVM_RUN(task,var))
        { statements
        DVM_STOP();
        }

Implementation.

The function  wfLXItask  verifies task-id and issues a message if it is not defined or not specified as a TASK.

Required subtrees are built by the function  mkRUNAM().

3.3 Shadow edges

3.3.1 SHADOW clause

Context and syntax.

    DVM( DISTRIBUTE | ALIGN ...
             ; SHADOW "["widths"]"... )

Note.  Nothing is generated at this point. Compiler keeps provided widths as the maximal ones. They will be used at array creation.

Implementation.

The function  wfSHADOW  verifies the width list and issues a message if ranks mismatch.

3.3.2 SHADOW_RENEW clause

Context and syntax.

    DVM(PARALLEL ... ; SHADOW_RENEW renewee... ... )
    renewee ::=  array [ "["widhs"]"... ] [ CORNER ]

Proposed compiler output.

    DVM_SHADOW_RENEW(loop-number,
        (DVM_SHADOWS(a,k,ls,hs,corner), // for each renewee
        ...
        ))

Note.  It is shorthand for the sequence "CREATE_SHADOW_GROUP; SHADOW_START; SHADOW_WAIT;" with temporary shadow edge group, performed before the loop.

Implementation.

The function  wfDVMshw()  verifies shadow edge width list and issues a message if:

The function  wfDVMshad()  verifies renewee and issues a message if CORNER is used for 1-D array (warning).

Required subtrees are built by the function  wfSHRENEW. Final tree building is performed by the function Ploop, after the loop is entirely parsed. It inserts early created subtree into appropriate point of a parallel loop shell.

3.3.3 SHADOW_GROUP directive

Context and syntax.

    DVM(SHADOW_GROUP) void * sh-group-id;

Proposed compiler output.

    ShadowGroupRef sh-group-id;

Note.  Source declaration is substituted.

Implementation.

The function  ISWFdcltr  verifies (besides all) that sh-group-id is declared as void *, and issues a message otherwise.

The function  crRef(N,type)  changes the type "void*" by the RTL type "ShadowGroupRef".

3.3.4 CREATE_SHADOW_GROUP directive

Context and syntax.

    DVM(CREATE_SHADOW_GROUP sh-group-id : renewee...);

Proposed compiler output.

    DVM_CREATE_SHADOW_GROUP( sh-group-id,
        (DVM_SHADOWS(a,k,ls,hs,corner), // for each renewee
        ...
        ))

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfDVMshw()  verifies shadow edge width list and issues a message if:

The function  wfDVMshad()  verifies renewee and issues a message if CORNER is used for 1-D array (warning).

Required subtrees are built by the function  wfLX_CRSG. It uses the following functions:

3.3.5 SHADOW_START directive

Context and syntax.

    DVM(SHADOW_START sh-group-id);

Proposed compiler output.

    DVM_SHADOW_START(sg);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIsg  verifies sh-group-id and issues a message if it is not defined or not specified as SHADOW_GROUP.

Required subtrees are built by the function  wfSHSTART().

3.3.6 SHADOW_START clause

Context and syntax.

    DVM(PARALLEL ... ; SHADOW_START sh-group-id ... ) ...

Proposed compiler output.

    DVM_PAR_SHADOW_START(n,sg); // in loop header

Implementation.

The function  wfLXIsg  verifies sh-group-id and issues a message if it is not defined or not specified as SHADOW_GROUP.

Required subtrees are built by the function  wfSHSTART(). Final tree building is performed by the function Ploop, after the loop is entirely parsed. It inserts early created subtree into appropriate point of a parallel loop shell.

3.3.7 SHADOW_WAIT directive

Context and syntax.

    DVM(SHADOW_WAIT sh-group-id);

Proposed compiler output.

    DVM_SHADOW_WAIT(sg);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIsg  verifies sh-group-id and issues a message if it is not defined or not specified as SHADOW_GROUP.

Required subtrees are built by the function  wfSHWAIT().

3.3.8 SHADOW_WAIT clause

Context and syntax.

    DVM(PARALLEL ... ; SHADOW_WAIT sh-group-id ...) ...

Proposed compiler output.

    DVM_PAR_SHADOW_WAIT(n,sg); // in loop header

Implementation.

The function  wfLXIsg  verifies sh-group-id and issues a message if it is not defined or not specified as SHADOW_GROUP.

Required subtrees are built by the function  wfSHWAIT(). Final tree building is performed by the function Ploop, after the loop is entirely parsed. It inserts early created subtree into appropriate point of a parallel loop shell.

3.4 Remote access

3.4.1 REMOTE_ACCESS directive and clause

Context and syntax.

    DVM(REMOTE_ACCESS ra-reference...)
        C-statement
    DVM(PARALLEL ... ;
        REMOTE_ACCESS [ ra-group : ] ra-reference...
        ...) ...
    ra-reference ::= array [ "["[expr]"]"... ]

Proposed compiler output.

    DVM_BLOCK_BEG();
    DVM_REMOTE20(arr,buf,k,as,bs);
    statements using remote references
    DVM_BLOCK_END();

Implementation.

The function  wfREMOTE()  verifies index expressions and issues a message if they are incorrect. It also keeps information necessary for remote reference recognition and convertion.

Required subtrees are built by the function  mk_remote(dir,oper). It uses the functions:

3.4.2 REMOTE_GROUP directive

Context and syntax.

    DVM(REMOTE_GROUP) void * ra-group-id;

Proposed compiler output.

    RegularAccessGroupRef ra-group-id;
    long  RMG_ra-group-id;

Note.  Source declaration is substituted. The PREFETCH and RESET operations require a flag variable to control buffer renewing operations.

Implementation.

The function  ISWFdcltr  verifies (besides all) that ra-group-id is declared as void *, and issues a message otherwise.

The function  crRef(N,type)  changes the type "void*" by the RTL type "RegularAccessGroupRef" and creates a declaration of flag variable "RMG_...". The function  crRMGdcltrs(N)  generates a declarator for it.

3.4.3 PREFETCH directive

Context and syntax.

    DVM(PREFETCH ra-group-id );

Proposed compiler output.

    DVM_PREFETCH(rg);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIag  verifies ra-group-id and issues a message if it is not defined or not specified as REMORE_GROUP.

Required subtrees are built by the function  wfPREFETCH().

3.4.4 RESET directive

Context and syntax.

    DVM(RESET ra-group-id );

Proposed compiler output.

    DVM_RESET(rg);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIag  verifies ra-group-id and issues a message if it is not defined or not specified as REMORE_GROUP.

Required subtrees are built by the function  wfRESET().

3.4.5 Remote references

Remote references are substituted by references to remote access buffers.

Implementation.

3.5 Reduction operations

3.5.1 REDUCTION_GROUP directive

Context and syntax.

    DVM(REDUCTION_GROUP) void * red-group-id;

Proposed compiler output.

    RedGroupRef red-group-id;

Note.  Source declaration is substituted.

Implementation.

The function  ISWFdcltr  verifies (besides all) that the red-group-id is declared as void *, and issues a message otherwise.

The function  crRef(N,type)  changes the type "void*" by the RTL type "RedGroupGroupRef".

3.5.2 REDUCTION clause

Context and syntax.

    DVM( PARALLEL | TASK_REGION ... ;
        REDUCTION [ red-group-id : ] red-operation...
        ... ) ...

Proposed compiler output.

    DVM_CREATE_RG(rg, (
        DVM_RVAL(...) | DVM_RLOC(...)  // for each operation
        ...
        ));
        loop creation and mapping
    DVM_REDUCTION20(loopid,rg);       // insert to the group
        loop headers and body
    [ DVM_END_REDUCTION(); ]          // synchronous reduction

Implementation.

Required subtrees are built by the function  wfREDUCTION, namely a list of DVM_RVAR or DVM_RLOC macros for all reduction operations in the directive is created. Final tree building is performed by the function Ploop, after the loop has been entirely parsed. It inserts early created subtree into appropriate point of a parallel loop shell, depending on whether reduction is synchronous or asynchronous.

3.5.3 Reduction variables and operations

Context and syntax.

    DVM(...; REDUCTION ... MAX(red-var) ... )
    DVM(...; REDUCTION ... MIN(red-var) ... )
    DVM(...; REDUCTION ... SUM(red-var) ... )
    DVM(...; REDUCTION ... PROD(red-var) ... )
    DVM(...; REDUCTION ... AND(red-var) ... )
    DVM(...; REDUCTION ... OR(red-var) ... )
    DVM(...; REDUCTION ... MAXLOC(red-var,loc-var) ... )
    DVM(...; REDUCTION ... MINLOC(red-var,loc-var) ... )

Proposed compiler output.

    DVM_RVAR(rf_MAX,var,t,l)
    DVM_RVAR(rf_MIN,var,t,l)
    DVM_RVAR(rf_SUM,var,t,l)
    DVM_RVAR(rf_PROD,var,t,l)
    DVM_RVAR(rf_AND,var,t,l)
    DVM_RVAR(rf_OR,var,t,l)
    DVM_RLOC(rf_MAX,var,t,l,loc-var)
    DVM_RLOC(rf_MIN,var,t,l,loc-var)

Note.  The parameter t is a code of the variable type (rt_INT, rt_LONG, rt_FLOAT, rt_DOUBLE). Parameter l is the number of elements in red-var (if it is an array) or 1.

Implementation.

The function  cRG0()  creates macro DVM_RVAR or DVM_RLOC for one reduction operation of the list. Its first parameter is RTL's name of the operation which is generated by the function rts_name(t). The function  cRG(Ad,N)  creates a list of the macros for all operations in a directive.

3.5.4 REDUCTION_START directive

Context and syntax.

    DVM(REDUCTION_START red-group-id);

Proposed compiler output.

    DVM_REDUCTION_START(red-group-id);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIrg  verifies red-group-id and issues a message if it is not defined or not specified as REDUCTION_GROUP.

Required subtrees are built by the function  wfRSTART().

3.5.5 REDUCTION_WAIT directive

Context and syntax.

    DVM(REDUCTION_WAIT red-group-id);

Proposed compiler output.

    DVM_REDUCTION_WAIT(red-group-id);

Note.  The executable directive is converted to the statement.

Implementation.

The function  wfLXIrg  verifies red-group-id and issues a message if it is not defined or not specified as REDUCTION_GROUP.

Required subtrees are built by the function  wfRWAIT().

3.6 Implicit constructions

3.6.1 Creation and deletion of distributed arrays

Context and syntax.

    array = malloc(dim1 *...* dimr * elem-size);
    free( array );

Proposed compiler output.  It includes all or part of the following statements depending on array declaration.

  [ DVM_CREATE_TEMPLATE(am,t,r,di); // implicit template   ]
  [ DVM_ONTO(ps,k,ls,hs);           // target system       ]
  [ DVM_DISTRIBUTE(amv,ps,k,axs);   // distribute template ]
  [ DVM_GENBLOCK(am,ps,k,gbs);      // GENBLOCK parameters ]
    DVM_MALLOC(arr,r,len,dim,lw,hw,redis) // initialize array handler
  [ DVM_ALIGN(arr,base,k,i,a,b)     // align with template ]

Implementation.

The function  ISWF  verifies the parameter of malloc and the left side of assignement and issues a message if:

Required subtrees are built by the function  mk_alloc(lhs,parm). It uses the functions mk_templ and mk_genblock, and uses a subtree built for the ONTO clause of DISTRIBUTE directive.

3.6.2 Static distributed arrays

Context and syntax.

    DVM(DISTRIBUTE | ALIGN...)
        element-type array-id "["const-dim"]"...;

Proposed compiler output.  Usual array creation sequence as for malloc.

Note.  For global declarations implicit malloc is inserted at the beginning of the main function. For local declarations it is inserted before the first statement of the block.

Implementation.

The function  ISWFdcltr  (besides all) determines whether a declarator is "static" one. If so it builds subtree for implicit allocation and keeps it in temporary local or global list using function addIMloc and issues a message if insertion point has already been passed. Statements will be inserted in appropriate place by functions genIMglob or genIMloc.

3.6.3 References to distributed data

Context and syntax.  Ordinary references to array elements array[ind1]...[indr] with distributed array. Special form of references as array(ind1,...,indr) macros is allowed to simulate dynamic arrays.

Proposed compiler output.

    DAElm<r>(type,array-id,ind1,...indr)

Note.  These are RTL macros.

Implementation.

The function  ISWFaccess(N)  verifies a reference to distributed data and issues a message if

It uses funstions:

If it is correct reference to distributed array elelment the same function builds RTL's form of the reference. The function  mk_datype(N,type)  creates the first parameter of macro DAElmx - the type as identifier. The function  mk_daind(N,type,lbk)  converts the reference to distributed array into other parameters of the macro.

3.6.4 Own computations

Context and syntax.

        lhs=rhs; // assignement

Proposed compiler output.

    if(DVM_ISLOCAL(lhs)) {
        lhs = rhs ; }
    DVM_ENDLOCAL();

Note.  Own computation statement is assignement to a distributed array in a non distributed branch of program. It should be guarded by the test of locality.

Implementation.

Required subtrees are built by the function  mk_local(N), when it is necessary (i.e. if a reference in the left side of the assignement may be non-local). If so it issues a weak warning (use the -w command line option to see it). The function  mk_ind_list(N)  is used to create a comma-list of index expressions.

3.6.5 Initialization and completion of parallel execution

Context and syntax.

    int main( int argc, char ** arg)
    {
        declarations...
        first-statement
        ...
        [ exit(rc); ]
        ...
        return rc;
    }

Proposed compiler output.

    int main( int argn, char ** args)
    {
        declarations...
        DVM_INIT(0,argn,args); // initialization of RTL
        [ implicit static array creation ]
        [ tracing of initialized variables ]
        [ other implicit actions ]
        first-statement
        ...
        [ DVM_EXIT(rc); ]  // exit through RTL
        ...
        DVM_RETURN(rc);    // exit through RTL
    }

Note.  For correct generation the main function must get a command-line parameters (which will be passed to RTL) and must have return or exit statement.

Implementation.

The function  isMain(N)  determines whether the current declaration is a declaration of the function main. The function  Arg(N)  extracts arguments of the main and issues a message if they are omitted.

Required subtrees are built by the function  wfRETURN() and also by the function ISWF just before the function genIMglob() invocation.

3.6.6 Input-output functions

Compilation of input-output functions is reduced to renaming of iofun to its RTL analog dvm_iofun. The only exception is fread() and fwrite() functions, when they are applied to a distributed array. In this case the array is read or written as a whole, i.e. other parameters of the function are ignored.

Implementation.

Identifier substitution is also performed by the function pSUBST at the transformation step. It uses a renaming list of pairs of identifiers. The list is built in the linked memory by the function RenInit() at the initialization step. The function  RenPair(a,b)  stores one pair to the list.

The renaming list contains the following identifies:

        C-name -------- RTL-name
        exit            DVM_EXIT
        FILE            DVMFILE
        clearerr        dvm_clearerr
        fclose          dvm_fclose
        feof            dvm_feof
        ferror          dvm_ferror
        fflush          dvm_fflush
        fgetc           dvm_fgetc
        fgetpos         dvm_fgetpos
        fgets           dvm_fgets
        fopen           dvm_fopen
        fprintf         dvm_void_fprintf
        fputc           dvm_fputc
        fputs           dvm_fputs
        fread           dvm_fread
        freopen         dvm_freopen
        fscanf          dvm_fscanf
        fseek           dvm_fseek
        fsetpos         dvm_fsetpos
        ftell           dvm_ftell
        fwrite          dvm_fwrite
        getc            dvm_getc
        getchar         dvm_getchar
        gets            dvm_gets
        printf          dvm_void_printf
        putc            dvm_putc
        putchar         dvm_putchar
        puts            dvm_puts
        rewind          dvm_rewind
        scanf           dvm_scanf
        setbuf          dvm_setbuf
        setvbuf         dvm_setvbuf
        tmpfile         dvm_tmpfile
        ungetc          dvm_ungetc
        vfprintf        dvm_void_vfprintf
        void_vprintf    dvm_void_vprintf
        vprintf         dvm_vprintf
        fgetchar        dvm_fgetchar
        fputchar        dvm_fputchar
        vfscanf         dvm_vfscanf
        vscanf          dvm_vscanf
        STDIN           DVMSTDIN
        STDOUT          DVMSTDOUT
        STDERR          DVMSTDERR
        STDAUX          DVMSTDAUX
        STDPRN          DVMSTDPRN
        remove          dvm_remove
        rename          dvm_rename
        tmpnam          dvm_tmpnam
        access          dvm_access
        unlink          dvm_unlink
        stat            dvm_stat

 

3.7 Debugging extensions

3.7.1 Performance analyzer. Loops

Context and syntax.

    [ DVM(PARALLEL... ) ]
        DO(var,first,last,step)    // or
        FOR(var,times)
            loop-body

Proposed compiler output.

    BPLOOP(n)  // for parallel loop or
    BSLOOP(n)  // for sequential loop
        code for loop
    ELOOP(n)

Note.  The argument n is a serial number of the loop used to identify paired commands. The set of loops the macros are generated for depends on a command-line options (-e1...-e4).

Implementation.

Required subtrees are built by the function  Ploop() depending on command line options.

3.7.2 Performance analyzer. INTERVAL directive

Context and syntax.

    DVM(INTERVAL  [ int-expr ] )
    { C-statements }

Proposed compiler output.

    DVM_BINTER(n,v)
      { code for statements }
    DVM_EINTER(n)

Note.  The argument n is a serial number of the loop used to identify paired commands. If int-expr does not present, the argument v has some standard value.

Implementation.

Required subtrees are built by the function  interval(N) depending on command line options.

3.7.3 Debugger. Data tracing

Context and syntax.  Any reference to ordinary or distributed var in C-statements or variable initialization.

Proposed compiler output.

    DVM_STVA(type,rt,var,base,rhs)  // lh-side of assignement
    DVM_LDV(type,rt,var,base)  // for read access
    DVM_STV(type,rt,var,base)  // to register initialization

Note.  The set of references the macros are generated for depends on a command-line options (-d1...-d4).

Implementation.

This is the last step of the function ISWFaccess, which invokes the function cDTscal or cDTarr, to rebuild an RTL reference subtree. One more step will be done later by the function stv2stva for an assignement expression; namely, the macro will be converted to DVM_STVA macro.

3.7.4 Debugger. Computation tracing

Context and syntax.  Any loop or task region construct.

Proposed compiler output.

        parallel loop creation
    DVM_PLOOP(n,r,ls,hs,ss)   // or DVM_SLOOP(n)
        loop-headers
    DVM_ITER(r,vars)
        code for loop body
    DVM_ENDLOOP(n)

for loop or

    DVM_BTASK(n)     // in TASK_REGION header
        ...
    DVM_ETASK(n)
        ON-block or ON-loop body
        ...
    DVM_NTASK(ind)   // end of TASK_REGION construct

for task region.

Implementation.

Required subtrees are built by the function  Ploop() for a parallel loop and by the function wfTASKREGION for a TASK_REGION block depending on command line options.

3.7.5 Sequential code

Generation of sequential code is set by the command-line option -s. All DVM-directives ignored except the following ones:

Note that preprocessor statements #define should be kept in place unlike the parallel code from which they moved to the beginning if the file.

Implementation.

The command line option -s is stored as a flag OPTs which controls generation of all constructs. At presence of this option almost all macros (with above mentioned exceptions) are generated as empty statements, but all declarations remain unchanged.