I have been looking at changing UPC's method of recording the blocking factor so that it uses less space in the tree type node. The suggested method for achieving this space reduction is to use a hash table to map pointers to type nodes into UPC blocking factors (for less commonly used blocking factor values).
In UPC, the default blocking factor for arrays is one, and for UPC shared scalar/struct variables it is zero. Therefore, the current approach is to only record blocking factors greater than one in a hash table. The basics are in place (in tree.h): -------------------------------------------------------------------- /* Non-zero if the UPC shared type refers to THREADS in its array dimension. */ #define UPC_TYPE_HAS_THREADS_FACTOR(TYPE) TYPE_LANG_FLAG_3 (TYPE) /* Non-zero if the UPC blocking factor is 0. */ #define UPC_TYPE_HAS_BLOCK_FACTOR_0(TYPE) TYPE_LANG_FLAG_4 (TYPE) /* Non-zero if the UPC blocking factor is greater than 1. In this case, the blocking factor value is stored in a hash table. */ #define UPC_TYPE_HAS_BLOCK_FACTOR_X(TYPE) TYPE_LANG_FLAG_5 (TYPE) extern void upc_block_factor_insert (tree, tree); extern tree upc_block_factor_lookup (tree); /* Return the UPC blocking factor of the type given by NODE. The default block factor is one. The additional flag bits over-ride the default. */ #define UPC_TYPE_BLOCK_FACTOR(NODE) \ (UPC_TYPE_HAS_BLOCK_FACTOR_0 (NODE) ? size_zero_node \ : UPC_TYPE_HAS_BLOCK_FACTOR_X (NODE) ? upc_block_factor_lookup (NODE) \ : size_one_node) -------------------------------------------------------------------- Note above, that the bits used are the TYPE_LANG_FLAG bits. This should be acceptable for UPC, because it is built as a language variant. Interestingly, if additional bits were allocated just for UPC, they would likely increase the size of the tree node, because there are no spare bits here: struct GTY(()) tree_type_common { [....] unsigned int precision : 10; [...] unsigned lang_flag_6 : 1; The bit field sizes in the interval shown above total to 32 bits. Therefore, it seems that any attempt to add new flag bits will likely increase the size of a tree_type_common node. -------------------------------------------------------------------- The issue that I'm running into, however, is that the re-implementation of UPC_TYPE_BLOCK_FACTOR() is not plug-and-play with its previous version that used a tree pointer in the node to record the blocking factor. Here's why: gcc/tree.c|5681 col 27| warning: passing argument 1 of ‘upc_block_factor_lookup’ discards qualifiers from pointer target type gcc/tree.h|1196 col 13| note: expected ‘tree’ but argument is of type ‘const_tree’ The code referenced above is: -------------------------------------------------------------------- bool check_qualified_type (const_tree cand, const_tree base, int type_quals) { return (TYPE_QUALS (cand) == type_quals [...] /* For UPC, the blocking factors have to be equal. */ && tree_int_cst_equal (UPC_TYPE_BLOCK_FACTOR (cand), UPC_TYPE_BLOCK_FACTOR (base)) [...] } -------------------------------------------------------------------- The prototype for upc_block_factor_lookup() accepts a 'tree', not a 'const_tree'. If the parameter is changed to 'const_tree', then the body of the procedure will encounter another 'const' clash because a tree_map is defined as having nodes of type 'tree', not 'const_tree'. For example, struct GTY(()) tree_map_base { tree from; }; -------------------------------------------------------------------- NOTE: I looked at calls to DECL_VALUE_EXPR() to see if it ran into this issue, however, only 'tree' nodes appear to be passed to this function macro. Any suggestions on how to work around this 'const' clash warning? Thanks, - Gary