Skip to content

Commit cbadb27

Browse files
authored
Merge pull request #823 from ThePortlandGroup/nv_stage
Pull 2019-11-07T08-16 Recent NVIDIA Changes
2 parents eab3991 + 9dd4ed0 commit cbadb27

File tree

34 files changed

+597
-110
lines changed

34 files changed

+597
-110
lines changed

runtime/flang/rdst.c

Lines changed: 169 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1995-2018, NVIDIA CORPORATION. All rights reserved.
2+
* Copyright (c) 1995-2019, NVIDIA CORPORATION. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,12 +24,20 @@
2424
#include "stdioInterf.h"
2525
#include "fioMacros.h"
2626

27+
extern char *__fstr2cstr();
28+
2729
void
2830
ENTFTN(TEMPLATE, template)(F90_Desc *dd, __INT_T *p_rank,
2931
__INT_T *p_flags, ...);
3032

33+
#include <string.h>
3134
#include "fort_vars.h"
32-
35+
#if defined(TARGET_LINUX_X8664) || defined (TARGET_LINUX_POWER) || defined(TARGET_OSX_X8664)
36+
#include <unistd.h>
37+
#include <sys/wait.h>
38+
#endif
39+
static void store_int_kind(void *, __INT_T *, int);
40+
static void ftn_msgcpy(char*, const char*, int);
3341
static char *intents[] = {"INOUT", "IN", "OUT", "??"};
3442

