clangupc / upc2c Goto Github PK
View Code? Open in Web Editor NEWClang based UPC to C Translator
Home Page: https://clangupc.github.io/clang-upc2c
License: Other
Clang based UPC to C Translator
Home Page: https://clangupc.github.io/clang-upc2c
License: Other
The following code:
#include <upc.h>
void my_function ( shared int * restrict y1)
{
}
reports the following error:
t.upc:3:27: error: restrict requires a pointer or reference ('upcr_pshared_ptr_t' (aka 'struct <anonymous>') is invalid)
void my_function ( shared int * restrict y1)
^
error: restrict requires a pointer or reference ('upcr_pshared_ptr_t' (aka 'struct <anonymous>') is invalid)
t.upc:3:27: error: restrict requires a pointer or reference ('upcr_pshared_ptr_t' (aka 'struct <anonymous>') is invalid)
error: restrict requires a pointer or reference ('upcr_pshared_ptr_t' (aka 'struct <anonymous>') is invalid)
One more AST print issues (bug858a.c). The following code:
typedef struct type_e {
int x;
int y;
struct { char ca[2]; int i; float f; } s;
int z;
} type_e;
type_e e1 = { .x = 1, .z = 2 };
converts to
typedef struct type_e {
int x;
int y;
struct {
char ca[2];
int i;
float f;
} s;
int z;
} type_e;
type_e e1 = { 1, /*implicit*/(int)0, /*implicit*/(struct <anonymous struct at bug858a.c:74:9>){}, 2 };
The following error is coming from spec1.3/issue64b. The errors coming out of the compiler are most likely ok as we are not spec 1.3 compatible. But we should not crash on the assertion error.
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/include/llvm/Support/Casting.h:97: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = clang::NullStmt; From = clang::Stmt]: Assertion `Val && "isa<> used on a null pointer"' failed.
Stack dump:
0. parser at end of file
spec1.3/issue64 generates warnings as barrier IDs are not of integer type.
UPC spec 1.3 states that barrier "expression shall have a type such that its value may be assigned to an object of type int". This means that implicit conversion on barrier ID is ok and should not produce a warning.
I cannot say if this is similar/related to #32.
The following code (upc-tutorial/heat_4.upc):
shared struct {
shared [] double *local;
} grid[THREADS], new_grid[THREADS];
translates into
typedef struct {
upcr_pshared_ptr_t local;
} _bupc_anon_struct0;
upcr_pshared_ptr_t grid;
typedef struct <anonymous at issue43.upc:1:8> _bupc_anon_struct1;
upcr_pshared_ptr_t new_grid;
When a UPC code calls the reduce functions with a predefined operation, one passes NULL for the user-provided function pointer. The upc2c translation of this idiom is causing warnings from (at least) the Sun C compiler that are not present with the Berkeley translator and the same backend compiler.
"try_all.trans.c", line 185: warning: argument #6 is incompatible with prototype:
prototype: pointer to function(int, int) returning int : "try_all.trans.c", line 29
argument : pointer to void (E_ARG_INCOMPATIBLE_WITH_ARG_L)
In the upc2c-generated .trans.c file the reduce calls end up with argument 6 as ((void *)0)
, while the Berkeley translator emits (int(*)(int, int)) 0ULL
.
It is clear to my why the Sun C compiler doesn't warn for the Berkeley translator with it's explicit cast. What is not clear to me is whether one should:
I have tried the second option (suppression) and it works, BUT I believe the necessary suppression flag is squashing warnings for any incompatible function arguments. That is overkill, but perhaps harmless if we assume upc2c will catch the incompatible args first.
Some of the tests get a warning and fail to link as "exit()" is being translated into "__upc_exit()" that does not exist.
For a simple example:
int main () { exit(1); }
generated code:
int user_main() {
UPCR_BEGIN_FUNCTION();
{
__upc_exit(1);
}
}
while BUPC does the following:
extern int user_main()
#line 3 "e.upc"
{
#line 3 "e.upc"
UPCR_BEGIN_FUNCTION();
#line 4 "e.upc"
exit((int) 1);
UPCR_EXIT_FUNCTION();
return 0;
} /* user_main */
Is it possible that clang-upc preprocessor is getting involved here? And rewrites exit before the translator?
The following code (dup_quals.upc):
const const int c1;
generates a warning from the translator:
warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier]
'clangupc' does the same. Note that warning is not generated for duplicate "shared", "relaxed", "strict" and the warning "-Wduplicate-decl-specifier" should control them too.
The other issue is why do we assert this warning if we are C99. Is there a subset of C99 warnings that need to be asserted?
GWU test case XIII_case1_i.upc fails with runtime error as we failed to allocate one of the shared arrays. For the code:
shared [] int src[SIZE];
shared [] int* shared dst[THREADS];
upc2c produces this allocation routine:
extern void UPCRI_ALLOC_XIII_case1_i_1703796583() {
UPCR_BEGIN_FUNCTION();
upcr_startup_pshalloc_t _bupc_pinfo[1] = { UPCRT_STARTUP_PSHALLOC(dst, 8UL, 1UL, 1UL, 8UL, "") };
upcr_startup_pshalloc(_bupc_pinfo, 1UL);
}
Berkeley compiler produces the following code:
void UPCRI_ALLOC_XIII_case1_i_12412478792584718051(void) {
UPCR_BEGIN_FUNCTION();
upcr_startup_pshalloc_t _bupc_pinfo[] = {
UPCRT_STARTUP_PSHALLOC(src, 400000, 1, 0, 4, "A100000_R0_i"),
UPCRT_STARTUP_PSHALLOC(dst, 8, 1, 1, 8, "A1H_R1_PR0_i"),
};
(bug40.upc)
'\xFF` is getting converted into '\UFFFFFFFF' and error is being reported
bug40.trans.c:44:27: error: \Uffffffff is not a valid universal character
Just noticed that .c files are compiled as C files instead of UPC.
Noticed that clangupc does the following:
clangupc -c test.c
clang-3.3: warning: treating 'c' input as 'upc' when in UPC mode, this behavior is deprecated
The following code is a shorter version of bug858:
int test_a(void) {
typedef struct type_a {
int x;
int y;
int arr[10];
} type_a;
}
is being converted into
int test_a() {
UPCR_BEGIN_FUNCTION();
{
struct type_a {
int x;
int y;
int arr[10];
} typedef struct type_a;
}
}
The following code fails to generate the right results (shorter version of bugzill/checkforall.upc):
#include <upc.h>
#include <stdio.h>
#define N 10
#define M 11
#define check(expr) do { \
if (!(expr)) printf("ERROR: thread %i failed (%s) at %s:%i\n", \
MYTHREAD, #expr, __FILE__, __LINE__); } while (0)
int main() {
int i,j;
int cnt1, cnt2;
cnt1 = 0;
cnt2 = 0;
for (i=0;i<N;i++) {
cnt1++;
upc_forall (j=0; j<M*THREADS; j++; j) {
cnt2++;
printf ("j=%d\n", j);
check(j % THREADS == MYTHREAD);
}
}
printf ("cnt2: %d expected: %d\n", cnt2, N*M);
check(cnt2 == N*M);
}
Running it produces the following output:
j=0
j=0
j=0
j=0
j=0
j=0
j=0
j=0
j=0
j=0
cnt2: 10 expected: 110
ERROR: thread 0 failed (cnt2 == N*M) at checkforall.upc:26
Note that checkforall has some other upc_forall statements that seem to work. I don't know if this is the issue of the nested for loop.
upc2c needs to return "1" if compilation does not succeed. Right now a 0 is always returned which cases issues with negative tests that expect an error condition.
gcc/clangupc return 1 on compilation errors.
Tests with "-" in their names (e.g. no-main-return.upc) fail to compile as we generated the following alloc/init procedures:
UPCRI_ALLOC_no-main-return_976640825()
UPCRI_INIT_no-main-return_976640825()
We need to build a valid C procedure name from the file name.
I don't think that upc2c does anything wrong here, but will document it as this is different from what BUPC does. Sample code is taken from 'detect_upc/cycle.c'. The following program:
extern shared int b;
int
main ()
{
b=1;
}
fails to link with 'b' being undefined variable. Clangupc and GUPC also fail to link, but BUPC does not. The difference from BUPC is that upc2c converts like this:
extern shared int b; -> extern upcr_pshared_ptr_t b;
while BUPC drops the 'extern' part in the translation. In UPCR, the uniqueness of the shared variable is guaranteed by the run-time as allocation of the shared space is done only once. The first to come allocates the space, all the others get the same pointer to it.
The following code is generating a warning:
typedef char type_f2 [6];
void x ()
{
type_f2 f2[3] = { [1] = {[2] = 3,4} };
}
warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'type_f2' (aka 'char [6]')
[-Wint-conversion]
warning: excess elements in scalar initializer
'clangupc' (or gcc) does not produce this warning. Must be some clang issue.
This program fails with ICE (bug87):
/* all the headers listed in the ANSI-C spec */
#include <assert.h>
#if 0
/* complex currently not supported */
#include <complex.h>
#include <tgmath.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <fenv.h>
#include <float.h>
#include <inttypes.h>
#include <iso646.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <wchar.h>
#include <wctype.h>
#define CHECKSZ(x,val) assert(sizeof(x) == val)
int main(void) {
int8_t i8 = 0;
uint8_t u8 = 0;
int16_t i16 = 0;
uint16_t u16 = 0;
int32_t i32 = 0;
uint32_t u32 = 0;
int64_t i64 = 0;
uint64_t u64 = 0;
intptr_t ip = 0;
uintptr_t up = 0;
bool b = true;
CHECKSZ(int8_t,1);
CHECKSZ(uint8_t,1);
CHECKSZ(int16_t,2);
CHECKSZ(uint16_t,2);
CHECKSZ(int32_t,4);
CHECKSZ(uint32_t,4);
CHECKSZ(int64_t,8);
CHECKSZ(uint64_t,8);
CHECKSZ(i8,1);
CHECKSZ(u8,1);
CHECKSZ(i16,2);
CHECKSZ(u16,2);
CHECKSZ(i32,4);
CHECKSZ(u32,4);
CHECKSZ(i64,8);
CHECKSZ(u64,8);
u64=u64+u32+u16+u8;
i64=i64+i32+i16+i8;
printf("done.\n");
return 0;
}
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/tools/clang/tools/upc2c/Transform.cpp:1476: clang::Decl* {anonymous}::RemoveUPCTransform::TransformDeclarationImpl(clang::Decl*, clang::DeclContext*): Assertion `!"Unknown Decl"' failed.
This code:
#include <upc.h>
int
main ()
{
int x = 4/sizeof(shared const void *);
}
produces this warning:
t.upc:6:12: warning: division by zero is undefined [-Wdivision-by-zero]
int x = 4/sizeof(shared const void *);
This does not happen on clangupc or BUPC.
Some of the collective tests (try-prefix) fail in run-time due to the possible wrong casting or of the wrong test itself. It is all coming down to the following code:
#include <stdio.h>
int start = -1;
int n_local = 0;
unsigned int thr = 2;
int
main ()
int i;
for (i=start+thr; i<(start + n_local*thr); i+=thr) {
printf ("%d \n", i);
}
}
If 'thr' (unsigned int) is converted to integer first then the loop would not be executed at all. However the loop is being executed for each value of the integer and I suspect that somehow unsigned int comparison is done.
upc2c translator generates the following code to calculate the local contribution of the thread:
for (i = start + THREADS; i < (start + n_local * THREADS); i += THREADS) {
local_result += (UPCR_GET_PSHARED(&_bupc_spilld1,
(UPCR_ADD_PSHARED1(UPCR_SHARED_TO_PSHARED(src), 4UL, i)), 0UL, 4UL) , _bupc_spilld1);
}
And the THREADS is being defined as 'unsigned int' in one of the include files
(typedef unsigned int upcr_thread_t).
BUPC generates the following code:
i = start + ((int) upcr_threads () );
while(i < (start + (n_local * ((int) upcr_threads () ))))
and has the explicit cast of '(int)'. And for static threads, 'upcr_threads' is defined as THREADS. This cases the correct calculations.
#include <upc.h>
#include <stdlib.h>
int thread;
void
check ()
{
thread = upc_threadof (0);
thread = upc_threadof (NULL);
}
produces the following error:
issue6.upc:9:26: error: passing 'int' to parameter of incompatible type 'upcr_shared_ptr_t' (aka 'struct <anonymous>')
thread = upc_threadof (0);
issue6.upc:10:26: error: passing 'void *' to parameter of incompatible type 'upcr_shared_ptr_t' (aka 'struct <anonymous>')
thread = upc_threadof (NULL);
The current version of the translator leaves the #pragma upc in the translated code. It must be removed.
typedef struct test_case_t {
struct {int value;} first[1];
int second;
int third[1];
} test_case_t;
translates to
struct test_case_t {
struct _bupc_anon_struct0 first[1];
int second;
int third[1];
};
There is no _bupc_anon_struct0 definition.
After installing in the build area, the upc2c does not end up in the release area.
Hi, this may be a more general problem with rounding of double values, but I ran into it with GSL_DBL_MAX, when translating ode-initval2/driver.c. Trivial example follows:
$ cat big.c
#define GSL_DBL_MAX 1.7976931348623157e+308
int main() {
double d = GSL_DBL_MAX;
return 0;
}
which after upc2c big.c becomes:
$ cat big.trans.c
// ...
int user_main() {
UPCR_BEGIN_FUNCTION();
{
double d = 1.797693134862316E+308;
return 0;
}
return 0;
}
// ...
look at the last digits: 157 became 160 (with that '0' not printed).
Thanks, Wim
The following code (bug3198):
#include <upc.h>
void x ()
{
shared struct A {
shared [] int *pts1, *pts2;
} *a;
struct B {
shared [] int *pts1, *pts2;
};
shared struct S {
shared [] int *pts1, *pts2;
} *s = upc_alloc(sizeof(struct S));
shared struct B *b = upc_alloc(sizeof(struct B));
a = upc_alloc(sizeof(struct A));
}
produces the following errors:
t.trans.c: In function 'x':
t.trans.c:55:32: error: invalid application of 'sizeof' to incomplete type 'struct S'
t.trans.c:55:32: error: invalid application of 'sizeof' to incomplete type 'struct S'
t.trans.c:57:13: error: invalid application of 'sizeof' to incomplete type 'struct A'
t.trans.c:57:13: error: invalid application of 'sizeof' to incomplete type 'struct A'
The generated code misses definitions of struct A and S:
void x() {
UPCR_BEGIN_FUNCTION();
{
upcr_pshared_ptr_t a;
struct B {
upcr_pshared_ptr_t pts1;
upcr_pshared_ptr_t pts2;
};
upcr_pshared_ptr_t s = UPCR_SHARED_TO_PSHARED(upc_alloc(sizeof(struct S)));
upcr_pshared_ptr_t b = UPCR_SHARED_TO_PSHARED(upc_alloc(sizeof(struct B)));
a = UPCR_SHARED_TO_PSHARED(upc_alloc(sizeof(struct A)));
}
}
The following warning comes out of compiling some tests:
% upc2c -o test01.trans.c test01.upc
warning: expression result unused [-Wunused-value]
1 warning generated.
This warning does not come up when compiling the same test with "clangupc" I do not get any warning.
This error shows up during the program run.
#include <upc.h>
shared int arr[THREADS][THREADS];
int x;
void
test (int i)
{
x = arr[i+1][0];
}
The assignment statement is translated into:
x = (UPCR_GET_PSHARED(&_bupc_spilld0,
UPCR_ADD_PSHARED1(
UPCR_ADD_PSHARED1(arr, 4UL, (i + 1 * 4UL)), 4UL, 0), 0UL, 4UL) , _bupc_spilld0);
The above "i + 1 * 4UL" should be "(i + 1) * 4UL".
The following code (bug3124_good.upc):
enum incomplete_e;
produces:
enum incomplete_e {
};
which produces and error in compile time.
The following code:
void
issue4()
{
shared int *x;
x = x + 1;
x += 2;
}
generates an error on line "x += 2".
[nenad@dev 4]$ ../../bld/bin/upc2c -o issue4.trans.c issue4.upc
issue4.upc:7:5: error: invalid operands to binary expression ('upcr_pshared_ptr_t' (aka 'struct <anonymous>') and
'int')
x += 2;
~ ^ ~
1 error generated.
The following code (static-threads-val-too-big.upc):
/* Must be compiled with large static value of THREADS. */
shared int A[THREADS];
reports an error
error: THREADS value '2147483647' exceeds UPC implementation limit of '1024'
and returns error code of '0'.
I think that every error related to tool arguments will do the same. Also, in this case we should not produce any translate code. Right now we do. I don't know how is this similar to #3.
In the past (pre UPCR integration) the error was masked by another error caused by the #error pragma in the include files source code.
upc2c is emitting at least the following four builtins when translating bug547.upc from the Berkeley test suite:
__builtin_huge_val
__builtin_huge_valf
__builtin_inff
__builtin_nanf
Use of -fno-builtin does not have any effect.
This translation causes errors when the .trans.c is passed to a compiler without support for these buitins.
-Paul
The output of upc2c includes transformation of offsetof() to __builtin_offsetof().
This is due to, I believe, Clang's own stddef,h, which contains the following with NO conditional guards:
#define offsetof(t, d) __builtin_offsetof(t, d)
This leads to failures compiling a .trans.c file with a compiler that lacks this builtin.
Since this is in a HEADER, the -fno-builtin flag has no effect..
I propose to try fixing this by adding the following to the boilerplate emitted at the top of every trans.s file:
#define __builtin_offsetof(t, d) offsetof(t, d)
If that doesn't work (for instance due to coming after the #include lines in the .trans.c) then it may be preferable to have upc2c perform the renaming. As a last choice, the following should always work:
-Paul
The following error is being reported.
upcc: error during translator:
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/tools/clang/lib/AST/ExprConstant.cpp:4679: bool {anonymous}::IntExprEvaluator::Success(const llvm::APSInt&, const clang::Expr*, clang::APValue&): Assertion `SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() && "Invalid evaluation result."' failed.
Stack dump:
0. <eof> parser at end of file
The above error is being reported also on bug1732.
The following test (taken for bug137c/e) fails (no UPC code involved):
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
double foo(va_list ap) {
int x = va_arg((NULL,ap), int);
return x;
}
[nenad@dev bugzilla]$ ../../../../bld/bin/upc2c t.upc
t.upc:6:18: error: first argument to 'va_arg' is of type '__va_list_tag *' (aka 'struct __va_list_tag *') and not 'va_list'
int x = va_arg((NULL,ap), int);
~~~~~~~^~~~~~~~~~~~~~~
../../../../bld/bin/../lib/clang/3.4/include/stdarg.h:35:46: note: expanded from macro 'va_arg'
#define va_arg(ap, type) __builtin_va_arg(ap, type)
^
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/include/llvm/Support/Casting.h:97: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = clang::ParenListExpr; From = clang::Expr]: Assertion `Val && "isa<> used on a null pointer"' failed.
This seems to be specific to upc2c as clangupc does compile this code.
The current version of the translator does not recognize upc_code/c_code pragma values. Error is reported:
t.upc:3:13: warning: expected 'strict' or 'relaxed' after '#pragma upc' - ignored
^
t.upc:4:13: warning: expected 'strict' or 'relaxed' after '#pragma upc' - ignored
The following code fails (bug2895) to compare pointers to shared as equal:
shared int A[N*N*THREADS];
shared [1] int * shared s_psi1 = (shared [1] int *)&A;
[...]
check((shared void *)s_psi1 == (shared void *)&A);
The translated code:
if (!(UPCR_ISEQUAL_SHARED_SHARED(UPCR_PSHARED_TO_SHARED((UPCR_GET_PSHARED(&_bupc_spilld0, s_psi1, 0UL, 8UL) , _bupc_spilld0)), UPCR_PSHARED_TO_SHARED(A)))) {
fprintf(stderr, "%s:%d (thread %d) Error: test failed: %s\n", "t.upc", 44, MYTHREAD, "(shared void *)s_psi1 == (shared void *)&A");
fail = 1;
}
contains an error where the output of the UPCR_GET_PSHARED() (a void function) is passed as an argument to UPCR_PSHARED_TO_SHARED() which is an error. I am not sure how come the backend GCC does not recognize.
Another observation is the deficiency of the generated code. It looks like UPCR_ISEQUAL_SHARED_SHRED() is always used and arguments are always casted into SHARED. In the above case both of the pointers are phaseless. UPCR provides functions for every combinations of L/R pointers:
UPCR_ISEQUAL_SHARED_SHARED
UPCR_ISEQUAL_SHARED_PSHARED
UPCR_ISEQUAL_PSHARED_SHARED
UPCR_ISEQUAL_PSHARED_PSHARED
and there is no need to case phaseless pointer into a phased one.
Few of the test programs (10) produce the warning:
warning: declaration does not declare anything [-Wmissing-declarations]
It is caused by the incorrect clang AST print (I think). Simplified xample is like this:
struct one {
struct two {
int a;
int b;
} two [3];
};
struct one one[2];
it generates the following code:
41 struct one {
42 struct two {
43 int a;
44 int b;
45 };
46 struct two two[3];
47 };
48 struct one one[2];
with a warning on line 45. Has nothing to do with UPC.
The following code (from bug2960):
typedef shared [4] int T1[4*THREADS];
typedef shared [] short T3[4321];
shared [upc_localsizeof(T1)] char tmpT1[THREADS];
shared [upc_localsizeof(T3)] char tmpT3[THREADS];
produces the following translated code:
typedef int T1[4*THREADS];
typedef short T3[4321];
upcr_shared_ptr_t tmpT1;
upcr_shared_ptr_t tmpT3;
This produces the warning:
bug2960.trans.c:53:13: error: variably modified 'T1' at file scope
as THREADS was left in the typedef. I think we need to remove all typedef statements from the c code instead of removing "shared" only.
The following code (ptrmath-volatile.upc):
#include <upc.h>
shared char * volatile mysptr = NULL;
int main() {
++mysptr;
mysptr = mysptr + 1;
}
generates a warning on "++mysptr" line
warning: passing 'volatile upcr_pshared_ptr_t *' (aka 'volatile struct <anonymous> *') to parameter of type 'upcr_pshared_ptr_t *' (aka 'struct <anonymous> *') discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
Clangupc or BUPC do not generate a warning. Note that the next line does not generate warning.
Currently, about 30 tests fail with an internal assertion error in the transform package (there are really only 15 tests, as they are compiled twice);
upcc -network=smp -DCLASS=SS -DDEBUG -T 4 upc-examples/mg/mg.c
[...]
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/tools/clang/tools/upc2c/Transform.cpp:1315: clang::Decl* {anonymous}::RemoveUPCTransform::TransformDeclarationImpl(clang::Decl*, clang::DeclContext*): Assertion `!"Unknown Decl"' failed.
upcc -network=smp -nolines -c upc-semantic-checks/shared-vla-not-allowed.upc
[...]
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/tools/clang/tools/upc2c/Transform.cpp:1448: clang::FunctionDecl* {anonymous}::RemoveUPCTransform::GetSharedAllocationFunction(): Assertion `!"Other array types should not syntax check"' failed.
upcc -network=smp -nolines -trans lt-pts-and-local-ptr.upc
[...]
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/include/llvm/Support/Casting.h:97: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = clang::ParenExpr; From = clang::Expr]: Assertion `Val && "isa<> used on a null pointer"' failed.
upcc -network=smp -nolines -trans -T 4 bug3058.upc
[...]
upc2c: /eng/upc/dev/nenad/clang-upc2c/src/llvm/tools/clang/tools/upc2c/Transform.cpp:413: {anonymous}::RemoveUPCTransform::ArrayDimensionT {anonymous}::RemoveUPCTransform::GetArrayDimension(clang::QualType): Assertion `!"Other array types should not syntax check"' failed.
After the update to 3.4 baseline test18 gets an error:
test18.trans.c:243:18: error: unknown type name 'shared'
Here is a sample code:
void
bug230_proc(strict shared int ia[2][10*THREADS])
{
ia[0][0] = 1;
}
is translated into
void bug230_proc(shared strict int (*ia)[10*THREADS]) {
UPCR_BEGIN_FUNCTION();
int _bupc_spilld0;
{
(_bupc_spilld0 = 1 , UPCR_PUT_PSHARED_STRICT(UPCR_ADD_PSHARED1(UPCR_ADD_PSHARED1(ia, 4UL, (0 * (10UL * upcr_threads()))), 4UL, 0), 0UL, &_bupc_spilld0, 4UL) , _bupc_spilld0);
}
}
The following code:
int main(void)
{
extern int n;
return n;
}
translates into:
int user_main() {
UPCR_BEGIN_FUNCTION();
{
extern int n;
return n;
}
return 0;
}
and the following warning is getting reported:
bug956.trans.c: In function 'user_main':
bug956.trans.c:44:9: warning: nested extern declaration of 'n' [-Wnested-externs]
Hi, this comes from testing upc2c with upcc, on gsl-1.16. The failing file is gsl-1.16/sys/hypot.c, but it comes down to:
$ cat inl.c
inline double gsl_pow_2(const double x) {
return x * x;
}
which after translation becomes:
$ cat inl.trans.c
inline double gsl_pow_2(const double x) {
UPCR_BEGIN_FUNCTION();
{
return x * x;
}
}
which compiled by upcc yields the error message below. (And the gsl build treats this warning as error.)
I don't know enough what the resolution should be (no UPCR_... in inline functions, making the inline static, or a change in gasnet, or ...).
Thanks, Wim
$ clang -Wno-unused -DGASNET_SEQ -IUPC/berkeley_upc-2.18.0/gasnet -IUPC/berkeley_upc-2.18.0/gasnet/smp-conduit -IUPC/berkeley_upc-2.18.0/gasnet/other -IUPC/berkeley_upc-2.18.0/gasnet/extended-ref -IUPC/build/dbg/gasnet -IUPC/berkeley_upc-2.18.0 -IUPC/build/dbg -IUPC/berkeley_upc-2.18.0/upcr_postinclude -c 'inl.trans.c'
inl.trans.c:42:5: warning: static function 'gasneti_trace_setsourceline' is used in an inline function with external linkage [-Wstatic-in-inline]
UPCR_BEGIN_FUNCTION();
^
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/upcr_threads.h:439:5: note: expanded from macro 'UPCR_BEGIN_FUNCTION'
upcri_srcpos_declnosemi() /* intentional no semicolon */ \
^
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/upcr_err.h:76:67: note: expanded from macro 'upcri_srcpos_declnosemi'
#define upcri_srcpos_declnosemi() ; char _bupc_dummy_SRCPOS = _upcri_dosrcpos(0)
^
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/upcr_err.h:67:52: note: expanded from macro '_upcri_dosrcpos'
#define _upcri_dosrcpos(profcond) ((profcond),GASNETT_TRACE_SETSOURCELINE(__FILE__,__LINE__),0)
^
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/gasnet/gasnet_tools.h:406:44: note: expanded from macro 'GASNETT_TRACE_SETSOURCELINE'
#define GASNETT_TRACE_SETSOURCELINE GASNETI_TRACE_SETSOURCELINE
^
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/gasnet/gasnet_trace.h:178:37: note: expanded from macro 'GASNETI_TRACE_SETSOURCELINE'
(GASNETI_SRCLINE_TRACKING() ? gasneti_trace_setsourceline((const char *)filename, (unsigned int)linenum) : ((void)0))
^
inl.trans.c:41:1: note: use 'static' to give inline function 'gsl_pow_2' internal linkage
inline double gsl_pow_2(const double x) {
^
static
/home/wlav/Corvette/UPC/berkeley_upc-2.18.0/gasnet/gasnet_trace.h:139:10: note: 'gasneti_trace_setsourceline' declared here
void gasneti_trace_setsourceline(const char *filename, unsigned int linenum) {
^
1 warning generated.
Some of the translated tests report the following warning:
"warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]"
For example, test07_sep.upc, lines
33 void
34 test07 ()
35 {
36 extern shared int array[FACTOR * THREADS];
37 int i;
38 for (i = MYTHREAD; i < FACTOR * THREADS; i += THREADS)
39 {
40 array[i] = i + 1;
41 }
are converted into:
26 extern upcr_pshared_ptr_t array;
27 void test07() {
28 UPCR_BEGIN_FUNCTION();
29 int _bupc_spilld0;
30 int _bupc_spilld1;
31 {
32 ;
33 int i;
34 for (i = MYTHREAD; i < 100 * 8; i += 8) {
35 (_bupc_spilld0 = i + 1 , UPCR_PUT_PSHARED_STRICT(UPCR_ADD_PSHARED1(array, 4UL
, i), 0UL, &_bupc_spilld0, 4UL) , _bupc_spilld0);
36 }
and line 32 is causing the warning. Note that adding '-std=c99' as a gcc option does not help and warning still comes through. My experiments with some simpler code did not work, I was not able to reproduce the problem.
I tried the simple example:
int
main ()
{
x(1);
}
upc2c does generates a warning that there is no prototype but the generated code has the function prototype inserted just before the UPCRI_ALLOC.. :
int user_main() {
UPCR_BEGIN_FUNCTION();
{
x(1);
}
}
int x();
extern void UPCRI_ALLOC_t_1402437185() {
UPCR_BEGIN_FUNCTION();
}
extern void UPCRI_INIT_t_1402437185() {
UPCR_BEGIN_FUNCTION();
if (upcr_mythread() == 0) {
}
}
The following code (upcfish.upc):
struct OceanGrid1{
int SharkForceY;
};
struct Shark {
shared struct OceanGrid1 *position1;
shared struct OceanGrid *position;
};
struct OceanGrid{
int SharkForceY;
};
translates into
struct OceanGrid1 {
int SharkForceY;
};
struct Shark {
upcr_pshared_ptr_t position1;
struct OceanGrid;
upcr_pshared_ptr_t position;
};
struct OceanGrid {
int SharkForceY;
};
Line "struct OceanGrid" in the "Sahrk" structure is extra. It seems that it happens only on the incomplete types.
Lots of tests that do not have main() with explicit return statement generate a warning in the compile phase:
bug3045.trans.c: In function 'user_main':
bug3045.trans.c:62:1: warning: control reaches end of non-void function [-Wreturn-type]
The reason is the we rename main() to user_main() and we need to suppress the warning on user_main.
Can we generate code like this in the user_main():
user_main()
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmultichar"
[....]
#pragma clang diagnostic pop
}
BUPC adds an explicit return to every function that does not have one. For example"
int
main () {}
int
x () {}
int
y ()
{
return 2;
}
generates this:
#line 2 "t.upc"
extern int user_main()
#line 2 "t.upc"
{
#line 2 "t.upc"
UPCR_BEGIN_FUNCTION();
UPCR_EXIT_FUNCTION();
return 0;
} /* user_main */
#line 5 "t.upc"
extern int x()
#line 5 "t.upc"
{
#line 5 "t.upc"
UPCR_BEGIN_FUNCTION();
UPCR_EXIT_FUNCTION();
return 0;
} /* x */
#line 9 "t.upc"
extern int y()
#line 9 "t.upc"
{
#line 9 "t.upc"
UPCR_BEGIN_FUNCTION();
#line 10 "t.upc"
UPCR_EXIT_FUNCTION();
#line 10 "t.upc"
return 2;
} /* y */
It seems:
At the moment a translated file is generated even though there is an error in the source file. The output file does not contain any translations but rather snippets of code required by the UPCR (only the header code and empty alloc.init routines).
We should not generate the output file if there is a compile error.
Hi, again an example originally from gsl (siman/siman_tsp.c), but simplified here:
$ cat ptr.c
#define N_CITIES 4
double Mtsp(void *xp, void *yp)
{
int *route1 = (int *) xp, *route2 = (int *) yp;
double distance = 0;
unsigned int i;
for (i = 0; i < N_CITIES; ++i) {
distance += ((route1[i] == route2[i]) ? 0 : 1);
}
return distance;
}
becomes after translation (just upc2c ptr.c):
$ cat ptr.trans.c
// ...
double Mtsp(void *xp, void *yp) {
UPCR_BEGIN_FUNCTION();
{
int *route1 = (int *)xp, *route2 = (*)yp;
double distance = 0;
unsigned int i;
for (i = 0; i < 4; ++i) {
distance += ((route1[i] == route2[i]) ? 0 : 1);
}
return distance;
}
}
// ...
note how for the initialization of route2, the 'int' type has disappeared from the cast.
Thanks, Wim
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.