We are in the process of updating GCC/UPC's support for the UPC dialect of C to version 4.2.0 of GCC. GCC/UPC is described here: http://www.intrepid.com/upc.html
Generally, things are working. However, at the moment, all tests fail when optimizations are enabled. For example: test00.upc:35: internal compiler error: in referenced_var_check_and_insert, at tree-dfa.c:639 It is failing on this check: (gdb) l 634 635 if (h) 636 { 637 /* DECL_UID has already been entered in the table. Verify that it is 638 the same entry as TO. See PR 27793. */ 639 gcc_assert (h->to == to); 640 return false; 641 } 642 643 h = GGC_NEW (struct int_tree_map); (gdb) p h->to $1 = 0x2aaaae1ad160 (gdb) pt <var_decl 0x2aaaae1ad160 x1 type <integer_type 0x2aaaaded5300 char public string-flag QI size <integer_cst 0x2aaaadec5810 constant invariant 8> unit size <integer_cst 0x2aaaadec5840 constant invariant 1> align 8 symtab 0 alias set -1 precision 8 min <integer_cst 0x2aaaadec58d0 -128> max <integer_cst 0x2aaaadec5990 127> pointer_to_this <pointer_type 0x2aaaadee8a80>> addressable used public static common QI defer-output file test00.upc line 26 size <integer_cst 0x2aaaadec5810 8> unit size <integer_cst 0x2aaaadec5840 1> align 8> (gdb) p to $2 = 0x2aaaae1b7630 (gdb) pt <var_decl 0x2aaaae1b7630 x1 type <integer_type 0x2aaaaded5300 char public string-flag QI size <integer_cst 0x2aaaadec5810 constant invariant 8> unit size <integer_cst 0x2aaaadec5840 constant invariant 1> align 8 symtab 0 alias set -1 precision 8 min <integer_cst 0x2aaaadec58d0 -128> max <integer_cst 0x2aaaadec5990 127> pointer_to_this <pointer_type 0x2aaaadee8a80>> addressable used public static common QI defer-output file test00.upc line 26 size <integer_cst 0x2aaaadec5810 8> unit size <integer_cst 0x2aaaadec5840 1> align 8> Above, the two tree nodes are clones of each other created by the following UPC-specific code: 1109 /* Convert shared variable reference VAR into a shared pointer 1110 value of the form {0, 0, &VAR} */ 1111 1112 tree 1113 upc_build_shared_var_addr (tree type, tree var) 1114 { 1115 tree new_var, var_addr, val; 1116 if (!(TREE_CODE (var) == VAR_DECL && TREE_SHARED (var))) 1117 abort (); 1118 if (!(TREE_CODE (type) == POINTER_TYPE && TYPE_SHARED (TREE_TYPE (type)))) 1119 abort (); 1120 1121 /* Create a VAR_DECL that is the same as VAR, but 1122 with qualifiers (esp. TYPE_QUAL_SHARED) removed so that 1123 we can create the actual address of the variable (in the shared 1124 section) without infinite recursion in the 1125 gimplification pass. Make sure the new copy has 1126 the same UID as the old. In the future, we might need 1127 to reference the symbol name directly. */ 1128 1129 new_var = copy_node (var); 1130 DECL_UID (new_var) = DECL_UID (var); 1131 TREE_TYPE (new_var) = TYPE_MAIN_VARIANT (TREE_TYPE (var)); 1132 TREE_SHARED (new_var) = 0; 1133 TREE_STRICT (new_var) = 0; 1134 TREE_RELAXED (new_var) = 0; 1135 var_addr = build_fold_addr_expr (new_var); 1136 TREE_CONSTANT (var_addr) = 1; 1137 val = upc_build_shared_ptr_value (type, 1138 integer_zero_node, 1139 integer_zero_node, 1140 var_addr); 1141 return val; 1142 } As background, GCC/UPC adds a new qualifier, "shared" to indicate that a value must be accessed remotely and that it is shared across all UPC "threads" (which can be thought of as processes all running the same program, but with differing local copies of data). The UPC specific aspects of the language are translated by a gimplify pass into normal gimple trees that are then passed to the middle and back ends of GCC. For example a reference to a value of a type that is qualified as "shared" will result in a call to a (possibly inlined) remote "get" library routine. Where this gimplify pass can get confused is when it sees a reference to a shared variable. If it sees a reference to a shared variable on the right hand side of an assignment, it assumes that its value is needed and generates a remote get call. The address of a shared variable has three parts (phase, thread, virtual address). For declared variables, the phase and thread are always 0. A constructor is used to create a shared address. That's what upc_build_shared_ptr_value() does above. The virtual address part of the shared address is simply the regular address of the variable, because all shared variables are collected together in their own "upc_shared" linkage section. This section is needed simply for address assignment purposes. The actual shared data is located in a global shared address region. The code above clones a shared variable, stripping its type qualifiers (most importantly the "shared" qualifier). When the address of the cloned variable is taken, its normal C pointer-sized address will result, and the special gimplify pass doesn't get confused, thinking that the address of the variable is a shared address. The code above isn't clever. It clones the variable each time it needs to generate a shared address. In GCC 4.2, this runs into problems in the optimization pass that implements special checks for this sort of inconsistency. The discussion above is a (very) long lead up to a request for ideas and suggestions for better handling this situation. One simple idea would be to leave the original VAR_DECL as is, but create a tree node that is an address expression which refers only to the variable's external name, and thus doesn't refer to any VAR_DECL. Is the possible? Schematically, it might look like thins: ptr_to_main_variant = build_pointer_type ( TYPE_MAIN_VARIANT (TREE_TYPE (var))); var_addr = build_fold_addr_expr_with_type (DECL_NAME(var), ptr_to_main_variant); but of course ADDR_EXPR doesn't allow a bare reference to an identifier. Is there some way to generate a tree node that creates an address, using only the external linkage name? The other idea that I've experimented with is to have the gimplify pass look for ADDR_EXPR of a shared variable, and rather than transform this into a 3 part constructor (phase, thread, virtual address), leave it as is, and then have a language-specific routine create the 3 part address literal using appropriate varasm constructs. This seemed promising, but runs into problems with various other consistency checks in the compiler that I haven't tried to figure out yet. All suggestions/help appreciated, - Gary