3543
/** \brief Compare alignments and local storage sequences. Return true if all
@@ -2808,4 +2816,163 @@ ENTF90(CONTIGCHK, contigchk)(void *ptr, F90_Desc *pd, __INT_T lineno,
28082816
ENTF90(CONTIGERROR, contigerror)(ptr, pd, lineno, ptrnam, srcfil, flags);
28092817
}
28102818
}
2819+
2820+
/** \brief Execute a command line.
2821+
*
2822+
* \param command is the command to be executed.
2823+
* \param wait controls to execute command synchronously or asynchronously.
2824+
* \param exitstatus is the value of exit status.
2825+
* \param cmdstat shows the status of command execution.
2826+
* \param cmdmsg is the assigned explanatory message.
2827+
* \param exitstat_int_kind is the integer kind for the exitstat.
2828+
* \param cmdstat_int_kind is the integer kind for the cmdstat.
2829+
* \param DCLEN64(command) is generated by compiler which contains the length
2830+
* of the command string.
2831+
* \param DCLEN64(cmdmsg) is generated by compiler which contains the length
2832+
of the cmdmsg string.
2833+
*/
2834+
void
2835+
ENTF90(EXECCMDLINE, execcmdline)(DCHAR(command), __LOG_T *wait,
2836+
__INT_T *exitstatus,
2837+
__INT_T *cmdstat, DCHAR (cmdmsg),
2838+
__INT_T *exitstat_int_kind,
2839+
__INT_T *cmdstat_int_kind
2840+
DCLEN64(command) DCLEN64(cmdmsg)) {
2841+
char *cmd, *cmdmes;
2842+
int cmdmes_len, stat;
2843+
int cmdflag = 0;
2844+
enum CMD_ERR{NO_SUPPORT_ERR=-1, FORK_ERR=1, EXECL_ERR=2, SIGNAL_ERR=3};
28112845

2846+
cmd = __fstr2cstr(CADR(command), CLEN(command));
2847+
cmdmes = (char*) CADR(cmdmsg);
2848+
cmdmes_len = CLEN(cmdmsg);
2849+
2850+
if (cmdstat)
2851+
store_int_kind(cmdstat, cmdstat_int_kind, 0);
2852+
#if defined(TARGET_LINUX_X8664) || defined(TARGET_OSX_X8664) || defined (TARGET_LINUX_POWER)
2853+
pid_t pid, w;
2854+
int wstatus, ret;
2855+
2856+
/* If WAIT is present with the value false, and the processor supports
2857+
* asynchronous execution of the command, the command is executed
2858+
* asynchronously; otherwise it is executed synchronously.
2859+
*/
2860+
pid = fork();
2861+
if (pid < 0) {
2862+
if (cmdmes)
2863+
ftn_msgcpy(cmdmes, "Fork failed", cmdmsg_len);
2864+
if (cmdstat)
2865+
store_int_kind(cmdstat, cmdstat_int_kind, FORK_ERR);
2866+
} else if (pid == 0) {
2867+
ret = execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
2868+
exit(ret);
2869+
} else {
2870+
// either wait is not specified or wait is true, then synchronous mode
2871+
if ( !wait || *wait == -1) {
2872+
#if DEBUG
2873+
printf("either wait is not specified or Wait = .true.\n");
2874+
printf("Synchronous execution mode!\n");
2875+
#endif
2876+
/* code executed by parent, wait for children */
2877+
w = waitpid(pid, &wstatus, WUNTRACED | WCONTINUED);
2878+
if (w == -1)
2879+
cmdflag = EXECL_ERR;
2880+
2881+
if (WIFEXITED(wstatus)) {
2882+
stat = WEXITSTATUS(wstatus);
2883+
2884+
if (exitstatus)
2885+
store_int_kind(exitstatus, exitstat_int_kind, stat);
2886+
}
2887+
2888+
if (WIFSIGNALED(wstatus))
2889+
cmdflag = SIGNAL_ERR;
2890+
2891+
if (cmdstat && cmdflag > 0)
2892+
store_int_kind(cmdstat, cmdstat_int_kind, cmdflag);
2893+
2894+
if (cmdmes) {
2895+
switch (cmdflag) {
2896+
case EXECL_ERR:
2897+
ftn_msgcpy(cmdmes, "Excel failed", cmdmsg_len);
2898+
break;
2899+
case SIGNAL_ERR:
2900+
ftn_msgcpy(cmdmes, "Signal error", cmdmsg_len);
2901+
break;
2902+
}
2903+
}
2904+
2905+
/* If a condition occurs that would assign a nonzero value to CMDSTAT
2906+
but the CMDSTAT variable is not present, error termination is
2907+
initiated.
2908+
*/
2909+
if (!cmdstat && cmdflag > 0) {
2910+
fprintf(__io_stderr(), "ERROR STOP ");
2911+
exit(cmdflag);
2912+
}
2913+
2914+
#if DEBUG
2915+
if (WIFEXITED(wstatus)) {
2916+
printf("exited, status=%d\n", WEXITSTATUS(wstatus));
2917+
} else if (WIFSIGNALED(wstatus)) {
2918+
printf("killed by signal %d\n", WTERMSIG(wstatus));
2919+
} else if (WIFSTOPPED(wstatus)) {
2920+
printf("stopped by signal %d\n", WSTOPSIG(wstatus));
2921+
} else if (WIFCONTINUED(wstatus)) {
2922+
printf("continued\n");
2923+
}
2924+
#endif
2925+
} // end else
2926+
}
2927+
#else // defined(TARGET_WIN)
2928+
// Windows runtime work to be continued.
2929+
cmdflag = NO_SUPPORT_ERR;
2930+
if (cmdmes)
2931+
ftn_msgcpy(cmdmes, "No Windows support", cmdmsg_len);
2932+
if (cmdstat)
2933+
store_int_kind(cmdstat, cmdstat_int_kind, cmdflag);
2934+
else
2935+
__fort_abort("execute_command_line: not yet supported on Windows\n");
2936+
#endif
2937+
__cstr_free(cmd);
2938+
}
2939+
2940+
// TODO: Code restructure needed to reduce redundant codes.
2941+
/*
2942+
* helper function to store an int/logical value into a varying int/logical
2943+
*/
2944+
static void
2945+
store_int_kind(void *b, __INT_T *int_kind, int v)
2946+
{
2947+
switch (*int_kind) {
2948+
case 1:
2949+
*(__INT1_T *)b = (__INT1_T)v;
2950+
break;
2951+
case 2:
2952+
*(__INT2_T *)b = (__INT2_T)v;
2953+
break;
2954+
case 4:
2955+
*(__INT4_T *)b = (__INT4_T)v;
2956+
break;
2957+
case 8:
2958+
*(__INT8_T *)b = (__INT8_T)v;
2959+
break;
2960+
default:
2961+
__fort_abort("store_int_kind: unexpected int kind");
2962+
}
2963+
}
2964+
2965+
// TODO: Code restructure needed to reduce redundant codes.
2966+
/** \brief Copy msg string to statmsg and padding with blank space at the end.
2967+
*
2968+
* \param statmsg is the Fortran string we want to assign values.
2969+
* \param msg is the string contains error message.
2970+
* \param len is the length of statmsg.
2971+
*/
2972+
static void
2973+
ftn_msgcpy(char *statmsg, const char *msg, int len) {
2974+
int i;
2975+
for (i=0; i<len; ++i) {
2976+
statmsg[i] = *msg ? *msg++ : ' ';
2977+
}
2978+
}

