From 2d27134084de7f5742fbd2379b51ac5d040245a7 Mon Sep 17 00:00:00 2001 From: gfunck Date: Tue, 24 Jul 2012 23:30:09 +0000 Subject: [PATCH] gcc/upc/ Per UPC spec. 6.4.2p6, ignore the value of the phase of a pointer-to-shared, when comparing for equal or not equal. * upc-pts-packed.c (upc_pts_packed_build_cond_expr): Use bit-wise comparison only if the UPC pointer-to-shared target type has a block size <= 1 and the representation has vaddr first or the comparison is for equality/inequality. * upc-pts-struct.c (upc_pts_struct_build_cond_expr): Use (vaddr, thread) comparison only if the UPC pointer-to-shared has a block size <= 1 or the comparison is for equality/inequality. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gupc@189829 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/upc/ChangeLog | 13 +++++++++++++ gcc/upc/upc-pts-packed.c | 33 +++++++++++++++++++++++++++------ gcc/upc/upc-pts-struct.c | 41 ++++++++++++++++++++++------------------- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/gcc/upc/ChangeLog b/gcc/upc/ChangeLog index 88e137450a9..135d42858bc 100644 --- a/gcc/upc/ChangeLog +++ b/gcc/upc/ChangeLog @@ -1,3 +1,16 @@ +2012-07-24 Gary Funck + + Per UPC spec. 6.4.2p6, ignore the value of the + phase of a pointer-to-shared, when comparing for + equal or not equal. + * upc-pts-packed.c (upc_pts_packed_build_cond_expr): + Use bit-wise comparison only if the UPC pointer-to-shared + target type has a block size <= 1 and the representation + has vaddr first or the comparison is for equality/inequality. + * upc-pts-struct.c (upc_pts_struct_build_cond_expr): + Use (vaddr, thread) comparison only if the UPC pointer-to-shared + has a block size <= 1 or the comparison is for equality/inequality. + 2012-07-04 Gary Funck * config-lang.in: Adjust for move of C front-end files. diff --git a/gcc/upc/upc-pts-packed.c b/gcc/upc/upc-pts-packed.c index 8b37ad3ba08..01d3df11a31 100644 --- a/gcc/upc/upc-pts-packed.c +++ b/gcc/upc/upc-pts-packed.c @@ -571,11 +571,20 @@ upc_pts_packed_build_cvt (location_t loc, tree exp) /* Expand the expression EXP, which is a comparison between two UPC pointers-to-shared. + Per 6.4.2p6: + Two compatible pointers-to-shared which point to the same object + (i.e. having the same address and thread components) shall compare + as equal according to == and !=, regardless of whether the phase + components match. + When a UPC pointer-to-shared is represented as (vaddr, thread, phase) - the comparison can be done all at once, when comparing - for equality. For the 'packed' representation, we can - use a straight integer comparison of the representation types. */ + and the underlying pointer component types have a block size <=1, + we can use a straight unsigned integer comparison of the + representation types. Otherwise, if vaddr comes + last, then the straight bit-wise comparison works only for equality. + For the equality operation when the block size is greater than 1, + the phase field is first masked off. */ static tree upc_pts_packed_build_cond_expr (location_t loc, tree exp) { @@ -601,9 +610,10 @@ upc_pts_packed_build_cond_expr (location_t loc, tree exp) const tree bs1 = upc_get_block_factor (elem_type1); const int has_phase0 = !(integer_zerop (bs0) || integer_onep (bs0)); const int has_phase1 = !(integer_zerop (bs1) || integer_onep (bs1)); - const int has_phase = has_phase0 && has_phase1; - const int is_bitwise_cmp = ((code == EQ_EXPR || code == NE_EXPR) - || (!has_phase && UPC_PTS_VADDR_FIRST)); + const int has_phase = has_phase0 || has_phase1; + const int is_eq_op = (code == EQ_EXPR || code == NE_EXPR); + const int is_bitwise_cmp = is_eq_op + || (!has_phase && UPC_PTS_VADDR_FIRST); if (is_bitwise_cmp) { if (ttcode0 == VIEW_CONVERT_EXPR @@ -616,6 +626,17 @@ upc_pts_packed_build_cond_expr (location_t loc, tree exp) op1 = TREE_OPERAND (op1, 0); else op1 = build1 (VIEW_CONVERT_EXPR, upc_pts_rep_type_node, op1); + if (is_eq_op) + { + /* Mask off the phase value. */ + const_tree phase_mask = + fold_build1_loc (loc, BIT_NOT_EXPR, upc_pts_rep_type_node, + build_binary_op (loc, LSHIFT_EXPR, + upc_phase_mask_node, + upc_phase_shift_node, 0)); + op0 = build_binary_op (loc, BIT_AND_EXPR, op0, phase_mask, 0); + op1 = build_binary_op (loc, BIT_AND_EXPR, op1, phase_mask, 0); + } } else { diff --git a/gcc/upc/upc-pts-struct.c b/gcc/upc/upc-pts-struct.c index 1b72957cb2b..59ab3343b4c 100644 --- a/gcc/upc/upc-pts-struct.c +++ b/gcc/upc/upc-pts-struct.c @@ -577,16 +577,30 @@ upc_pts_struct_build_cvt (location_t loc, tree exp) return result; } -/* Rewrite op0 CMP op1 into a field by field - comparison of the UPC pointer-to-shared operands - in the following order: vaddr, thread, phase. */ + +/* Expand the expression EXP, which is a comparison between two + UPC pointers-to-shared. + + Per 6.4.2p6: + Two compatible pointers-to-shared which point to the same object + (i.e. having the same address and thread components) shall compare + as equal according to == and !=, regardless of whether the phase + components match. + + Thus, for the equality comparison, the phase component of the + pointers is omitted from the comparison. In that case, + rewrite the pointer-to-shared comparison operation into a + field by field comparison of the UPC pointer-to-shared operands + in the following order: (vaddr, thread). + + If the bit-wise comparison cannot be performed, then the difference + between the pointers is compared to zero. */ static tree upc_pts_struct_build_cond_expr (location_t loc, tree exp) { tree result; const enum tree_code code = TREE_CODE (exp); - const int is_bitwise_cmp = (code == EQ_EXPR || code == NE_EXPR); tree op0 = TREE_OPERAND (exp, 0); tree op1 = TREE_OPERAND (exp, 1); const tree type0 = TREE_TYPE (op0); @@ -605,8 +619,10 @@ upc_pts_struct_build_cond_expr (location_t loc, tree exp) const tree bs1 = upc_get_block_factor (ttype1); const int has_phase0 = !(integer_zerop (bs0) || integer_onep (bs0)); const int has_phase1 = !(integer_zerop (bs1) || integer_onep (bs1)); - const int has_phase = has_phase0 && has_phase1; - if (is_bitwise_cmp) + const int has_phase = has_phase0 || has_phase1; + const int is_eq_op = (code == EQ_EXPR || code == NE_EXPR); + const int is_vaddr_thread_cmp = !has_phase || is_eq_op; + if (is_vaddr_thread_cmp) { const tree t_t = TREE_TYPE (upc_thread_field_node); const tree v_t = TREE_TYPE (upc_vaddr_field_node); @@ -639,19 +655,6 @@ upc_pts_struct_build_cond_expr (location_t loc, tree exp) const tree thread_cmp = build_binary_op (loc, code, thread0, thread1, 0); result = build_binary_op (loc, tcode, off_cmp, thread_cmp, 0); - if (has_phase) - { - const tree p_t = TREE_TYPE (upc_phase_field_node); - const tree phase0 = build3 (COMPONENT_REF, p_t, op0, - upc_phase_field_node, - NULL_TREE); - const tree phase1 = build3 (COMPONENT_REF, p_t, op1, - upc_phase_field_node, - NULL_TREE); - const tree phase_cmp = - build_binary_op (loc, code, phase0, phase1, 0); - result = build_binary_op (loc, tcode, result, phase_cmp, 0); - } /* Remove possible C_MAYBE_EXPR operands. */ result = c_fully_fold (result, 0, NULL); result = gimple_boolify (result); -- 2.11.4.GIT