1 /* c-upc-pts-packed.c: implement UPC packed pointer-to-shared representation
2 Copyright (C) 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Gary Funck <gary@intrepid.com>
5 and Nenad Vukicevic <nenad@intrepid.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
27 #include "stringpool.h"
31 #include "langhooks.h"
39 #include "stor-layout.h"
46 #include "c-upc-gasp.h"
47 #include "c-upc-pts.h"
48 #include "c-upc-pts-ops.h"
49 #include "c-upc-rts-names.h"
51 static tree
upc_pts_packed_build_addrfield (location_t
, tree
);
52 static tree
upc_pts_packed_build_cond_expr (location_t
, tree
);
53 static tree
upc_pts_packed_build_constant (location_t
, tree
);
54 static tree
upc_pts_packed_build_cvt (location_t
, tree
);
55 static tree
upc_pts_packed_build_diff (location_t
, tree
);
56 static tree
upc_pts_packed_build_phaseof (location_t
, tree
);
57 static tree
upc_pts_packed_build_sum (location_t
, tree
);
58 static tree
upc_pts_packed_build_threadof (location_t
, tree
);
59 static tree
upc_pts_packed_build_value (location_t
, tree
, tree
, tree
, tree
);
60 static void upc_pts_packed_init_type (void);
61 static int upc_pts_packed_is_null_p (tree
);
63 const upc_pts_ops_t upc_pts_packed_ops
=
65 upc_pts_packed_build_value
,
66 upc_pts_packed_build_cond_expr
,
67 upc_pts_packed_build_constant
,
68 upc_pts_packed_build_cvt
,
69 upc_pts_packed_build_diff
,
70 upc_pts_packed_init_type
,
71 upc_pts_packed_is_null_p
,
72 upc_pts_packed_build_sum
,
73 upc_pts_packed_build_threadof
76 /* Build the internal representation of UPC's packed
77 pointer-to-shared type. */
80 upc_pts_packed_init_type (void)
82 tree shared_void_type
, shared_char_type
;
83 upc_pts_rep_type_node
= c_common_type_for_size (UPC_PTS_SIZE
, 1);
84 gcc_assert (TYPE_MODE (upc_pts_rep_type_node
) != BLKmode
);
85 record_builtin_type (RID_SHARED
, "upc_shared_ptr_t",
86 upc_pts_rep_type_node
);
87 shared_void_type
= c_build_qualified_type_1 (void_type_node
,
88 TYPE_QUAL_SHARED
, NULL_TREE
);
89 upc_pts_type_node
= build_pointer_type (shared_void_type
);
90 shared_char_type
= c_build_qualified_type_1 (char_type_node
,
93 upc_char_pts_type_node
= build_pointer_type (shared_char_type
);
95 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_VADDR_MASK
);
96 upc_thread_mask_node
=
97 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_THREAD_MASK
);
99 build_int_cst (upc_pts_rep_type_node
, UPC_PTS_PHASE_MASK
);
100 upc_vaddr_shift_node
=
101 build_int_cst (unsigned_type_node
, UPC_PTS_VADDR_SHIFT
);
102 upc_thread_shift_node
=
103 build_int_cst (unsigned_type_node
, UPC_PTS_THREAD_SHIFT
);
104 upc_phase_shift_node
=
105 build_int_cst (unsigned_type_node
, UPC_PTS_PHASE_SHIFT
);
107 upc_pts_packed_build_value (UNKNOWN_LOCATION
, upc_pts_type_node
,
108 integer_zero_node
, integer_zero_node
,
112 /* Called to expand a UPC specific constant into something the
113 backend can handle. Upon return a UPC pointer-to-shared will be
114 seen as the representation type of a UPC pointer-to-shared, with
115 individual (thread, phase, and virtual address) fields. */
118 upc_pts_packed_build_constant (location_t loc
, tree c
)
121 if (upc_pts_is_valid_p (c
))
123 const enum tree_code code
= TREE_CODE (c
);
124 if (!((code
== VIEW_CONVERT_EXPR
|| code
== NOP_EXPR
)
125 && (TREE_TYPE (TREE_OPERAND (c
, 0)) == upc_pts_rep_type_node
)))
128 build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
,
130 const tree phase
= upc_pts_packed_build_phaseof (loc
, val
);
131 const tree thread
= upc_pts_packed_build_threadof (loc
, val
);
132 const tree vaddr
= upc_pts_packed_build_addrfield (loc
, val
);
134 upc_pts_packed_build_value (loc
, TREE_TYPE (c
), vaddr
, thread
,
141 /* Build a constructor of the form {phase, thread, vaddr}. */
144 upc_pts_packed_build_value (location_t loc
, tree type
, tree vaddr
,
145 tree thread
, tree phase
)
148 const tree upc_pts_rep_t
= upc_pts_rep_type_node
;
149 const int is_null
= integer_zerop (phase
)
150 && integer_zerop (thread
) && integer_zerop (vaddr
);
151 const int is_const
= TREE_CONSTANT (phase
)
152 && TREE_CONSTANT (thread
) && TREE_CONSTANT (vaddr
);
155 result
= fold_convert (upc_pts_rep_t
, integer_zero_node
);
159 vaddr
= fold_convert (upc_pts_rep_t
, vaddr
);
161 build_binary_op (loc
, LSHIFT_EXPR
, vaddr
, upc_vaddr_shift_node
, 0);
162 if (!integer_zerop (thread
))
164 thread
= fold_convert (upc_pts_rep_t
, thread
);
165 result
= build_binary_op (loc
, BIT_IOR_EXPR
, result
,
166 build_binary_op (loc
, LSHIFT_EXPR
,
168 upc_thread_shift_node
,
171 if (!integer_zerop (phase
))
173 phase
= fold_convert (upc_pts_rep_t
, phase
);
174 result
= build_binary_op (loc
, BIT_IOR_EXPR
, result
,
175 build_binary_op (loc
, LSHIFT_EXPR
,
177 upc_phase_shift_node
,
181 TREE_CONSTANT (result
) = is_const
;
182 /* Wrap the representation value into the specified
183 UPC pointer-to-shared type */
184 result
= fold (build1 (VIEW_CONVERT_EXPR
, type
, result
));
185 TREE_CONSTANT (result
) = is_const
;
189 /* Return TRUE if EXP is a null UPC pointer-to-shared. */
192 upc_pts_packed_is_null_p (tree exp
)
194 if (exp
&& upc_pts_is_valid_p (exp
))
198 TREE_CODE (value
) == NOP_EXPR
199 || TREE_CODE (value
) == CONVERT_EXPR
200 || TREE_CODE (value
) == VIEW_CONVERT_EXPR
201 || TREE_CODE (value
) == NON_LVALUE_EXPR
;
202 value
= TREE_OPERAND (value
, 0)) /* loop */ ;
203 if ((TREE_TYPE (value
) == upc_pts_rep_type_node
)
204 && TREE_CONSTANT (value
))
205 return integer_zerop (value
);
210 /* Given EXP, whose type must be the UPC pointer-to-shared
211 representation type, isolate the virtual address field,
212 and return it. Caller must insure that EXP is a
213 stable reference, if required. */
216 upc_pts_packed_build_addrfield (location_t loc
, tree exp
)
219 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
220 vaddr
= build_binary_op (loc
, BIT_AND_EXPR
,
221 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
222 upc_vaddr_shift_node
, 0),
223 upc_vaddr_mask_node
, 0);
224 vaddr
= fold_convert (sizetype
, vaddr
);
228 /* Given, EXP, whose type must be the UPC pointer-to-shared
229 representation type, isolate the thread field,
230 and return it. Caller must insure that EXP is a
231 stable reference, if required. */
234 upc_pts_packed_build_threadof (location_t loc
, tree exp
)
237 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
238 affinity
= build_binary_op (loc
, BIT_AND_EXPR
,
239 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
240 upc_thread_shift_node
, 0),
241 upc_thread_mask_node
, 0);
242 affinity
= fold_convert (sizetype
, affinity
);
246 /* Given, EXP, whose type must be the UPC pointer-to-shared
247 representation type, isolate the phase field,
248 and return it. Caller must insure that EXP is a
249 stable reference, if required. */
252 upc_pts_packed_build_phaseof (location_t loc
, tree exp
)
255 gcc_assert (TREE_TYPE (exp
) == upc_pts_rep_type_node
);
256 phase
= build_binary_op (loc
, BIT_AND_EXPR
,
257 build_binary_op (loc
, RSHIFT_EXPR
, exp
,
258 upc_phase_shift_node
, 0),
259 upc_phase_mask_node
, 0);
260 phase
= fold_convert (sizetype
, phase
);
264 /* Rewrite EXP, an expression involving addition of an
265 integer to a UPC pointer-to-shared, into representation-specific
266 lower level operations. */
269 upc_pts_packed_build_sum (location_t loc
, tree exp
)
271 const tree op0
= TREE_OPERAND (exp
, 0);
272 const tree op1
= TREE_OPERAND (exp
, 1);
273 const enum tree_code op0_code
= TREE_CODE (TREE_TYPE (op0
));
274 const tree targ_type
= TREE_TYPE (TREE_TYPE (exp
));
275 const tree ptrop
= (op0_code
== POINTER_TYPE
) ? op0
: op1
;
276 const tree intop
= (op0_code
== POINTER_TYPE
) ? op1
: op0
;
279 if (integer_zerop (intop
))
285 const tree ptrop_as_pts_rep
= fold (build1 (VIEW_CONVERT_EXPR
,
286 upc_pts_rep_type_node
,
288 const tree sptrop
= save_expr (ptrop_as_pts_rep
);
289 const tree elem_type
= strip_array_types (targ_type
);
290 const tree elem_size
= !VOID_TYPE_P (elem_type
)
291 ? size_in_bytes (elem_type
) : integer_one_node
;
292 const tree block_factor
= upc_get_block_factor (elem_type
);
293 const int has_phase
= !(integer_zerop (block_factor
)
294 || integer_onep (block_factor
));
295 const tree old_vaddr
= upc_pts_packed_build_addrfield (loc
, sptrop
);
296 const tree index
= save_expr (intop
);
297 tree phase
, thread
, vaddr
;
298 if (VOID_TYPE_P (targ_type
) || integer_zerop (block_factor
))
300 /* vaddr = old_vaddr + index * elem_size */
301 vaddr
= build_binary_op (loc
, PLUS_EXPR
, old_vaddr
,
302 build_binary_op (loc
, MULT_EXPR
,
303 index
, elem_size
, 0),
305 thread
= upc_pts_packed_build_threadof (loc
, sptrop
);
306 phase
= integer_zero_node
;
310 const tree old_thread
=
311 upc_pts_packed_build_threadof (loc
, sptrop
);
312 const tree thread_cnt
= save_expr (upc_num_threads ());
313 /* n_threads must be a signed type, for various calculations
314 to work properly, below. */
315 const tree n_threads
= !TYPE_UNSIGNED (TREE_TYPE (thread_cnt
))
316 ? thread_cnt
: convert (integer_type_node
, thread_cnt
);
320 const tree elem_per_block
= block_factor
;
321 const tree old_phase
=
322 upc_pts_packed_build_phaseof (loc
, sptrop
);
323 tree nt_elems
, phase_diff
;
324 /* tincr = old_thread * elem_per_block + old_phase + index; */
325 tincr
= build_binary_op (loc
, PLUS_EXPR
,
326 build_binary_op (loc
, PLUS_EXPR
,
333 tincr
= save_expr (tincr
);
334 /* nt_elems = n_threads * elem_per_block; */
335 nt_elems
= build_binary_op (loc
, MULT_EXPR
, n_threads
,
337 nt_elems
= save_expr (nt_elems
);
338 /* Calculate floor_divmod (tincr, nt_elems, &t1, &t2);
339 n_elems and tincr must be a signed type, to ensure
340 that FLOOR_DIV and FLOOR_MOD work as expected. */
341 if (TYPE_UNSIGNED (TREE_TYPE (tincr
)))
342 tincr
= convert (integer_type_node
, tincr
);
343 if (TYPE_UNSIGNED (TREE_TYPE (nt_elems
)))
344 nt_elems
= convert (integer_type_node
, nt_elems
);
346 build_binary_op (loc
, FLOOR_DIV_EXPR
, tincr
, nt_elems
, 0);
348 build_binary_op (loc
, FLOOR_MOD_EXPR
, tincr
, nt_elems
, 0);
350 /* thread = t2 / elem_per_block; */
351 thread
= build_binary_op (loc
, TRUNC_DIV_EXPR
,
352 t2
, elem_per_block
, 0);
353 /* phase = t2 % elem_per_block; */
354 phase
= build_binary_op (loc
, TRUNC_MOD_EXPR
,
355 t2
, elem_per_block
, 0);
356 phase_diff
= build_binary_op (loc
, MINUS_EXPR
,
357 phase
, old_phase
, 0);
358 /* vaddr = old_vaddr + (t1 * elem_per_block + phase_diff)
360 vaddr
= build_binary_op (loc
, PLUS_EXPR
,
362 build_binary_op (loc
, MULT_EXPR
,
363 build_binary_op (loc
, PLUS_EXPR
,
364 build_binary_op (loc
, MULT_EXPR
,
365 t1
, elem_per_block
, 0),
371 /* tincr = old_thread + index; */
373 build_binary_op (loc
, PLUS_EXPR
, old_thread
, index
, 0);
374 tincr
= save_expr (tincr
);
375 /* floor_divmod (tincr, n_threads, &t1, &t2); */
376 if (TYPE_UNSIGNED (TREE_TYPE (tincr
)))
377 tincr
= convert (integer_type_node
, tincr
);
379 build_binary_op (loc
, FLOOR_DIV_EXPR
, tincr
, n_threads
, 0);
381 build_binary_op (loc
, FLOOR_MOD_EXPR
, tincr
, n_threads
, 0);
382 /* vaddr = old_vaddr + t1 * elem_size; */
383 vaddr
= build_binary_op (loc
, PLUS_EXPR
, old_vaddr
,
384 build_binary_op (loc
, MULT_EXPR
,
389 phase
= integer_zero_node
;
392 result
= upc_pts_packed_build_value (loc
, TREE_TYPE (exp
),
393 vaddr
, thread
, phase
);
398 /* Expand the expression EXP, which calculates the difference
399 between two UPC pointers-to-shared. */
402 upc_pts_packed_build_diff (location_t loc
, tree exp
)
404 tree op0
= TREE_OPERAND (exp
, 0);
405 tree op1
= TREE_OPERAND (exp
, 1);
406 const tree result_type
= ptrdiff_type_node
;
407 const tree target_type
= TREE_TYPE (TREE_TYPE (op0
));
408 const tree n_threads
= upc_num_threads ();
409 const tree elem_size
= convert (ssizetype
, size_in_bytes (target_type
));
410 const tree block_factor
= upc_get_block_factor (target_type
);
411 tree thread0
, thread1
, thread_diff
;
413 tree off0
, off1
, offset_diff
, elem_diff
;
416 /* The two pointers must both point to UPC shared objects, and we
417 have to perform the reverse of addition on UPC pointers-to-shared */
419 if ((upc_shared_type_p (target_type
)
420 && !upc_shared_type_p (TREE_TYPE (TREE_TYPE (op1
))))
421 || (upc_shared_type_p (TREE_TYPE (TREE_TYPE (op1
)))
422 && !upc_shared_type_p (target_type
)))
424 error ("attempt to take the difference of a UPC pointer-to-shared "
425 "and a local pointer");
426 return error_mark_node
;
428 op0
= save_expr (op0
);
429 op1
= save_expr (op1
);
430 op0
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op0
);
431 op1
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op1
);
432 off0
= upc_pts_packed_build_addrfield (loc
, op0
);
433 off1
= upc_pts_packed_build_addrfield (loc
, op1
);
434 /* Convert offset fields into ptrdiff_t types so that the
435 result of the difference comes out as a signed type. */
436 off0
= convert (result_type
, off0
);
437 off1
= convert (result_type
, off1
);
438 offset_diff
= build_binary_op (loc
, MINUS_EXPR
, off0
, off1
, 0);
439 elem_diff
= build_binary_op (loc
, EXACT_DIV_EXPR
,
440 offset_diff
, elem_size
, 0);
441 if (integer_zerop (block_factor
))
445 thread0
= convert (ssizetype
, upc_pts_packed_build_threadof (loc
, op0
));
446 thread1
= convert (ssizetype
, upc_pts_packed_build_threadof (loc
, op1
));
447 thread_diff
= build_binary_op (loc
, MINUS_EXPR
, thread0
, thread1
, 0);
448 phase_diff
= integer_zero_node
;
449 if (!tree_int_cst_equal (block_factor
, integer_one_node
))
452 convert (ssizetype
, upc_pts_packed_build_phaseof (loc
, op0
));
454 convert (ssizetype
, upc_pts_packed_build_phaseof (loc
, op1
));
456 save_expr (build_binary_op (loc
, MINUS_EXPR
, phase0
, phase1
, 0));
458 /* The expression below calculates the following:
459 (elem_diff - phase_diff) * THREADS
460 + (thread_diff * block_factor) + phase_diff; */
461 result
= build_binary_op (loc
, PLUS_EXPR
,
462 build_binary_op (loc
, PLUS_EXPR
,
463 build_binary_op (loc
, MULT_EXPR
,
464 build_binary_op (loc
, MINUS_EXPR
,
468 build_binary_op (loc
, MULT_EXPR
,
470 block_factor
, 0), 0),
472 result
= fold_convert (result_type
, result
);
476 /* Handle conversions between UPC pointers-to-shared and
477 local pointers, or between UPC pointers-to-shared which
478 have differing block factors. */
481 upc_pts_packed_build_cvt (location_t loc
, tree exp
)
483 const tree type
= TREE_TYPE (exp
);
484 const tree ptr
= TREE_OPERAND (exp
, 0);
485 tree tt1
, tt2
, b1
, b2
;
487 tt1
= TREE_TYPE (TREE_TYPE (exp
));
488 tt2
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp
, 0)));
489 b1
= upc_get_block_factor (tt1
);
490 b2
= upc_get_block_factor (tt2
);
491 if (upc_shared_type_p (tt1
) != upc_shared_type_p (tt2
))
493 if (upc_shared_type_p (tt1
))
495 /* Error: local -> shared */
496 result
= error_mark_node
;
500 /* shared -> local */
501 int doprofcall
= flag_upc_debug
502 || (flag_upc_instrument
&& get_upc_pupc_mode ());
503 const char *libfunc_name
=
504 doprofcall
? UPC_GETADDRG_LIBCALL
: UPC_GETADDR_LIBCALL
;
505 tree src
= build1 (NOP_EXPR
, upc_pts_rep_type_node
,
506 TREE_OPERAND (exp
, 0));
507 tree libfunc
, lib_args
, lib_call
;
508 libfunc
= identifier_global_value (get_identifier (libfunc_name
));
510 internal_error ("library function %s not found", libfunc_name
);
511 lib_args
= tree_cons (NULL_TREE
, src
, NULL_TREE
);
514 upc_gasp_add_src_args (lib_args
,
515 LOCATION_FILE (input_location
),
516 LOCATION_LINE (input_location
));
517 lib_call
= build_function_call (loc
, libfunc
, lib_args
);
518 result
= build1 (VIEW_CONVERT_EXPR
, type
, lib_call
);
521 else if ((upc_shared_type_p (tt1
) && !VOID_TYPE_P (tt1
))
522 && !(integer_zerop (b1
) && integer_zerop (b2
)))
524 /* Below, we handle the case of conversions to non-generic
526 tree s1
= TYPE_SIZE (tt1
);
527 tree s2
= TYPE_SIZE (tt2
);
528 /* normalize block sizes, so that [0] => NULL */
529 if (integer_zerop (b1
))
531 if (integer_zerop (b2
))
533 /* normalize type size so that 0 => NULL */
534 if (s1
&& integer_zerop (s1
))
536 if (s2
&& integer_zerop (s2
))
538 /* If the source type is an array type, then bypass
539 the check for equal type sizes. This arises when
540 an array is implicitly converted to a pointer to
542 if ((TREE_CODE (tt1
) != ARRAY_TYPE
)
543 && (TREE_CODE (tt2
) == ARRAY_TYPE
))
545 const tree elem_type1
= strip_array_types (tt1
);
546 const tree elem_type2
= strip_array_types (tt2
);
547 if (TYPE_MAIN_VARIANT (elem_type1
)
548 == TYPE_MAIN_VARIANT (elem_type2
))
551 /* If the source type is a not a generic pointer to shared, and
552 either its block size or type size differs from the target,
553 then the result must have zero phase. If the source type is
554 a generic pointer to shared and the target type is a pointer
555 to a shared type with either an indefinite block size, or
556 a block size of one, then the resulting value must have a
558 if ((!VOID_TYPE_P (tt2
)
559 && !(tree_int_cst_equal (b1
, b2
)
560 && tree_int_cst_equal (s1
, s2
)))
561 || (VOID_TYPE_P (tt2
)
563 || tree_int_cst_equal (b1
, integer_one_node
))))
565 const tree ptr_as_pts_rep
= fold (build1 (VIEW_CONVERT_EXPR
,
566 upc_pts_rep_type_node
,
568 const tree sptr
= save_expr (ptr_as_pts_rep
);
569 const tree ptr_with_zero_phase
=
570 upc_pts_packed_build_value (loc
, type
,
571 upc_pts_packed_build_addrfield (loc
, sptr
),
572 upc_pts_packed_build_threadof (loc
, sptr
),
574 result
= ptr_with_zero_phase
;
577 else if (upc_shared_type_p (tt1
) && VOID_TYPE_P (tt1
))
579 /* If the target is a generic pointer-to-shared type, we can
580 safely use the source value directly. */
583 gcc_assert (TREE_CODE (type
) != CONVERT_EXPR
);
587 /* Expand the expression EXP, which is a comparison between two
588 UPC pointers-to-shared.
591 Two compatible pointers-to-shared which point to the same object
592 (i.e. having the same address and thread components) shall compare
593 as equal according to == and !=, regardless of whether the phase
596 When a UPC pointer-to-shared is represented as (vaddr, thread, phase)
597 and the underlying pointer component types have a block size <=1,
598 we can use a straight unsigned integer comparison of the
599 representation types. Otherwise, if vaddr comes
600 last, then the straight bit-wise comparison works only for equality.
602 For the equality operation when the block size is greater than 1,
603 the phase field is first masked off. */
605 upc_pts_packed_build_cond_expr (location_t loc
, tree exp
)
608 const enum tree_code code
= TREE_CODE (exp
);
609 tree op0
= TREE_OPERAND (exp
, 0);
610 tree op1
= TREE_OPERAND (exp
, 1);
611 const tree type0
= TREE_TYPE (op0
);
612 const tree type1
= TREE_TYPE (op1
);
613 gcc_assert (POINTER_TYPE_P (type0
));
614 gcc_assert (POINTER_TYPE_P (type1
));
616 const tree ttype0
= TREE_TYPE (type0
);
617 const tree ttype1
= TREE_TYPE (type1
);
618 const enum tree_code ttcode0
= TREE_CODE (ttype0
);
619 const enum tree_code ttcode1
= TREE_CODE (ttype1
);
620 const tree elem_type0
= strip_array_types (ttype0
);
621 const tree elem_type1
= strip_array_types (ttype1
);
622 gcc_assert (TREE_SHARED (elem_type0
));
623 gcc_assert (TREE_SHARED (elem_type1
));
625 const tree bs0
= upc_get_block_factor (elem_type0
);
626 const tree bs1
= upc_get_block_factor (elem_type1
);
627 const int has_phase0
= !(integer_zerop (bs0
) || integer_onep (bs0
));
628 const int has_phase1
= !(integer_zerop (bs1
) || integer_onep (bs1
));
629 const int has_phase
= has_phase0
|| has_phase1
;
630 const int is_eq_op
= (code
== EQ_EXPR
|| code
== NE_EXPR
);
631 const int is_bitwise_cmp
= is_eq_op
632 || (!has_phase
&& UPC_PTS_VADDR_FIRST
);
635 if (ttcode0
== VIEW_CONVERT_EXPR
636 && TREE_TYPE (TREE_OPERAND (op0
, 0)) == upc_pts_rep_type_node
)
637 op0
= TREE_OPERAND (op0
, 0);
639 op0
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op0
);
640 if (ttcode1
== VIEW_CONVERT_EXPR
641 && TREE_TYPE (TREE_OPERAND (op1
, 0)) == upc_pts_rep_type_node
)
642 op1
= TREE_OPERAND (op1
, 0);
644 op1
= build1 (VIEW_CONVERT_EXPR
, upc_pts_rep_type_node
, op1
);
645 if (is_eq_op
&& has_phase
)
647 /* Mask off the phase value. */
649 fold_build1_loc (loc
, BIT_NOT_EXPR
, upc_pts_rep_type_node
,
650 build_binary_op (loc
, LSHIFT_EXPR
,
652 upc_phase_shift_node
, 0));
653 op0
= build_binary_op (loc
, BIT_AND_EXPR
, op0
, phase_mask
, 0);
654 op1
= build_binary_op (loc
, BIT_AND_EXPR
, op1
, phase_mask
, 0);
659 const tree ptr_diff
= build_binary_op (loc
, MINUS_EXPR
,
662 op1
= build_int_cst (TREE_TYPE (op0
), 0);
664 TREE_OPERAND (exp
, 0) = op0
;
665 TREE_OPERAND (exp
, 1) = op1
;