tools/flang1/flang1exe/dtypeutl.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,20 @@ tk_match_arg(int formal_dt, int actual_dt, LOGICAL flag)
15171517
}
15181518
}
15191519
else if (!eq_dtype2(f_dt, a_dt, flag)) {
1520+
if (DTY(f_dt) == TY_PTR && DTY(a_dt) == TY_PTR &&
1521+
DTY(DTY(f_dt + 1)) == TY_PROC && DTY(DTY(a_dt + 1)) == TY_PROC) {
1522+
/* eq_dtype2 checks equality of the procedure pointers.
1523+
* If they are not the same (including the same name), then
1524+
* it returns false. This is correct for an equality test.
1525+
* However, in this case, we don't care about the names being
1526+
* the same if all other attributes are equal.
1527+
*/
1528+
DTYPE d1 = DTY(f_dt + 1);
1529+
DTYPE d2 = DTY(a_dt + 1);
1530+
if (cmp_interfaces(DTY(d1 + 2), DTY(d2 + 2), FALSE)) {
1531+
return TRUE;
1532+
}
1533+
}
15201534
return FALSE;
15211535
}
15221536

tools/flang1/flang1exe/func.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,6 +1968,23 @@ rewrite_func_ast(int func_ast, int func_args, int lhs)
19681968
ARGT_ARG(newargt, 3) = dim;
19691969
}
19701970
goto ret_new;
1971+
case I_EXECUTE_COMMAND_LINE:
1972+
nargs = 7;
1973+
rtlRtn = RTE_execcmdline;
1974+
newsym = sym_mkfunc_nodesc(mkRteRtnNm(rtlRtn), DT_INT);
1975+
newargt = mk_argt(nargs);
1976+
for (i = 0; i < nargs - 1; i++) {
1977+
int arg = ARGT_ARG(func_args, i);
1978+
ARGT_ARG(newargt, i) = arg != 0 ? arg : i == 0 ? astb.ptr0c : astb.ptr0;
1979+
}
1980+
/* Add two extra arguments at the end of the execute_command_line argument
1981+
list. Those two integer kind for the exitstat and cmdstat argument
1982+
respectively.
1983+
*/
1984+
ARGT_ARG(newargt, nargs - 2) = mk_cval(size_of(stb.user.dt_int), DT_INT4);
1985+
ARGT_ARG(newargt, nargs - 1) = mk_cval(size_of(stb.user.dt_int), DT_INT4);
1986+
is_icall = FALSE;
1987+
goto ret_call;
19711988
case I_NORM2: /* norm2(array, [dim]) */
19721989
srcarray = ARGT_ARG(func_args, 0);
19731990
dim = ARGT_ARG(func_args, 1);

tools/flang1/flang1exe/lower.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,15 @@
136136
* All of 1.53 +
137137
* pass allocptr and ptrtarget values for default initialization
138138
* of standalone pointers.
139+
*
140+
* 20.1 -- 1.55
141+
* All of 1.54 +
142+
* pass elemental field for subprogram when emitting ST_ENTRY.
143+
*
144+
* For ST_PROC, pass IS_PROC_PTR_IFACE flag.
139145
*/
140146
#define VersionMajor 1
141-
#define VersionMinor 54
147+
#define VersionMinor 55
142148

143149
void lower(int);
144150
void lower_end_contains(void);

tools/flang1/flang1exe/lowersym.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,6 +3951,7 @@ lower_symbol(int sptr)
39513951
#endif
39523952
putbit("pure", 0);
39533953
putbit("recursive", 0);
3954+
putbit("elemental", 0);
39543955
putval("returnval", 0);
39553956
putbit("passbyval", 0);
39563957
putbit("passbyref", 0);
@@ -4042,6 +4043,7 @@ lower_symbol(int sptr)
40424043
putbit("is_interface", IS_INTERFACEG(sptr));
40434044
putval("assocptr", ASSOC_PTRG(sptr));
40444045
putval("ptrtarget",PTR_TARGETG(sptr));
4046+
putbit("prociface", IS_PROC_PTR_IFACEG(sptr));
40454047
}
40464048

40474049
strip = 1;
@@ -4077,6 +4079,7 @@ lower_symbol(int sptr)
40774079
putbit("mscall", MSCALLG(sptr));
40784080
putbit("pure", PUREG(sptr));
40794081
putbit("recursive", RECURG(sptr));
4082+
putbit("elemental", ELEMENTALG(sptr));
40804083
putsym("returnval", FVALG(sptr));
40814084
putbit("passbyval", PASSBYVALG(sptr));
40824085
putbit("passbyref", PASSBYREFG(sptr));
@@ -4271,6 +4274,7 @@ lower_symbol(int sptr)
42714274
#endif
42724275
putval("assocptr", ASSOC_PTRG(sptr));
42734276
putval("ptrtarget", PTR_TARGETG(sptr));
4277+
putbit("prociface", IS_PROC_PTR_IFACEG(sptr));
42744278
strip = 1;
42754279
break;
42764280

@@ -4320,6 +4324,7 @@ lower_symbol(int sptr)
43204324
putbit("is_interface", 0);
43214325
putval("assocptr", 0);
43224326
putval("ptrtarget", 0);
4327+
putbit("prociface", 0);
43234328
strip = 1;
43244329
break;
43254330

@@ -4521,6 +4526,7 @@ lower_symbol(int sptr)
45214526
putval("descriptor", IS_PROC_DUMMYG(sptr) ? SDSCG(sptr) : 0);
45224527
putsym("assocptr", ASSOC_PTRG(sptr));
45234528
putsym("ptrtarget", PTR_TARGETG(sptr));
4529+
putbit("prociface", IS_PROC_PTR_IFACEG(sptr));
45244530
if (gbl.stbfil && DTY(DTYPEG(sptr) + 2)) {
45254531
if (fvalfirst) {
45264532
putsym(NULL, FVALG(sptr));

tools/flang1/flang1exe/scopestack.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -421,17 +421,14 @@ void
421421
par_pop_scope(void)
422422
{
423423
SCOPE_SYM *symp;
424-
int blksym;
425424
/*
426-
* Restore the scope of any symbols which appeared in a SHARED
427-
* clause -- this is only needed if the DEFAULT scope is 'PRIVATE' or
428-
* 'NONE".
425+
* Restore the scope of any symbols that appeared in a SHARED clause.
426+
* This is only needed if the DEFAULT scope is 'PRIVATE' or 'NONE".
429427
*/
430428
for (symp = curr_scope()->shared_list; symp != NULL; symp = symp->next) {
431429
SCOPEP(symp->sptr, symp->scope);
432430
}
433-
blksym = curr_scope()->sym;
434-
if (blksym) {
431+
if (BLK_SYM(sem.scope_level)) {
435432
exit_lexical_block(flg.debug && !XBIT(123, 0x400));
436433
}
437434

tools/flang1/flang1exe/semant.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,7 +2479,7 @@ semant1(int rednum, SST *top)
24792479
* body should never contain a procedure defined by a subprogram,
24802480
* so this flag should never be set for an interface. Because
24812481
* getsym() does not have access to sem.interface, we reset the
2482-
* NTERNAL flag here.
2482+
* INTERNAL flag here.
24832483
*/
24842484
INTERNALP(sptr, 0);
24852485
}
@@ -3027,7 +3027,7 @@ semant1(int rednum, SST *top)
30273027
set_construct_name(0);
30283028
// fall through
30293029
case BLOCK_STMT2:
3030-
if (DI_NEST(sem.doif_depth) >= DI_B(DI_FIRST_DIRECTIVE))
3030+
if (DI_NEST(sem.doif_depth) >= DI_B(DI_FIRST_DIRECTIVE) && !XBIT(59,8))
30313031
error(1219, ERR_Severe, gbl.lineno,
30323032
"BLOCK construct in the scope of a parallel directive", CNULL);
30333033
sptr = sem.scope_stack[sem.scope_level].sptr;
@@ -11343,6 +11343,49 @@ semant1(int rednum, SST *top)
1134311343
if (POINTERG(sptr)) {
1134411344
attr |= ET_B(ET_POINTER);
1134511345
}
11346+
if (!IS_PROC_DUMMYG(sptr) && IS_INTERFACEG(proc_interf_sptr) &&
11347+
!IS_PROC_PTR_IFACEG(proc_interf_sptr)) {
11348+
/* Create a unique symbol for the interface so it does not conflict with
11349+
* an external procedure symbol. For non-procedure dummy arguments,
11350+
* we need a unique symbol for the interface in order to preserve
11351+
* the interface flag (IS_PROC_PTR_IFACE). We need the interface flag in
11352+
* the back-end so we properly generate the procedure descriptor
11353+
* actual arguments on the call-site (when we call the procedure pointer).
11354+
* This is only needed by the LLVM back-end because the bridge uses the
11355+
* interface to generate the LLVM IR for the actual arguments.
11356+
*/
11357+
char * buf;
11358+
int len;
11359+
SPTR sym;
11360+
11361+
/* First, let's see if we aleady have a unique interface symbol */
11362+
len = strlen(SYMNAME(proc_interf_sptr)) + strlen("iface") + 1;
11363+
buf = getitem(0, len);
11364+
sprintf(buf,"%s$iface",SYMNAME(proc_interf_sptr));
11365+
sym = findByNameStypeScope(buf, ST_PROC, 0);
11366+
if (sym > NOSYM && !cmp_interfaces_strict(sym, proc_interf_sptr, 0)) {
11367+
/* The interface is not compatible. We will now try to find one that
11368+
* is compatible in the symbol table.
11369+
*/
11370+
SPTR sym2 = sym;
11371+
get_next_hash_link(sym2, 0);
11372+
while ((sym2=get_next_hash_link(sym2, 1)) > NOSYM) {
11373+
if (cmp_interfaces_strict(sym2, proc_interf_sptr, 0)) {
11374+
break;
11375+
}
11376+
}
11377+
sym = sym2;
11378+
}
11379+
if (sym <= NOSYM) {
11380+
/* We don't yet have a unique interface symbol, so create it now */
11381+
sym = get_next_sym(SYMNAME(proc_interf_sptr), "iface");
11382+
/* Propagate flags from the original symbol to the new symbol */
11383+
copy_sym_flags(sym, proc_interf_sptr);
11384+
HCCSYMP(sym, 1);
11385+
IS_PROC_PTR_IFACEP(sym, 1);
11386+
}
11387+
proc_interf_sptr = sym;
11388+
}
1134611389
sptr = decl_procedure_sym(sptr, proc_interf_sptr, attr);
1134711390
sptr =
1134811391
setup_procedure_sym(sptr, proc_interf_sptr, attr, entity_attr.access);

0 commit comments

Comments
 (0)