OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
wn.cxx
Go to the documentation of this file.
1 /*
2 
3  Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved.
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of version 2 of the GNU General Public License as
7  published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it would be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13  Further, this software is distributed without any warranty that it is
14  free of the rightful claim of any third person regarding infringement
15  or the like. Any license provided herein, whether implied or
16  otherwise, applies only to this software file. Patent licenses, if
17  any, provided herein do not apply to combinations of this program with
18  other software, or any other product whatsoever.
19 
20  You should have received a copy of the GNU General Public License along
21  with this program; if not, write the Free Software Foundation, Inc., 59
22  Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 
24  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky,
25  Mountain View, CA 94043, or:
26 
27  http://www.sgi.com
28 
29  For further information regarding this notice, see:
30 
31  http://oss.sgi.com/projects/GenInfo/NoticeExplan
32 
33 */
34 
35 
36 /* ====================================================================
37  * ====================================================================
38  *
39  *
40  * Revision history:
41  * dd-mmm-94 - Original Version
42  *
43  * Description: Base Routines for tree nodes in WHIRL
44  *
45  * ====================================================================
46  * ====================================================================
47  */
48 #ifdef USE_PCH
49 #include "common_com_pch.h"
50 #endif /* USE_PCH */
51 #pragma hdrstop
52 #include <math.h>
53 #include <string.h> /* for memset() */
54 
55 #include "defs.h"
56 #include "stab.h"
57 #include "irbdata.h"
58 #include "wn.h"
59 #include "config_targ.h"
60 #include "wn_simp.h"
61 #include "wio.h"
62 #include "targ_const.h"
63 #include "const.h"
64 #include "strtab.h"
65 #include "config.h"
66 #ifdef BACK_END
67 #include "fb_whirl.h"
68 #include "tracing.h"
69 #endif /* BACK_END */
70 
71 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
72 #include "wn_util.h"
73 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
74 
75 #ifdef KEEP_WHIRLSTATS
76 INT32 whirl_num_allocated=0;
77 INT32 whirl_bytes_allocated=0;
78 INT32 whirl_num_deallocated=0;
79 INT32 whirl_bytes_deallocated=0;
80 
81 void whirlstats()
82 {
83  fprintf(stderr,"Num allocated = %d\nbytes allocated = %d\n",whirl_num_allocated,whirl_bytes_allocated);
84  fprintf(stderr,"Num deallocated = %d\nbytes deallocated = %d\n",whirl_num_deallocated,whirl_bytes_deallocated);
85 }
86 #endif
87 
91 
92 typedef enum {
94 } BTYPE;
95 
96 static struct winfo {
99  INT size:16;
100 } WINFO [MTYPE_LAST + 1] = {
101  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* UNKNOWN */
102  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_B */
103  INT_TYPE, UINT_TYPE, 1, /* MTYPE_I1 */
104  INT_TYPE, UINT_TYPE, 2, /* MTYPE_I2 */
105  INT_TYPE, UINT_TYPE, 4, /* MTYPE_I4 */
106  INT_TYPE, UINT_TYPE, 8, /* MTYPE_I8 */
107  UINT_TYPE, INT_TYPE, 1, /* MTYPE_U1 */
108  UINT_TYPE, INT_TYPE, 2, /* MTYPE_U2 */
109  UINT_TYPE, INT_TYPE, 4, /* MTYPE_U4 */
110  UINT_TYPE, INT_TYPE, 8, /* MTYPE_U8 */
111  FLOAT_TYPE, FLOAT_TYPE, 4, /* MTYPE_F4 */
112  FLOAT_TYPE, FLOAT_TYPE, 8, /* MTYPE_F8 */
113  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_F10*/
114  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_F16*/
115  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_STR*/
116  FLOAT_TYPE, FLOAT_TYPE, 16, /* MTYPE_FQ */
117  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_M */
118  COMPLEX_TYPE, COMPLEX_TYPE, 8, /* MTYPE_C4 */
119  COMPLEX_TYPE, COMPLEX_TYPE, 16, /* MTYPE_C8 */
120  COMPLEX_TYPE, COMPLEX_TYPE, 32, /* MTYPE_CQ */
121  UNKNOWN_TYPE, UNKNOWN_TYPE, 0, /* MTYPE_V */
122  INT_TYPE, UINT_TYPE, 0, /* MTYPE_BS */
123  UINT_TYPE, INT_TYPE, 4, /* MTYPE_A4 */
124  UINT_TYPE, INT_TYPE, 8 /* MTYPE_A8 */
125 };
126 
127 #define WTYPE_base_type(w) WINFO[w].base_type
128 #define WTYPE_comp_type(w) WINFO[w].comp_type
129 #define WTYPE_size(w) WINFO[w].size
130 
131 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
132 
133 BOOL FE_Address_Opt = TRUE;
134 BOOL FE_Store_Opt = TRUE;
135 BOOL FE_Cvtl_Opt = TRUE;
136 
137 extern "C" { WN * WN_COPY_Tree ( WN * ); }
138 
139 static UINT64 masks [] = { 0, 0xff, 0xffff, 0, 0xffffffffULL,
140  0, 0, 0, 0xffffffffffffffffULL };
141 
142 
143 static WN *
144 fe_combine_address_offset ( WN_OFFSET * offset, WN * addr )
145 {
146  WN * new_addr;
147  INT64 const_val;
148  INT32 i;
149 
150  if ( FE_Address_Opt == FALSE )
151  return addr;
152 
153  i = -1;
154  new_addr = addr;
155 
156  if ( WN_operator(addr) == OPR_ADD
157  || WN_operator(addr) == OPR_SUB ) {
158 
159  if ( WN_operator(WN_kid0(addr)) == OPR_INTCONST )
160  i = 0;
161 
162  else
163  if ( WN_operator(WN_kid1(addr)) == OPR_INTCONST )
164  i = 1;
165  }
166 
167  if ( i >= 0 ) {
168 
169  if ( WN_operator(addr) == OPR_ADD )
170  const_val = *offset + WN_const_val(WN_kid(addr,i));
171 
172  else
173  const_val = *offset - WN_const_val(WN_kid(addr,i));
174 
175  if ( const_val >= INT32_MIN && const_val <= INT32_MAX ) {
176 
177  *offset = const_val;
178  new_addr = WN_COPY_Tree ( WN_kid(addr,1-i) );
179  }
180  }
181 
182  return new_addr;
183 } /* fe_combine_address_offset */
184 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
185 
186 BOOL
188 {
189  TYPE_ID rtype = WN_rtype(wn);
190  return ( ( WTYPE_base_type(ltype) == WTYPE_base_type(rtype) )
191  || ( WTYPE_base_type(ltype) == WTYPE_comp_type(rtype) ) );
192 } /* Types_Are_Compatible */
193 
194 
195 /*-----------------------------------------------------------------------*/
196 BOOL
198 {
199  BOOL compatible;
200 
201 #if 0
202  /* Apparently the following is an overkill. Possibly there was a
203  frontend bug that has been fixed. Until we can come up with a test
204  case, we allow unsigned/signed to be compatible.
205  */
206 
207  /* if the formal is of UINT and actual is INT, stid could introduce */
208  /* problems hence return not compatible */
209  if ((WTYPE_base_type(ltype) == UINT_TYPE) &&
210  (WTYPE_base_type(rtype) == INT_TYPE))
211  return FALSE;
212 #endif
213 
214  /* if the base types are the same or the base type of the stid */
215  /* is of comparable type and size of lhs is */
216  /* greater than size of rhs then return true */
217  compatible = (((WTYPE_base_type(ltype) == WTYPE_base_type(rtype))
218  || (WTYPE_base_type(ltype) == WTYPE_comp_type(rtype)))
219  && (WTYPE_size(ltype) >= WTYPE_size(rtype)));
220 
221  return (compatible);
222 } /* IPO_Types_Are_Compatible */
223 
224 /* ---------------------------------------------------------------------- */
225 /* Is_Const_Parm: returns true iff for call_wn and a childIndex i,
226  the i-th formal to the function is a const parameter
227  eg f(const int &x), or f(const int *x)
228 */
229 /* ---------------------------------------------------------------------- */
230 /* doesn't seem like this is used anymore */
231 
232 
233 
234 /* ---------------------------------------------------------------------
235  * WN Free Lists
236  *
237  * Each WN_FREE_LIST is a list of WHIRL nodes of a certain size that have
238  * been freed by WN_Delete. Note that the node address stored is the
239  * WN_StartAddress (i.e., the address of the allocated object, which may
240  * not be the same as the WN * returned by the creator).
241  *
242  * TODO: Since I have very little time to implement this, the current
243  * implementation keeps free lists only for nodes of the two most common
244  * sizes. We should generalize this to other sizes later.
245  * ---------------------------------------------------------------------
246  */
247 
248 /* Use a field within the WN to link to next free WN.
249  * This lets us use WN as the representation of WN_FREE_LIST.
250  */
251 typedef WN * WN_FREE_LIST;
252 
253 /* ---------------------------------------------------------------------
254  * BOOL WN_FREE_LIST_Empty(WN_FREE_LIST *list)
255  *
256  * Is <list> empty?
257  * ---------------------------------------------------------------------
258  */
259 #define WN_FREE_LIST_Empty(list) (*(list) == NULL)
260 
261 /*
262  * provide a way to turn off free list
263  */
265 
266 void
268 {
269  use_free_list = FALSE;
270 }
271 
272 /* ---------------------------------------------------------------------
273  * void WN_FREE_LIST_Push(WN_FREE_LIST *list, WN *wn)
274  *
275  * Add <wn> (actually, WN_StartAddress(wn)) to the start of <list>.
276  * ---------------------------------------------------------------------
277  */
278 inline void WN_FREE_LIST_Push(WN_FREE_LIST *list, WN *wn)
279 {
280  STMT_WN *stmt_wn;
281  stmt_wn = (STMT_WN *) WN_StartAddress(wn);
282  WN_prev_free(stmt_wn) = (WN *)(*list);
283  *list = (WN_FREE_LIST)stmt_wn;
284 }
285 
286 /* ---------------------------------------------------------------------
287  * WN *WN_FREE_LIST_Pop(WN_FREE_LIST *list)
288  *
289  * Requires: WN_FREE_LIST_Empty(list) == FALSE
290  *
291  * Remove first item from <list> and return the item.
292  * ---------------------------------------------------------------------
293  */
294 inline WN *WN_FREE_LIST_Pop(WN_FREE_LIST *list)
295 {
296  STMT_WN *item = (STMT_WN *)(*list);
297  *list = (WN_FREE_LIST)WN_prev_free(item);
298  return (WN *)item;
299 }
300 
301 /* ---------------------------------------------------------------------
302  * WN_FREE_LIST *Which_WN_FREE_LIST(INT32 size)
303  *
304  * Return the appropriate free list for a node of the given <size>,
305  * or NULL if there is no appropriate list.
306  *
307  * See TODO in Free Lists description above for note about future work.
308  * ---------------------------------------------------------------------
309  */
310 
311 /* For now, only two lists of the common sizes. Note that freed expr
312  * nodes with two kids will end up on the free_stmt_list, which is fine.
313  * It's the size, not type, that's important when choosing the list.
314  */
316 
317 inline WN_FREE_LIST *Which_WN_FREE_LIST(INT32 size)
318 {
319  if (size == sizeof(WN)+2*sizeof(WN *))
320  return &free_stmt_list;
321  else if (size == sizeof(WN))
322  return &free_expr_list;
323  return NULL;
324 }
325 
326 
327 
328 /* ---------------------------------------------------------------------
329  * void WN_Mem_Push(void)
330  *
331  * Saves the WN memory state for later restoration by WN_Mem_Pop.
332  *
333  * ---------------------------------------------------------------------
334  */
335 
336 void WN_Mem_Push(void)
337 {
338  if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
339  MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
341  }
342  MEM_POOL_Push(WN_mem_pool_ptr);
343 }
344 
345 
346 
347 /* ---------------------------------------------------------------------
348  * void WN_Mem_Pop(void)
349  *
350  * Deallocates all WN nodes created since the last call to WN_Mem_Push.
351  *
352  * ---------------------------------------------------------------------
353  */
354 
355 void WN_Mem_Pop(void)
356 {
357  if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
358  MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
360  }
361  free_stmt_list = free_expr_list = NULL;
362  MEM_POOL_Pop(WN_mem_pool_ptr);
363 }
364 
365 
366 /* ---------------------------------------------------------------------
367  * void IPA_WN_Delete(WN_MAP_TAB *maptab, WN *wn)
368  *
369  * Free node <wn> and its associated maps.
370  * ---------------------------------------------------------------------
371  */
372 
373 #define MAX_CLEANUP_FNS 8
374 static void (*delete_cleanup_fns[MAX_CLEANUP_FNS])(WN *wn);
376 
377 void IPA_WN_Delete(WN_MAP_TAB *maptab, WN *wn)
378 {
379  UINT16 i;
380  WN_FREE_LIST *free_list;
381 
382  Is_True((WN_opcode(wn)),("Trying to delete WHIRL node with 0 opcode"));
383 
384  free_list = use_free_list ? Which_WN_FREE_LIST(WN_Size(wn)) : 0;
385 
386 
387 #ifdef KEEP_WHIRLSTATS
388  whirl_num_deallocated++;
389  whirl_bytes_deallocated += WN_Size(wn);
390 #endif
391 
392  /* Invoke cleanup functions.
393  */
394  for (i = 0; i < num_delete_cleanup_fns; i++)
395  (*delete_cleanup_fns[i])(wn);
396 
397  /* Add node to appropriate free list (if any).
398  */
399  if (free_list)
400  WN_FREE_LIST_Push(free_list, wn);
401 
402  /* Free maps */
403  WN_MAP_Add_Free_List(maptab, wn);
404 
405  /* For better error checking, set the opcode to an invalid one */
406 // WN_set_opcode(wn, OPCODE_UNKNOWN);
410 }
411 
412 
413 /* ---------------------------------------------------------------------
414  * void IPA_WN_DELETE_Tree(WN_MAP_TAB *maptab, WN *tree)
415  *
416  * Free node entire <tree> and its associated maps.
417  * ---------------------------------------------------------------------
418  */
419 
420 void IPA_WN_DELETE_Tree(WN_MAP_TAB *maptab, WN *tree)
421 {
422  WN *node;
423  INT i;
424 
425  if (tree) {
426  if (WN_opcode(tree) == OPC_BLOCK) {
427  node = WN_first(tree);
428  while (node != NULL) {
429  WN *next = WN_next(node);
430  IPA_WN_DELETE_Tree (maptab, node);
431  node = next;
432  }
433  } else
434  for (i = 0; i < WN_kid_count(tree); i++)
435  IPA_WN_DELETE_Tree(maptab, WN_kid(tree, i));
436 
437  IPA_WN_Delete(maptab, tree);
438  }
439 }
440 
441 
442 /* ---------------------------------------------------------------------
443  * void WN_Register_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
444  *
445  * See "wn.h" for interface description.
446  * ---------------------------------------------------------------------
447  */
448 
449 void WN_Register_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
450 {
451  UINT16 i;
452  for (i=0; i < num_delete_cleanup_fns; i++)
453  if (delete_cleanup_fns[i] == cleanup_fn)
454  return;
455  FmtAssert(num_delete_cleanup_fns < MAX_CLEANUP_FNS,
456  ("attempting to register too many WN_Delete cleanup functions"));
457  delete_cleanup_fns[num_delete_cleanup_fns++] = cleanup_fn;
458 }
459 
460 
461 /* ---------------------------------------------------------------------
462  * void WN_Remove_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
463  *
464  * See "wn.h" for interface description.
465  * ---------------------------------------------------------------------
466  */
467 
468 void WN_Remove_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
469 {
470  UINT16 i;
471 
472  for (i = 0; i < num_delete_cleanup_fns; i++)
473  if (delete_cleanup_fns[i] == cleanup_fn)
474  break;
475  if (i >= num_delete_cleanup_fns)
476  return;
478  for (; i < num_delete_cleanup_fns; i++)
480 }
481 
482 
483 /* ---------------------------------------------------------------------
484  * WN_MAP_ID New_Map_Id( void )
485  *
486  * Return the map_id for a new WN.
487  * ---------------------------------------------------------------------
488  */
489 #define New_Map_Id() ((WN_MAP_ID) (-1))
490 
491 /* ---------------------------------------------------------------------
492  * WN *WN_Create(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, mINT16 kid_count)
493  *
494  * Core create routine. Return a new <opr, rtype, desc> node with <kid_count>
495  * kids. <kid_count> must be consistent with <opcode>.
496  * ---------------------------------------------------------------------
497  */
498 
499 WN *
500 WN_Create (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, mINT16 kid_count)
501 {
502  OPCODE opcode = OPCODE_make_op (opr, rtype, desc);
503  INT16 next_prev_ptrs = (OPCODE_has_next_prev(opcode) ? 1 : 0);
504  INT16 size = (sizeof(WN) +
505  (sizeof(WN *) * (max(0,kid_count-2))) +
506  next_prev_ptrs * (sizeof(mUINT64) + (2 * sizeof(WN *))));
507  WN_FREE_LIST *free_list;
508  WN *wn;
509 
510  free_list = use_free_list ? Which_WN_FREE_LIST(size) : 0;
511 
512 #ifdef KEEP_WHIRLSTATS
513  whirl_num_allocated++;
514  whirl_bytes_allocated += size;
515 #endif
516 
517  Is_True(((OPCODE_nkids(opcode) == kid_count) ||
518  (OPCODE_nkids(opcode) == -1)),
519  ("Illegal number of kids for WN_Create"));
520 
521  /* Find the memory. First try a free list, then go to the MEM_POOL.
522  * Note: For safety, we use a memset'd MEM_POOL and memset new nodes
523  * popped from a free list, but clients should not be relying
524  * on uninitialized fields being zeroed.
525  */
526  if (free_list && !WN_FREE_LIST_Empty(free_list)) {
527  wn = WN_FREE_LIST_Pop(free_list);
528  memset(wn, '\0', size);
529  } else {
530  if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
531  MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
532  MEM_POOL_Push(WN_mem_pool_ptr);
534  }
535  wn = (WN *)MEM_POOL_Alloc(WN_mem_pool_ptr, size);
536  memset(wn, '\0', size);
537  }
538 
539  /* Some nodes have next and previous pointers grow off the bottom.
540  */
541  if (next_prev_ptrs) {
542  STMT_WN *stmt_wn;
543  stmt_wn = (STMT_WN *)wn;
544  wn = (WN *)&(WN_real_fields(stmt_wn));
545  }
546 
547  /* Finish initialization.
548  */
549  WN_set_operator(wn, opr);
550  WN_set_rtype(wn, rtype);
551  WN_set_desc(wn, desc);
552  WN_set_kid_count(wn, kid_count);
553  WN_map_id(wn) = New_Map_Id();
554 
555  return wn;
556 }
557 
558 WN *
560  mINT16 kid_count, WN *next, WN *prev,
561  ST_IDX st,INT32 label_number, INT32 num_entries,
562  TY_IDX ty, TY_IDX load_addr_ty, WN_OFFSET offset,
563  INT16 cvtl_bits, INT32 /* num_dim */,
564  WN_ESIZE element_size, INT64 const_value, UINT32 flag,
565  INTRINSIC intrinsic)
566 {
567  OPCODE opcode = OPCODE_make_op (opr, rtype, desc);
568  WN *wn;
569 
570 
571  wn = WN_Create(opcode,kid_count);
572  if (OPCODE_has_next_prev(opcode)) {
573  WN_next(wn) = next;
574  WN_prev(wn) = prev;
575  }
576  if (OPCODE_has_sym(opcode)) {
577  WN_st_idx(wn) = st;
578  }
579  if (OPCODE_has_label(opcode)) {
580  WN_label_number(wn) = label_number;
581  }
582  if (OPCODE_has_num_entries(opcode)) {
583  WN_num_entries(wn) = num_entries;
584  }
585  if (OPCODE_has_1ty(opcode)) {
586  WN_set_ty(wn,ty);
587  }
588  if (OPCODE_has_2ty(opcode)) {
589  WN_set_ty(wn,ty);
590  WN_set_load_addr_ty(wn,load_addr_ty);
591  }
592  if (OPCODE_has_offset(opcode)) {
593  WN_offset(wn) = offset;
594  }
595  if (OPCODE_has_bits(opcode)) {
596  WN_cvtl_bits(wn) = cvtl_bits;
597  }
598  /* Num_dim is now just a read-only quantity */
599 #if 0
600  if (OPCODE_has_ndim(opcode)) {
601  WN_num_dim(wn) = num_dim;
602  }
603 #endif
604  if (OPCODE_has_esize(opcode)) {
605  WN_element_size(wn) = element_size;
606  }
607  if (OPCODE_has_value(opcode)) {
608  WN_const_val(wn) = const_value;
609  }
610  if (OPCODE_has_flags(opcode)) {
611  WN_set_flag(wn,flag);
612  }
613  if (OPCODE_has_inumber(opcode)) {
614  WN_intrinsic(wn) = intrinsic;
615  }
616  return wn;
617 }
618 
619 /* ignore children and next-previous pointers, are the two nodes
620  * equivalent
621  */
622 BOOL WN_Equiv(WN *wn1, WN *wn2)
623 {
624  OPCODE opcode;
625 
626  opcode = WN_opcode(wn1);
627  if (opcode != WN_opcode(wn2)) return(FALSE);
628  if (opcode == OPC_BLOCK) return(TRUE);
629  if (WN_kid_count(wn1) != WN_kid_count(wn2)) return(FALSE);
630 
631  if (OPCODE_has_sym(opcode)) {
632  if (WN_st_idx(wn1) != WN_st_idx(wn2)) return(FALSE);
633  }
634  if (OPCODE_has_label(opcode)) {
635  if (WN_label_number(wn1) != WN_label_number(wn2)) return(FALSE);
636  }
637  if (OPCODE_has_num_entries(opcode)) {
638  if (WN_num_entries(wn1) != WN_num_entries(wn2)) return(FALSE);
639  }
640  if (OPCODE_has_1ty(opcode)) {
641  if (WN_ty(wn1) != WN_ty(wn2)) return(FALSE);
642  }
643  if (OPCODE_has_2ty(opcode)) {
644  if (WN_ty(wn1) != WN_ty(wn2)) return(FALSE);
645  if (WN_load_addr_ty(wn1) != WN_load_addr_ty(wn2)) return(FALSE);
646  }
647  if (OPCODE_has_offset(opcode)) {
648  if (WN_offset(wn1) != WN_offset(wn2)) return(FALSE);
649  }
650  if (OPCODE_has_bits(opcode)) {
651  if (WN_cvtl_bits(wn1) != WN_cvtl_bits(wn2)) return(FALSE);
652  }
653  if (OPCODE_has_ndim(opcode)) {
654  if (WN_num_dim(wn1) != WN_num_dim(wn2)) return(FALSE);
655  }
656  if (OPCODE_has_esize(opcode)) {
657  if (WN_element_size(wn1) != WN_element_size(wn2)) return(FALSE);
658  }
659  if (OPCODE_has_value(opcode)) {
660  if (WN_const_val(wn1) != WN_const_val(wn2)) return(FALSE);
661  }
662  if (OPCODE_has_flags(opcode)) {
663  if (WN_flag(wn1) != WN_flag(wn2)) return(FALSE);
664  }
665  if (OPCODE_has_inumber(opcode)) {
666  if (WN_intrinsic(wn1) != WN_intrinsic(wn2)) return(FALSE);
667  }
668 
669  return(TRUE);
670 }
671 
672 
673 /*
674  * Create hierarchical control flow nodes
675  *
676  */
677 
679 {
680  WN *wn;
681 
682  wn = WN_Create(OPC_BLOCK,0);
683  WN_first(wn) = WN_last(wn) = NULL;
684  return(wn);
685 }
686 
687 WN *WN_CreateDO(WN *index, WN *start, WN *end, WN *step, WN *body, WN *loop_info)
688 {
689  WN *wn;
690  INT nkids = 5;
691  if (loop_info != NULL) nkids++;
692 
693  Is_True(OPCODE_is_stmt(WN_opcode(start)),("Bad start in WN_CreateDO"));
694  Is_True(OPCODE_is_stmt(WN_opcode(step)),("Bad step in WN_CreateDO"));
695  Is_True(loop_info == NULL || WN_opcode(loop_info) == OPC_LOOP_INFO,
696  ("Bad loop_info in WN_CreateDO"));
697 /* TODO: can't find Boolean type
698  Is_True(WN_rtype(end)==Boolean_type,
699  ("Bad end in WN_CreateDO"));
700 */
701  Is_True(WN_opcode(body) == OPC_BLOCK,("Bad body in WN_CreateDO"));
702 
703  wn = WN_Create(OPC_DO_LOOP,nkids);
704  WN_index(wn) = index;
705  WN_start(wn) = start;
706  WN_end(wn) = end;
707  WN_step(wn) = step;
708  WN_do_body(wn) = body;
709  if (loop_info) WN_set_do_loop_info(wn, loop_info);
710 
711  return(wn);
712 }
713 
714 WN *WN_CreateDoWhile(WN *test, WN *body)
715 {
716  WN *wn;
717 
718  Is_True(WN_opcode(body) == OPC_BLOCK, ("Bad body in WN_CreateDoWhile"));
719 /* TODO: can't find Boolean type
720  Is_True(WN_rtype(test)==Boolean_type,
721  ("Bad test in WN_CreateDoWhile"));
722 */
723  wn = WN_Create(OPC_DO_WHILE,2);
724  WN_while_test(wn) = test;
725  WN_while_body(wn) = body;
726 
727  return(wn);
728 }
729 
730 WN *WN_CreateWhileDo(WN *test, WN *body)
731 {
732  WN *wn;
733 
734  Is_True(WN_opcode(body) == OPC_BLOCK, ("Bad body in WN_CreateWhileDo"));
735 /* TODO: can't find Boolean type
736  Is_True(WN_rtype(test)==Boolean_type,
737  ("Bad test in WN_CreateWhileDo"));
738 */
739  wn = WN_Create(OPC_WHILE_DO,2);
740  WN_while_test(wn) = test;
741  WN_while_body(wn) = body;
742 
743  return(wn);
744 }
745 
746 WN *WN_CreateIf(WN *test, WN *if_then, WN *if_else)
747 {
748  WN *wn;
749 
750  Is_True(WN_opcode(if_then) == OPC_BLOCK, ("Bad then in WN_CreateIf"));
751  Is_True(WN_opcode(if_else) == OPC_BLOCK, ("Bad else in WN_CreateIf"));
752 /* TODO: can't find Boolean type
753  Is_True(WN_rtype(test)==Boolean_type,
754  ("Bad test in WN_CreateIf"));
755 */
756  wn = WN_Create(OPC_IF,3);
757  WN_if_test(wn) = test;
758  WN_then(wn) = if_then;
759  WN_else(wn) = if_else;
760 
761  WN_Reset_If_Guard(wn);
762  return(wn);
763 }
764 
765 /*============================================================================
766  REGION handling routines
767 ============================================================================*/
768 
769 /* check if a region element (statement list, pragma list, or exit list) has
770  a block surrounding it, if not create one. Some lists may be NULL, in that
771  case return an empty block */
772 static WN *WN_block_element(WN *element)
773 {
774  if (element == NULL || WN_opcode(element) != OPC_BLOCK) {
775  WN *block = WN_CreateBlock();
776  if (element != NULL) {
777  WN_first(block) = element;
778  WN_last (block) = element;
779  WN_prev(element) = NULL;
780  WN_next(element) = NULL;
781  }
782  return block;
783  } else
784  return element;
785 }
786 
788 
789 extern "C" INT32
791 {
792  return ++last_region_id;
793 }
794 extern "C" INT32
796 {
797  return last_region_id;
798 }
799 
800 /* set maximum region id seen so far;
801  * special case 0 to mean reset region ids to 0 */
802 extern void
804 {
805  if (id == 0)
806  last_region_id = 0;
807  else
808  last_region_id = MAX(last_region_id,id);
809 }
810 
811 /* =======================================================================
812  *
813  * WN_CreateRegion
814  *
815  * body must be an SCF node.
816  * If body is not a block,
817  * Create a REGION whose kid is a BLOCK which contains body.
818  * If body is a BLOCK
819  * Create a REGION whose kid is body.
820  * Copy the linenum from body to the result.
821  *
822  * OPC_REGION
823  * / | \
824  * OPC_BLOCK OPC_BLOCK OPC_BLOCK
825  * exit list pragma list statement list
826  *
827  * region_id: pass in -1 for WN_CreateRegion to assign an unique region id,
828  * otherwise specify a valid region_id (0-N) for the region.
829  *
830  * =======================================================================
831  */
832 WN *
833 WN_CreateRegion (REGION_KIND kind, WN *body, WN *pragmas, WN *exits,
834  INT region_id, INITO_IDX ereg_supp)
835 {
836  WN *wn;
837 
838  Is_True( OPCODE_is_scf(WN_opcode(body)) , ("Bad body in WN_CreateRegion"));
839  wn = WN_Create(OPC_REGION,3); // 3 kids: exits, pragmas, statements
840  WN_Set_Linenum(wn,WN_Get_Linenum(body));
841 
842  WN_set_region_kind(wn, kind);
843  WN_set_region_id(wn, (region_id == -1) ? New_Region_Id() : region_id);
844  WN_region_body(wn) = WN_block_element(body);
845  WN_region_pragmas(wn) = WN_block_element(pragmas);
846  WN_region_exits(wn) = WN_block_element(exits);
847  WN_ereg_supp(wn) = ereg_supp;
848 
850 
851  return(wn);
852 }
853 
854 WN *WN_CreateRegionExit (INT32 label_number)
855 {
856  WN *wn;
857 
858  wn = WN_Create(OPC_REGION_EXIT,0);
859  WN_label_number(wn) = label_number;
860 
861  return(wn);
862 }
863 
864 // nkids is the number of function arguments
865 WN *
866 WN_CreateEntry (INT16 nkids, ST_IDX name, WN *body, WN *pragmas, WN *varrefs)
867 {
868  WN *wn;
869  wn = WN_Create (OPC_FUNC_ENTRY, nkids + 3);
870  WN_entry_name(wn) = name;
871  WN_func_body(wn) = body;
872  WN_func_pragmas(wn) = WN_block_element(pragmas);
873  WN_func_varrefs(wn) = WN_block_element(varrefs);
874  return wn;
875 }
876 
877 /*
878  * Create statement nodes
879  *
880  */
881 
882 // no st anymore in goto
883 WN *WN_CreateGoto(INT32 label_number)
884 {
885  WN *wn;
886 
887  wn = WN_Create(OPC_GOTO,0);
888  WN_label_number(wn) = label_number;
889 
890  return(wn);
891 }
892 
893 WN *WN_CreateGotoOuterBlock (INT32 label_number, SYMTAB_IDX label_level)
894 {
895  WN * wn;
897  WN_label_number(wn) = label_number;
898  WN_label_level(wn) = label_level;
899 
900  return wn;
901 } /* WN_CreateGotoOuterBlock */
902 
904 {
905  WN *wn;
906 
908  ("Bad addr in WN_CreateAgoto"));
909  wn = WN_Create(OPC_AGOTO,1);
910  WN_kid0(wn) = addr;
911 
912  return(wn);
913 }
914 
916 {
917  WN *wn;
918 
919  wn = WN_Create(OPC_ALTENTRY,0);
920  WN_st_idx(wn) = entry;
921 
922  return(wn);
923 }
924 
925 WN *WN_CreateTruebr(INT32 label_number, WN *exp)
926 {
927  WN *wn;
928 
930  ("Bad exp in WN_CreateTruebr"));
931  wn = WN_Create(OPC_TRUEBR,1);
932  WN_kid0(wn) = exp;
933  WN_label_number(wn) = label_number;
934 
935  return(wn);
936 }
937 
938 WN *WN_CreateFalsebr(INT32 label_number, WN *exp)
939 {
940  WN *wn;
941 
943  ("Bad exp in WN_CreateFalsebr"));
944  wn = WN_Create(OPC_FALSEBR,1);
945  WN_kid0(wn) = exp;
946  WN_label_number(wn) = label_number;
947 
948  return(wn);
949 }
950 
951 /* a return */
953 {
954  WN *wn;
955 
956  wn = WN_Create(OPC_RETURN,0);
957 
958  return(wn);
959 }
960 
962 {
963  WN *wn;
964 
965  wn = WN_Create (opr, rtype, desc, 1);
966  WN_kid0(wn) = val;
967 
968  return(wn);
969 }
970 
971 WN *
973  INT32 label_number, UINT32 label_flag, WN *loop_info)
974 {
975  WN *wn;
976  INT nkids = 0;
977  if (loop_info != NULL) nkids++;
978  Is_True(loop_info == NULL || WN_opcode(loop_info) == OPC_LOOP_INFO,
979  ("Bad loop_info in WN_CreateDO"));
980 
981  wn = WN_Create(OPC_LABEL, nkids);
982  WN_label_number(wn) = label_number;
983  WN_label_flag(wn) = label_flag;
984  if ( loop_info )
985  WN_set_label_loop_info(wn, loop_info);
986 
987  return(wn);
988 }
989 
990 WN *WN_CreateCompgoto(INT32 num_entries, WN *value,
991  WN *block, WN *deflt, INT32 last_label)
992 {
993  WN *wn;
994 
996  ("Bad value in WN_CreateCompgoto"));
997  Is_True(WN_opcode(block) == OPC_BLOCK,
998  ("Bad block in WN_CreateCompgoto"));
999  if (deflt) Is_True(WN_opcode(deflt) == OPC_GOTO,
1000  ("Bad deflt in WN_CreateCompgoto"));
1001  if (deflt) {
1002  wn = WN_Create(OPC_COMPGOTO,3);
1003  } else {
1004  wn = WN_Create(OPC_COMPGOTO,2);
1005  }
1006  WN_kid0(wn) = value;
1007  WN_kid(wn,1) = block;
1008  if (deflt) WN_kid(wn,2) = deflt;
1009  WN_num_entries(wn) = num_entries;
1010  WN_last_label(wn) = last_label;
1011 
1012  return(wn);
1013 }
1014 
1015 WN *WN_CreateSwitch(INT32 num_entries, WN *value,
1016  WN *block, WN *deflt, INT32 last_label)
1017 {
1018  WN *wn;
1019 
1021  ("Bad value in WN_CreateSwitch"));
1022  Is_True(WN_opcode(block) == OPC_BLOCK,
1023  ("Bad block in WN_CreateSwitch"));
1024  if (deflt) Is_True(WN_opcode(deflt) == OPC_GOTO,
1025  ("Bad deflt in WN_CreateSwitch"));
1026  if (deflt) {
1027  wn = WN_Create(OPC_SWITCH,3);
1028  } else {
1029  wn = WN_Create(OPC_SWITCH,2);
1030  }
1031  WN_switch_test(wn) = value;
1032  WN_switch_table(wn) = block;
1033  if (deflt) WN_switch_default(wn) = deflt;
1034  WN_num_entries(wn) = num_entries;
1035  WN_last_label(wn) = last_label;
1036 
1037 #ifdef FRONT_END
1039 #endif /* FRONT_END */
1040 
1041  return(wn);
1042 }
1043 
1044 WN *WN_CreateCasegoto (INT64 case_value, INT32 case_label)
1045 {
1046  WN *wn;
1047  wn = WN_Create(OPC_CASEGOTO,0);
1048  WN_const_val(wn) = case_value;
1049  WN_label_number(wn) = case_label;
1050  return wn;
1051 }
1052 
1053 WN *WN_CreateXgoto(INT32 num_entries, WN *value, WN *block, ST_IDX st)
1054 {
1055  WN *wn;
1056 
1058  ("Bad value in WN_CreateXgoto"));
1059  Is_True(WN_opcode(block) == OPC_BLOCK,
1060  ("Bad block in WN_CreateXgoto"));
1061  wn = WN_Create(OPC_XGOTO,2);
1062  WN_kid0(wn) = value;
1063  WN_kid(wn,1) = block;
1064  WN_st_idx(wn) = st;
1065  WN_num_entries(wn) = num_entries;
1066 
1067  return(wn);
1068 }
1069 
1070 WN *
1072  WN_OFFSET offset, TY_IDX ty, WN *value, WN *addr,
1073  UINT field_id)
1074 {
1075  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1076  WN *wn;
1078  WN_rtype(addr)==MTYPE_U8 ||
1079  WN_rtype(addr)==MTYPE_U4 ||
1080  WN_rtype(addr)==MTYPE_I8 ||
1081  WN_rtype(addr)==MTYPE_I4,
1082  ("Bad addr in WN_CreateIstore"));
1084  ("Bad value in WN_CreateIstore"));
1086  ("Bad return type in WN_CreateIstore"));
1087  Is_True(opr == OPR_ISTORE || opr == OPR_ISTBITS,
1088  ("Bad opcode in WN_CreateIstore"));
1089 
1090 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1091 
1092  addr = fe_combine_address_offset ( &offset, addr );
1093 
1094  UINT64 ty_size;
1095  if (field_id == 0) {
1096  ty_size = TY_size(TY_pointed(ty));
1097  }
1098  else {
1099  UINT tmp = 0;
1100  ty_size = TY_size(FLD_type(FLD_get_to_field(TY_pointed(ty),field_id,tmp)));
1101  }
1102 
1103  if ( FE_Cvtl_Opt ) {
1104 
1105  OPCODE value_opc;
1106 
1107  value_opc = WN_opcode(value);
1108 
1109  if ( ( ( WN_operator(value) == OPR_CVTL
1110  || WN_operator(value) == OPR_CVT )
1111  && WN_cvtl_bits(value) == ty_size * 8 )
1112  || ( ( value_opc == OPC_I4I8CVT
1113  || value_opc == OPC_I4U8CVT
1114  || value_opc == OPC_U4I8CVT
1115  || value_opc == OPC_U4U8CVT )
1116  && ty_size < 8 ) )
1117  value = WN_kid0(value);
1118  }
1119 
1120  if ( FE_Store_Opt
1121  && WN_operator(value) == OPR_BAND ) {
1122 
1123  UINT64 mask;
1124  WN * kid0;
1125  WN * kid1;
1126 
1127  mask = masks [ty_size];
1128  kid0 = WN_kid0(value);
1129  kid1 = WN_kid1(value);
1130 
1131  if ( WN_operator(kid0) == OPR_INTCONST
1132  && ( ( WN_const_val(kid0) & mask ) == mask ) )
1133  value = kid1;
1134 
1135  else
1136  if ( WN_operator(kid1) == OPR_INTCONST
1137  && ( ( WN_const_val(kid1) & mask ) == mask ) )
1138  value = kid0;
1139  }
1140 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
1141 
1142  wn = WN_SimplifyIstore(opc,offset,ty,field_id,value,addr);
1143 
1144  if (!wn) {
1145  wn = WN_Create(opc,2);
1146  WN_kid0(wn) = value;
1147  WN_kid1(wn) = addr;
1148  WN_store_offset(wn) = offset;
1149  WN_set_ty(wn,ty);
1150  WN_set_field_id(wn, field_id);
1151  }
1152  else {
1153  /* Parent pointer (if it exists) for returned node must be NULL */
1156  }
1157  }
1158 
1159  return(wn);
1160 }
1161 
1162 
1163 WN *
1165  WN_OFFSET offset, TY_IDX ty, WN *value, WN *addr,
1166  UINT field_id)
1167 {
1168  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1169  WN *wn;
1171  WN_rtype(addr)==MTYPE_U8 ||
1172  WN_rtype(addr)==MTYPE_U4 ||
1173  WN_rtype(addr)==MTYPE_I8 ||
1174  WN_rtype(addr)==MTYPE_I4,
1175  ("Bad addr in WN_CreatePstore"));
1177  ("Bad value in WN_CreatePstore"));
1179  ("Bad return type in WN_CreatePstore"));
1180  Is_True(opr == OPR_ISTORE ||opr == OPR_PSTORE|| opr == OPR_ISTBITS,
1181  ("Bad opcode in WN_CreatePstore"));
1182 
1183 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1184 
1185  addr = fe_combine_address_offset ( &offset, addr );
1186 
1187  UINT64 ty_size;
1188  if (field_id == 0) {
1189  ty_size = TY_size(TY_pointed(ty));
1190  }
1191  else {
1192  UINT tmp = 0;
1193  ty_size = TY_size(FLD_type(FLD_get_to_field(TY_pointed(ty),field_id,tmp)));
1194  }
1195 
1196  if ( FE_Cvtl_Opt ) {
1197 
1198  OPCODE value_opc;
1199 
1200  value_opc = WN_opcode(value);
1201 
1202  if ( ( ( WN_operator(value) == OPR_CVTL
1203  || WN_operator(value) == OPR_CVT )
1204  && WN_cvtl_bits(value) == ty_size * 8 )
1205  || ( ( value_opc == OPC_I4I8CVT
1206  || value_opc == OPC_I4U8CVT
1207  || value_opc == OPC_U4I8CVT
1208  || value_opc == OPC_U4U8CVT )
1209  && ty_size < 8 ) )
1210  value = WN_kid0(value);
1211  }
1212  if ( FE_Store_Opt
1213  && WN_operator(value) == OPR_BAND ) {
1214 
1215  UINT64 mask;
1216  WN * kid0;
1217  WN * kid1;
1218 
1219  mask = masks [ty_size];
1220  kid0 = WN_kid0(value);
1221  kid1 = WN_kid1(value);
1222 
1223  if ( WN_operator(kid0) == OPR_INTCONST
1224  && ( ( WN_const_val(kid0) & mask ) == mask ) )
1225  value = kid1;
1226 
1227  else
1228  if ( WN_operator(kid1) == OPR_INTCONST
1229  && ( ( WN_const_val(kid1) & mask ) == mask ) )
1230  value = kid0;
1231  }
1232 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_EN
1233 D_MFEF77) */
1234 
1235  wn = WN_SimplifyPstore(opc,offset,ty,field_id,value,addr);
1236 
1237  if (!wn) {
1238  wn = WN_Create(opc,2);
1239  WN_kid0(wn) = value;
1240  WN_kid1(wn) = addr;
1241  WN_store_offset(wn) = offset;
1242  WN_set_ty(wn,ty);
1243  WN_set_field_id(wn, field_id);
1244  }
1245  else {
1246  /* Parent pointer (if it exists) for returned node must be NULL */
1248  }
1249 
1250  return(wn);
1251 }
1252 
1253 
1254 WN *
1256  TY_IDX ty, WN *value, WN *addr1, WN *addr2)
1257 {
1258  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1259  WN *wn;
1260 
1262  ("Bad opcode in WN_CreateIstorex"));
1264  ("Bad value in WN_CreateIstorex"));
1266  ("Bad address 1 in WN_CreateIstorex"));
1268  ("Bad address 2 in WN_CreateIstorex"));
1269  wn = WN_Create (opr, rtype, desc, 3);
1270  WN_store_offset(wn) = 0;
1271  WN_kid0(wn) = value;
1272  WN_kid1(wn) = addr1;
1273  WN_kid(wn,2) = addr2;
1274  WN_set_ty(wn,ty);
1275  return(wn);
1276 }
1277 
1278 WN *WN_CreatePrefetchx(UINT32 flag, WN *addr1, WN *addr2)
1279 {
1280  WN *wn;
1281 
1283  ("Bad address 1 in WN_CreatePrefetchx"));
1285  ("Bad address 2 in WN_CreatePrefetchx"));
1286  wn = WN_Create(OPC_PREFETCHX,2);
1287  WN_kid0(wn) = addr1;
1288  WN_kid1(wn) = addr2;
1289  WN_set_flag(wn,flag);
1290  return(wn);
1291 }
1292 
1294  WN *value, WN *addr, WN *num_bytes)
1295 {
1296  WN *wn;
1297 
1299  WN_rtype(addr)==MTYPE_U8 ||
1300  WN_rtype(addr)==MTYPE_U4 ||
1301  WN_rtype(addr)==MTYPE_I8 ||
1302  WN_rtype(addr)==MTYPE_I4,
1303  ("Bad addr in WN_CreateMstore"));
1305  ("Bad value in WN_CreateMstore"));
1307  ("Bad num_bytes in WN_CreateMstore"));
1308 
1309 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1310 
1311  addr = fe_combine_address_offset ( &offset, addr );
1312 
1313 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
1314 
1315  wn = WN_Create(OPC_MSTORE,3);
1316  WN_kid0(wn) = value;
1317  WN_kid1(wn) = addr;
1318  WN_kid(wn,2) = num_bytes;
1319  WN_store_offset(wn) = offset;
1320  WN_set_ty(wn,ty);
1321 
1322 #ifdef FRONT_END
1324 #endif /* FRONT_END */
1325  return(wn);
1326 }
1327 
1328 /* Create a STID, note this needs the opcode since there are many */
1329 /* opcodes with the OPR_STID operator */
1330 WN *
1332  WN_OFFSET offset, ST* st, TY_IDX ty, WN *value, UINT field_id)
1333 {
1334  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1335  WN *wn;
1336  ST_IDX st_idx = ST_st_idx (st);
1337 
1339  ("Bad value in WN_CreateStid"));
1341  ("Bad return type in WN_CreateStid"));
1342  Is_True(opr == OPR_STID || opr == OPR_STBITS,
1343  ("Bad opcode in WN_CreateStid"));
1344 #ifdef FRONT_END
1345  Is_True(!((offset == 0) && (st == Int32_Preg ||
1346  st == Int64_Preg ||
1347  st == Float32_Preg ||
1348  st == Float64_Preg)),
1349  ("Preg offset 0 in WN_CreateStid"));
1350 #endif /* FRONT_END */
1351 
1352 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1353 
1354  UINT64 ty_size;
1355  if (field_id == 0) {
1356  ty_size = TY_size(ty);
1357  }
1358  else {
1359  UINT tmp = 0;
1360  ty_size = TY_size(FLD_type(FLD_get_to_field(ty, field_id, tmp)));
1361  }
1362 
1363  if (FE_Cvtl_Opt && ST_class(st) != CLASS_PREG ) {
1364 
1365  OPCODE value_opc;
1366 
1367  value_opc = WN_opcode(value);
1368 
1369  if ( ( ( WN_operator(value) == OPR_CVTL
1370  || WN_operator(value) == OPR_CVT )
1371  && WN_cvtl_bits(value) == ty_size * 8 )
1372  || ( ( value_opc == OPC_I4I8CVT
1373  || value_opc == OPC_I4U8CVT
1374  || value_opc == OPC_U4I8CVT
1375  || value_opc == OPC_U4U8CVT )
1376  && ty_size < 8 ) )
1377  value = WN_kid0(value);
1378  }
1379 
1380  if (FE_Store_Opt && ST_class(st) != CLASS_PREG &&
1381  WN_operator(value) == OPR_BAND ) {
1382 
1383  UINT64 mask;
1384  WN * kid0;
1385  WN * kid1;
1386 
1387  mask = masks [ty_size];
1388  kid0 = WN_kid0(value);
1389  kid1 = WN_kid1(value);
1390 
1391  if ( WN_operator(kid0) == OPR_INTCONST
1392  && ( ( WN_const_val(kid0) & mask ) == mask ) )
1393  value = kid1;
1394 
1395  else
1396  if ( WN_operator(kid1) == OPR_INTCONST
1397  && ( ( WN_const_val(kid1) & mask ) == mask ) )
1398  value = kid0;
1399  }
1400 
1401 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
1402 
1403  wn = WN_Create(opc,1);
1404  WN_kid0(wn) = value;
1405  WN_store_offset(wn) = offset;
1406  WN_st_idx(wn) = st_idx;
1407  WN_set_ty(wn,ty);
1408  WN_set_field_id(wn, field_id);
1409 
1410  return(wn);
1411 }
1412 
1413 WN *
1415  WN_OFFSET offset, ST* st, TY_IDX ty, WN *value, UINT field_id)
1416 {
1417  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1418  WN *wn;
1419  ST_IDX st_idx = ST_st_idx (st);
1420 
1422  ("Bad value in WN_CreatePStid"));
1424  ("Bad return type in WN_CreatePStid"));
1425  Is_True(opr == OPR_STID || opr == OPR_STBITS,
1426  ("Bad opcode in WN_CreatePStid"));
1427 #ifdef FRONT_END
1428  Is_True(!((offset == 0) && (st == Int32_Preg ||
1429  st == Int64_Preg ||
1430  st == Float32_Preg ||
1431  st == Float64_Preg)),
1432  ("Preg offset 0 in WN_CreatePStid"));
1433 #endif /* FRONT_END */
1434 
1435 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1436 
1437  UINT64 ty_size;
1438  if (field_id == 0) {
1439  ty_size = TY_size(ty);
1440  }
1441  else {
1442  UINT tmp = 0;
1443  ty_size = TY_size(FLD_type(FLD_get_to_field(ty, field_id, tmp)));
1444  }
1445 
1446  if (FE_Cvtl_Opt && ST_class(st) != CLASS_PREG ) {
1447 
1448  OPCODE value_opc;
1449 
1450  value_opc = WN_opcode(value);
1451 
1452  if ( ( ( WN_operator(value) == OPR_CVTL
1453  || WN_operator(value) == OPR_CVT )
1454  && WN_cvtl_bits(value) == ty_size * 8 )
1455  || ( ( value_opc == OPC_I4I8CVT
1456  || value_opc == OPC_I4U8CVT
1457  || value_opc == OPC_U4I8CVT
1458  || value_opc == OPC_U4U8CVT )
1459  && ty_size < 8 ) )
1460  value = WN_kid0(value);
1461  }
1462 
1463  if (FE_Store_Opt && ST_class(st) != CLASS_PREG &&
1464  WN_operator(value) == OPR_BAND ) {
1465 
1466  UINT64 mask;
1467  WN * kid0;
1468  WN * kid1;
1469 
1470  mask = masks [ty_size];
1471  kid0 = WN_kid0(value);
1472  kid1 = WN_kid1(value);
1473 
1474  if ( WN_operator(kid0) == OPR_INTCONST
1475  && ( ( WN_const_val(kid0) & mask ) == mask ) )
1476  value = kid1;
1477 
1478  else
1479  if ( WN_operator(kid1) == OPR_INTCONST
1480  && ( ( WN_const_val(kid1) & mask ) == mask ) )
1481  value = kid0;
1482  }
1483 
1484 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_E
1485 ND_MFEF77) */
1486 
1487  wn = WN_Create(opc,1);
1488  WN_kid0(wn) = value;
1489  WN_store_offset(wn) = offset;
1490  WN_st_idx(wn) = st_idx;
1491  WN_set_ty(wn,ty);
1492  WN_set_field_id(wn, field_id);
1493 
1494  return(wn);
1495 }
1496 
1497 
1498 WN *WN_CreatePrefetch(WN_OFFSET offset, UINT32 flag, WN *addr)
1499 {
1500  WN *wn;
1502  ("Bad addr in WN_CreatePrefetch"));
1503  wn = WN_Create(OPC_PREFETCH,1);
1504  WN_kid0(wn) = addr;
1505  WN_offset(wn) = offset;
1506  WN_set_flag(wn,flag);
1507  return(wn);
1508 }
1509 
1510 WN *WN_CreateIo(IOSTATEMENT iostatement, mINT16 kid_count)
1511 {
1512  WN *wn;
1513 
1514  Is_True(kid_count >= 1,("Bad kid_count in WN_CreateIo"));
1515  wn = WN_Create(OPC_IO,kid_count);
1516  WN_io_statement(wn) = iostatement;
1518 
1519  return(wn);
1520 }
1521 
1523 {
1524  WN *wn;
1525 
1526  wn = WN_Create(OPC_IO_ITEM,0);
1527  WN_io_item(wn) = ioitem;
1528  WN_set_ty(wn, ty);
1529 
1530  return(wn);
1531 }
1532 
1533 WN *WN_CreateIoItem1(IOITEM ioitem, WN *kid0, TY_IDX ty)
1534 {
1535  WN *wn;
1536 
1537  wn = WN_Create(OPC_IO_ITEM,1);
1538  WN_io_item(wn) = ioitem;
1539  WN_kid0(wn) = kid0;
1540  WN_set_ty(wn, ty);
1541 
1542  return(wn);
1543 }
1544 
1545 WN *WN_CreateIoItem2(IOITEM ioitem, WN *kid0, WN *kid1, TY_IDX ty)
1546 {
1547  WN *wn;
1548 
1549  wn = WN_Create(OPC_IO_ITEM,2);
1550  WN_io_item(wn) = ioitem;
1551  WN_kid0(wn) = kid0;
1552  WN_kid1(wn) = kid1;
1553  WN_set_ty(wn, ty);
1554 
1555  return(wn);
1556 }
1557 
1558 WN *WN_CreateIoItem3(IOITEM ioitem, WN *kid0, WN *kid1, WN *kid2, TY_IDX ty)
1559 {
1560  WN *wn;
1561 
1562  wn = WN_Create(OPC_IO_ITEM,3);
1563  WN_io_item(wn) = ioitem;
1564  WN_kid0(wn) = kid0;
1565  WN_kid1(wn) = kid1;
1566  WN_kid(wn,2) = kid2;
1567  WN_set_ty(wn, ty);
1568 
1569  return(wn);
1570 }
1571 
1572 WN *WN_CreateIoItemN(IOITEM ioitem, mINT16 kid_count, TY_IDX ty)
1573 {
1574  WN *wn;
1575 
1576  wn = WN_Create(OPC_IO_ITEM,kid_count);
1577  WN_io_item(wn) = ioitem;
1578  WN_set_ty(wn, ty);
1579 
1580  return(wn);
1581 }
1582 
1584 {
1585  WN *wn;
1586 
1588  ("Bad exp in WN_CreateEval"));
1589  wn = WN_Create(OPC_EVAL,1);
1590  WN_kid0(wn) = exp;
1591 
1592  return(wn);
1593 }
1594 
1595 WN *
1596 WN_CreatePragma (WN_PRAGMA_ID pragma_name, ST_IDX st, INT32 arg1, INT32 arg2)
1597 {
1598  WN *wn;
1599 
1600  wn = WN_Create(OPC_PRAGMA,0);
1601  WN_pragma(wn) = pragma_name;
1602  WN_st_idx(wn) = st;
1603  WN_pragma_flags(wn) = 0;
1604  WN_pragma_arg1(wn) = arg1;
1605  WN_pragma_arg2(wn) = arg2;
1606 
1607  return(wn);
1608 }
1609 
1610 WN *
1612  ST_IDX st,
1613  INT32 arg1,
1614  PREG_NUM asm_copyout_preg,
1615  UINT32 asm_opnd_num)
1616 {
1617  WN *wn;
1618 
1619  Is_True(pragma_name == WN_PRAGMA_ASM_CONSTRAINT,
1620  ("ASM_CONSTRAINT-specific CreatePragma can't be used for "
1621  "other pragmas"));
1622  wn = WN_Create(OPC_PRAGMA,0);
1623  WN_pragma(wn) = pragma_name;
1624  WN_st_idx(wn) = st;
1625  WN_pragma_flags(wn) = 0;
1626  WN_pragma_arg1(wn) = arg1;
1627  WN_set_pragma_asm_copyout_preg(wn, asm_copyout_preg);
1628  WN_set_pragma_asm_opnd_num(wn, asm_opnd_num);
1629 
1630  return(wn);
1631 }
1632 
1633 WN *WN_CreateXpragma(WN_PRAGMA_ID pragma_name, ST_IDX st, INT16 kid_count)
1634 {
1635  WN *wn;
1636 
1637  wn = WN_Create(OPC_XPRAGMA, kid_count);
1638  WN_pragma(wn) = pragma_name;
1639  WN_st_idx(wn) = st;
1640  WN_pragma_flags(wn) = 0;
1641  WN_pragma_arg64(wn) = 0;
1642 
1643  return(wn);
1644 }
1645 
1646 /*
1647  * Create expression nodes
1648  *
1649  */
1650 
1651 /* first the generic ones */
1652 
1654 {
1655  WN *wn;
1656 
1657  wn = WN_Create(opr, rtype, desc, 0);
1658 
1659  return(wn);
1660 }
1661 
1662 WN *WN_CreateExp1(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,WN *kid0)
1663 {
1664  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1665  WN *wn;
1666 
1668  ("Bad kid0 in WN_CreateExp1"));
1669 
1670  wn = WN_SimplifyExp1(opc, kid0);
1671  if (!wn) {
1672  wn = WN_Create(opr, rtype, desc, 1);
1673  WN_kid0(wn) = kid0;
1674  }
1675  else {
1676  /* Parent pointer (if it exists) for returned node must be NULL */
1679  }
1680  }
1681 
1682  return(wn);
1683 }
1684 
1685 WN *WN_CreateExp2(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, WN *kid0, WN *kid1)
1686 {
1687  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1688  WN *wn;
1689 
1691  ("Bad kid0 in WN_CreateExp2"));
1693  ("Bad kid1 in WN_CreateExp2"));
1694  wn = WN_SimplifyExp2(opc, kid0, kid1);
1695  if (!wn) {
1696  wn = WN_Create(opr,rtype,desc,2);
1697  WN_kid0(wn) = kid0;
1698  WN_kid1(wn) = kid1;
1699  }
1700  else {
1701  /* Parent pointer (if it exists) for returned node must be NULL */
1704  }
1705  }
1706 
1707  return(wn);
1708 }
1709 
1711  WN *kid0, WN *kid1, WN *kid2)
1712 {
1713  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1714  WN *wn;
1715 
1717  ("Bad kid0 in WN_CreateExp3"));
1719  ("Bad kid1 in WN_CreateExp3"));
1721  ("Bad kid2 in WN_CreateExp3"));
1722 
1723  wn = WN_SimplifyExp3(opc, kid0, kid1, kid2);
1724  if (!wn) {
1725  wn = WN_Create(opr,rtype,desc,3);
1726  WN_kid0(wn) = kid0;
1727  WN_kid1(wn) = kid1;
1728  WN_kid(wn,2) = kid2;
1729  }
1730  else {
1731  /* Parent pointer (if it exists) for returned node must be NULL */
1734  }
1735  }
1736 
1737  return(wn);
1738 }
1739 
1741  INT16 cvtl_bits, WN* kid0)
1742 {
1743  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1744  WN *wn;
1745 
1746  Is_True(OPCODE_operator(opc) == OPR_CVTL, ("Bad opcode in WN_CreateCvtl"));
1747 
1748  wn = WN_SimplifyCvtl(opc, cvtl_bits, kid0);
1749  if (!wn) {
1750  wn = WN_CreateExp1(opr, rtype, desc, kid0);
1751  WN_cvtl_bits(wn) = cvtl_bits;
1752  }
1753  else {
1754  /* Parent pointer (if it exists) for returned node must be NULL */
1757  }
1758  }
1759 
1760  return(wn);
1761 }
1762 
1763 WN *
1765  WN_OFFSET offset, TY_IDX ty,
1766  TY_IDX load_addr_ty, WN *addr, UINT field_id)
1767 {
1768  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1769  WN *wn;
1770 
1772  WN_rtype(addr) == MTYPE_U8 ||
1773  WN_rtype(addr) == MTYPE_U4 ||
1774  WN_rtype(addr) == MTYPE_I8 ||
1775  WN_rtype(addr) == MTYPE_I4,
1776  ("Bad addr in WN_CreateIload"));
1777 
1778  Is_True(opr == OPR_ILOAD || opr == OPR_ILDBITS,
1779  ("Bad opcode in WN_CreateIload"));
1780 
1781 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1782 
1783  addr = fe_combine_address_offset ( &offset, addr );
1784 
1785 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
1786 
1787  wn = WN_SimplifyIload(opc,offset,ty,field_id,load_addr_ty,addr);
1788  if (!wn) {
1789  wn = WN_CreateExp1(opr,rtype,desc,addr);
1790  WN_load_offset(wn) = offset;
1791  WN_set_ty(wn,ty);
1792  WN_set_load_addr_ty(wn,load_addr_ty);
1793  WN_set_field_id(wn, field_id);
1794  }
1795  else {
1796  /* Parent pointer (if it exists) for returned node must be NULL */
1799  }
1800  }
1801 
1802  return(wn);
1803 }
1804 
1805 WN *
1807  TY_IDX ty, TY_IDX load_addr_ty, WN *addr1,
1808  WN *addr2)
1809 {
1810  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1811  WN *wn;
1812 
1814  ("Bad opcode in WN_CreateIloadx"));
1815  Is_True(WN_operator(addr1) == OPR_LDID,
1816  ("Bad address1 in WN_CreateIloadx"));
1817  Is_True(WN_operator(addr2) == OPR_LDID,
1818  ("Bad address2 in WN_CreateIloadx"));
1819  wn = WN_CreateExp2(opr,rtype,desc,addr1,addr2);
1820  WN_load_offset(wn) = 0;
1821  WN_set_ty(wn,ty);
1822  WN_set_load_addr_ty(wn,load_addr_ty);
1823  return(wn);
1824 }
1825 
1826 
1827 WN *WN_CreateMload (WN_OFFSET offset, TY_IDX ty,WN *addr, WN *num_bytes)
1828 {
1829  WN *wn;
1830 
1832  WN_rtype(addr)==MTYPE_U8 ||
1833  WN_rtype(addr)==MTYPE_U4 ||
1834  WN_rtype(addr)==MTYPE_I8 ||
1835  WN_rtype(addr)==MTYPE_I4,
1836  ("Bad addr in WN_CreateMload"));
1837 
1838 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
1839 
1840  addr = fe_combine_address_offset ( &offset, addr );
1841 
1842 #endif /* (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77) */
1843 
1844  wn = WN_CreateExp2(OPC_MLOAD,addr,num_bytes);
1845  WN_load_offset(wn) = offset;
1846  WN_set_ty(wn,ty);
1847 
1848  return(wn);
1849 }
1850 
1851 
1852 
1853 
1854 WN *
1856  WN_OFFSET offset, ST_IDX st, TY_IDX ty, UINT field_id)
1857 {
1858  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1859  WN *wn;
1860 
1861  Is_True (opr == OPR_LDID || opr == OPR_LDBITS,
1862  ("Bad opcode in WN_CreateLdid"));
1863 
1864 #ifdef FRONT_END
1865  Is_True (!((offset == 0) && (&St_Table [st] == Int32_Preg ||
1866  &St_Table [st] == Int64_Preg ||
1867  &St_Table [st] == Float32_Preg ||
1868  &St_Table [st] == Float64_Preg)),
1869  ("Preg offset 0 in WN_CreateLdid"));
1870 #endif /* FRONT_END */
1871 
1872 
1873  wn = WN_Create(opr,rtype,desc,0);
1874  WN_load_offset(wn) = offset;
1875  WN_st_idx(wn) = st;
1876  WN_set_ty(wn,ty);
1877  WN_set_field_id(wn, field_id);
1878 
1879  return(wn);
1880 }
1881 
1882 
1884  WN_OFFSET offset, TY_IDX ty, ST_IDX st, UINT field_id)
1885 {
1886  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1887  WN *wn;
1888 
1890  ("Bad addr in WN_CreateLda"));
1892  ("Bad opcode in WN_CreateLda"));
1893  wn = WN_Create(opr,rtype,desc,0);
1894  WN_load_offset(wn) = offset;
1895  WN_st_idx(wn) = st;
1896  WN_set_ty(wn,ty);
1897  WN_set_field_id(wn, field_id);
1898 
1899  return(wn);
1900 }
1901 
1902 WN *
1904  WN_OFFSET offset, TY_IDX ty)
1905 {
1906  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1907  WN *wn;
1908 
1910  ("Bad addr in WN_CreateIlda"));
1912  ("Bad opcode in WN_CreateIlda"));
1913  wn = WN_Create(opr,rtype,desc,0);
1914  WN_load_offset(wn) = offset;
1915  WN_set_ty(wn,ty);
1916 
1917  return(wn);
1918 }
1919 
1920 
1922 {
1923  WN *wn;
1924 
1925  wn = WN_Create(OPC_IDNAME, 0);
1926  WN_idname_offset(wn) = offset;
1927  WN_st_idx(wn) = st;
1928 
1929  return(wn);
1930 }
1931 
1932 
1934 {
1935  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1936  WN *wn;
1937 
1939  ("Bad opcode in WN_CreateConst"));
1940  wn = WN_Create(opr,rtype,desc,0);
1941  WN_st_idx(wn) = st;
1942 
1943  return(wn);
1944 }
1945 
1946 WN *WN_CreateIntconst(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, INT64 const_val)
1947 {
1948  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1949  WN *wn;
1950 
1952  ("Bad opcode in WN_CreateIntconst"));
1953  wn = WN_Create(opr,rtype,desc,0);
1954  if (opc == OPC_U4INTCONST) {
1955  /* make sure that 32-bit value is sign-extended */
1956  UINT32 uval = const_val;
1957  INT32 sval = uval;
1958  WN_const_val(wn) = (INT64) sval;
1959  } else {
1960  WN_const_val(wn) = const_val;
1961  }
1962 
1963  return(wn);
1964 }
1965 
1967  WN *block, WN *value)
1968 {
1969  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1970  WN *wn;
1971 
1973  ("Bad value in WN_CreateComma"));
1974  Is_True(WN_opcode(block) == OPC_BLOCK,
1975  ("Bad block in WN_CreateComma"));
1976  wn = WN_Create(opr,rtype,desc,2);
1977  WN_kid0(wn) = block;
1978  WN_kid1(wn) = value;
1979 
1980 #ifdef FRONT_END
1982 #endif /* FRONT_END */
1983 
1984  return(wn);
1985 }
1986 
1988  WN *value, WN *block)
1989 {
1990  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
1991  WN *wn;
1992 
1994  ("Bad value in WN_CreateComma"));
1995  Is_True(WN_opcode(block) == OPC_BLOCK,
1996  ("Bad block in WN_CreateComma"));
1997  wn = WN_Create(opr,rtype,desc,2);
1998  WN_kid0(wn) = value;
1999  WN_kid1(wn) = block;
2000 
2001 #ifdef FRONT_END
2003 #endif /* FRONT_END */
2004 
2005  return(wn);
2006 }
2007 
2008 WN *WN_CreateAsm_Stmt (INT16 kid_count, char *asm_string)
2009 {
2010  WN *wn = WN_Create(OPC_ASM_STMT, kid_count);
2011 
2012  ST *asm_st = New_ST(CURRENT_SYMTAB);
2013  WN_st_idx(wn) = ST_st_idx(asm_st);
2014  ST_Init(asm_st,
2015  Str_To_Index (Save_Str(asm_string), Current_Strtab),
2016  CLASS_NAME,
2018  EXPORT_LOCAL,
2019  (TY_IDX) 0);
2020 
2021  return wn;
2022 }
2023 
2024 WN *WN_CreateAsm_Input (char *constraint_string,
2025  UINT32 opnd_num,
2026  WN *value)
2027 {
2028  WN *wn = WN_Create(OPC_ASM_INPUT, 1);
2029 
2030  ST *constraint_st = New_ST(CURRENT_SYMTAB);
2031  WN_st_idx(wn) = ST_st_idx(constraint_st);
2032  ST_Init(constraint_st,
2033  Str_To_Index (Save_Str(constraint_string), Current_Strtab),
2034  CLASS_NAME,
2036  EXPORT_LOCAL,
2037  (TY_IDX) 0);
2038 
2039  WN_kid0(wn) = value;
2040  WN_asm_opnd_num(wn) = opnd_num;
2041  return wn;
2042 }
2043 
2045 {
2046  WN *wn;
2047  wn = WN_Create(OPC_COMMENT,0);
2048 
2049  ST *comment_st = New_ST(CURRENT_SYMTAB);
2050  WN_st_idx(wn) = ST_st_idx(comment_st);
2051  ST_Init(comment_st,
2052  Str_To_Index (Save_Str(s), Current_Strtab),
2053  CLASS_NAME,
2055  EXPORT_LOCAL,
2056  (TY_IDX) 0);
2057 
2058  return wn;
2059 }
2060 
2062 {
2063  Is_True(WN_opcode(wn) == OPC_COMMENT, ("Bad opcode in WN_GetComment"));
2064  return ST_name_idx(WN_st(wn));
2065 }
2066 
2067 WN *WN_CopyNode (const WN* src_wn)
2068 {
2069  WN* wn;
2070  OPCODE opcode = WN_opcode(src_wn);
2071 
2072  if (src_wn == NULL) return NULL;
2073  wn = WN_Create (opcode, WN_kid_count(src_wn));
2074 
2075  WN_Copy_u1u2 (wn, src_wn);
2076  WN_Copy_u3 (wn, src_wn);
2077  WN_set_field_id(wn, WN_field_id(src_wn));
2078 
2079  if (opcode == OPC_REGION && WN_ereg_supp(src_wn) != (INITO_IDX) 0) {
2080  const INITO& src_ino = Inito_Table[WN_ereg_supp (src_wn)];
2081  const ST *st = Copy_ST (INITO_st (src_ino));
2082  WN_ereg_supp(wn) = New_INITO (st, src_ino.val);
2083  }
2084 
2085  if (OPCODE_has_next_prev(opcode)) {
2086  WN_linenum(wn) = WN_linenum(src_wn);
2087  }
2088 
2089  return(wn);
2090 }
2091 
2092 #if 0
2093 /* no one uses this currently */
2094 void IPA_WN_Move_Maps (WN_MAP_TAB *maptab, WN *dst, WN *src)
2095 {
2096  INT32 i;
2097 
2098  /* if the opcodes are in the same category, just move the map_id */
2099  if (OPCODE_mapcat(WN_opcode(dst)) == OPCODE_mapcat(WN_opcode(src))) {
2100  if (WN_map_id(dst) != WN_MAP_UNDEFINED) WN_MAP_Add_Free_List(maptab, dst);
2101  WN_map_id(dst) = WN_map_id(src);
2102  WN_map_id(src) = WN_MAP_UNDEFINED;
2103  return;
2104  }
2105 
2106  /* otherwise iterate through the mappings */
2107  for (i = 0; i < WN_MAP_MAX; i++) {
2108  if (maptab->_is_used[i]) {
2109  switch (maptab->_kind[i]) {
2110  case WN_MAP_KIND_VOIDP: {
2111  IPA_WN_MAP_Set(maptab, i, dst, IPA_WN_MAP_Get(maptab, i, src));
2112  break;
2113  }
2114  case WN_MAP_KIND_INT32: {
2115  IPA_WN_MAP32_Set(maptab, i, dst, IPA_WN_MAP32_Get(maptab, i, src));
2116  break;
2117  }
2118  case WN_MAP_KIND_INT64: {
2119  IPA_WN_MAP64_Set(maptab, i, dst, IPA_WN_MAP64_Get(maptab, i, src));
2120  break;
2121  }
2122  default:
2123  Is_True(FALSE, ("WN_Move_Maps: unknown map kind"));
2124  }
2125  }
2126  }
2127 
2128  WN_MAP_Add_Free_List(maptab, src);
2129  WN_map_id(src) = WN_MAP_UNDEFINED;
2130 }
2131 #endif
2132 
2134 {
2135  INT32 i;
2136  OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn));
2137  INT32 old_map_id = WN_map_id(wn);
2138  UINT c;
2139 
2140  if (old_map_id == WN_MAP_UNDEFINED)
2141  return;
2142 
2143  WN_MAP_Add_Free_List(src, wn);
2145  WN_MAP_Set_ID(dst,wn);
2146 
2147  /* iterate through the mappings */
2148  /* Note that we transfer all the maps that are live, not just the
2149  reserved ones. This is because we want to have all the maps when
2150  we start processing the child PU (Preopt and LNO are not run
2151  on the child again to recreate the maps so we save them here.) */
2152  for (i = 0; i < WN_MAP_MAX; i++) {
2153  if (src->_is_used[i]) {
2154 
2155  if (!dst->_is_used[i]) { /* Create the destination */
2156  dst->_is_used[i] = TRUE;
2157  for (c = 0; c < WN_MAP_CATEGORIES; c++) {
2158  dst->_map_size[c][i] = 0;
2159  dst->_mapping[c][i] = NULL;
2160  }
2161  dst->_pool[i] = src->_pool[i];
2162  dst->_kind[i] = src->_kind[i];
2163  }
2164 
2165  switch (src->_kind[i]) {
2166  case WN_MAP_KIND_VOIDP: {
2167  if (old_map_id < src->_map_size[category][i]) {
2168  IPA_WN_MAP_Set(dst, i, wn, src->_mapping[category][i][old_map_id]);
2169  }
2170  break;
2171  }
2172  case WN_MAP_KIND_INT32: {
2173  if (old_map_id < src->_map_size[category][i]) {
2174  IPA_WN_MAP32_Set(dst, i, wn,
2175  ((INT32*) src->_mapping[category][i])[old_map_id]);
2176  }
2177  break;
2178  }
2179  case WN_MAP_KIND_INT64: {
2180  if (old_map_id < src->_map_size[category][i]) {
2181  IPA_WN_MAP64_Set(dst, i, wn,
2182  ((INT64*) src->_mapping[category][i])[old_map_id]);
2183  }
2184  break;
2185  }
2186  default:
2187  Is_True(FALSE, ("IPA_WN_Move_Maps_PU: unknown map kind"));
2188  }
2189  }
2190  }
2191 
2192 }
2193 
2194 
2195 INT32
2196 WN_Size_and_StartAddress (WN *wn, void **StartAddress)
2197 {
2198  if (OPCODE_has_next_prev(WN_opcode(wn))) {
2199  *StartAddress = (void *)&(WN_prev(wn));
2200  return sizeof(WN) + sizeof(mUINT64) +
2201  (max (2, WN_kid_count(wn)) * sizeof(WN*));
2202  } else {
2203  *StartAddress = (void *) wn;
2204  return sizeof(WN) + max(0, WN_kid_count(wn) - 2) * sizeof(WN*);
2205  }
2206 
2207 }
2208 
2209 
2210 WN *WN_CreateLoopInfo (WN *induction, WN *trip, UINT16 trip_est, UINT16 depth, INT32 flags)
2211 {
2212  WN *wn;
2213  INT16 nkids = 0;
2214  if (induction != NULL) nkids++;
2215  if (trip != NULL) nkids++;
2216  Is_True(!(induction==NULL && trip != NULL),
2217  ("trip must be null if induction is null in WN_CreateLoopInfo"));
2218 
2219  wn = WN_Create (OPC_LOOP_INFO, nkids);
2220  WN_loop_trip_est(wn) = trip_est;
2221  WN_loop_depth(wn) = depth;
2222  WN_loop_flag(wn) = flags;
2223  if (induction) WN_set_loop_induction(wn, induction);
2224  if (trip) WN_set_loop_trip(wn, trip);
2225  return wn;
2226 }
2227 
2229 {
2230  WN *wn;
2231  wn = WN_Create (OPC_EXC_SCOPE_BEGIN, nkids);
2232  WN_ereg_supp(wn) = ereg_supp;
2233  WN_offset(wn) = id;
2234  return wn;
2235 }
2236 
2238 {
2239  WN *wn;
2240  wn = WN_Create (OPC_EXC_SCOPE_END, 0);
2241  WN_offset(wn) = id;
2242  return wn;
2243 }
2244 
2245 WN *WN_CreateBarrier (BOOL forward, INT16 nkids)
2246 {
2247  WN *wn;
2248  if (forward)
2249  wn = WN_Create (OPC_FORWARD_BARRIER, nkids);
2250  else
2251  wn = WN_Create (OPC_BACKWARD_BARRIER, nkids);
2252  return wn;
2253 }
2254 
2256 {
2257  WN *wn;
2258  wn = WN_Create (OPC_TRAP, 0);
2259  WN_offset(wn) = value;
2260  return wn;
2261 }
2262 
2263 WN *WN_CreateAssert (INT32 value, WN *condition)
2264 {
2265  WN *wn;
2266  wn = WN_Create (OPC_ASSERT, 1);
2267  WN_kid(wn,0) = condition;
2268  WN_offset(wn) = value;
2269  return wn;
2270 }
2271 
2273 {
2274 
2276  return WN_Intconst(ty, (INT64) 0);
2277  else
2278  return Make_Const(Targ_Conv(ty, Host_To_Targ (MTYPE_I4, 0)));
2279 }
2280 
2281 WN *WN_Tas(TYPE_ID rtype, TY_IDX ty, WN *l)
2282 {
2283  WN *tas;
2284 
2285  tas = WN_CreateExp1(OPR_TAS, rtype, MTYPE_V, l);
2286  /* The simplifier may have set this to something other than a TAS,
2287  so check before setting the TY */
2288  if (WN_operator_is(tas, OPR_TAS)) {
2289  WN_set_ty(tas, ty);
2290  }
2291 
2292  return tas;
2293 }
2294 
2295 /* ---------------------------------------------------------------------
2296  *
2297  * WN *WN_Create_Intrinsic(OPCODE opc, INTRINSIC intrinsic, INT32 n, WN *kids[])
2298  *
2299  * Create an intrinsic node, calling the simplifier if necessary
2300  * ---------------------------------------------------------------------
2301  */
2303  INTRINSIC intrinsic, INT32 n, WN *kids[])
2304 {
2305  OPCODE opc = OPCODE_make_op (opr, rtype, desc);
2306  WN *call;
2307  INT32 i;
2308 
2309  call = WN_SimplifyIntrinsic(opc, intrinsic, n, kids);
2310  if (!call) {
2311  call = WN_Create(opr, rtype, desc, n);
2312  WN_intrinsic(call) = intrinsic;
2313  for (i=0; i<n; i++) {
2314  WN_kid(call,i) = kids[i];
2315  }
2316  }
2317  else {
2318  /* Parent pointer (if it exists) for returned node must be NULL */
2321  }
2322  }
2323 
2324  return call;
2325 }
2326 
2327 WN *WN_CreateParm(TYPE_ID rtype, WN *parm_node, TY_IDX ty, UINT32 flag)
2328 {
2329  OPCODE op = OPCODE_make_op(OPR_PARM, rtype, MTYPE_V);
2330  WN *wn;
2331 
2332  if ( parm_node != NULL ) {
2333  if (op != OPC_VPARM) {
2334  Is_True( OPCODE_is_expression(WN_opcode(parm_node)),
2335  ("Bad parm_node in WN_CreateParm"));
2336  Is_True( Types_Are_Compatible (rtype, parm_node ),
2337  ("rtype and parm_node's rtype are different in WN_CreateParm"));
2338  }
2339  wn = WN_CreateExp1(op, parm_node);
2340  }
2341  else {
2342  Is_True( rtype == MTYPE_V,
2343  ("non-VOID type in WN_CreateParm with null parm_node") );
2344  wn = WN_CreateExp0(op);
2345  }
2346  WN_set_ty(wn, ty);
2347  WN_set_flag(wn, flag);
2348  return wn;
2349 }
2350 
2351 WN *WN_Intconst(TYPE_ID rtype, INT64 value)
2352 {
2353  return WN_CreateIntconst(OPR_INTCONST, rtype, MTYPE_V, value);
2354 }
2355 
2356 WN *WN_Ldid(TYPE_ID desc, WN_OFFSET offset, ST_IDX sym, TY_IDX align,
2357  UINT field_id)
2358 {
2359  TYPE_ID rtype= Mtype_comparison(desc);
2360 
2361  return WN_CreateLdid (OPR_LDID, rtype, desc, offset, sym, align, field_id);
2362 }
2363 
2364 WN *
2365 WN_RLdid (TYPE_ID rtype, TYPE_ID desc, WN_OFFSET offset, ST_IDX sym,
2366  TY_IDX align)
2367 {
2368  return WN_CreateLdid (OPR_LDID, rtype, desc, offset, sym, align);
2369 }
2370 
2372 {
2373  ST *preg = MTYPE_To_PREG(desc);
2374 
2375  return WN_Ldid(desc, pregno, preg, ST_type(preg));
2376 }
2377 
2378 WN *
2379 WN_Stid (TYPE_ID desc, WN_OFFSET offset, ST* sym, TY_IDX align, WN *value,
2380  UINT field_id)
2381 {
2382  return WN_CreateStid(OPR_STID, MTYPE_V, desc, offset, sym, align, value,
2383  field_id);
2384 }
2385 WN *
2386 WN_PStid (TYPE_ID desc, WN_OFFSET offset, ST* sym, TY_IDX align, WN *value,
2387  UINT field_id)
2388 {
2389  return WN_CreatePStid(OPR_STID, MTYPE_V, desc, offset, sym, align, value,
2390  field_id);
2391 }
2392 
2393 
2394 WN *WN_StidIntoPreg(TYPE_ID desc, WN_OFFSET offset, ST* preg, WN *value)
2395 {
2396  return WN_CreateStid(OPR_STID, MTYPE_V, desc, offset, preg, ST_type(preg), value);
2397 }
2398 
2399 
2400 /*
2401  * These are much needed higher level routines built on the WN_Create
2402  * to build WN. Most of them determine the opcode based on type information
2403  * supplied.
2404  *
2405  * For a more detailed description, see wn.h
2406  */
2407 
2408 
2409 WN *WN_Iload(TYPE_ID desc, WN_OFFSET offset, TY_IDX align, WN *addr,
2410  UINT field_id)
2411 {
2412  TY_IDX palign;
2413  TYPE_ID rtype= Mtype_comparison(desc);
2414  palign = Make_Pointer_Type (align);
2415 
2416  return WN_CreateIload (OPR_ILOAD, rtype, desc, offset, align, palign, addr,
2417  field_id);
2418 }
2419 
2420 WN *
2421 WN_RIload (TYPE_ID rtype, TYPE_ID desc, WN_OFFSET offset, TY_IDX align,
2422  WN *addr)
2423 {
2424  TY_IDX palign;
2425  palign = Make_Pointer_Type(align);
2426 
2427  return WN_CreateIload (OPR_ILOAD, rtype, desc, offset, align, palign, addr);
2428 }
2429 
2430 WN *
2431 WN_Pstore (TYPE_ID desc, WN_OFFSET offset, TY_IDX align, WN *addr, WN *value,
2432  UINT field_id)
2433 {
2434  return WN_CreatePstore (OPR_ISTORE, MTYPE_V, desc, offset, align, value, addr,
2435  field_id);
2436 }
2437 
2438 
2439 WN *
2440 WN_Istore (TYPE_ID desc, WN_OFFSET offset, TY_IDX align, WN *addr, WN *value,
2441  UINT field_id)
2442 {
2443  return WN_CreateIstore (OPR_ISTORE, MTYPE_V, desc, offset, align, value, addr,
2444  field_id);
2445 }
2446 
2447 WN *WN_Unary(OPERATOR opr, TYPE_ID rtype, WN *l)
2448 {
2449  return WN_CreateExp1(opr, rtype, MTYPE_V, l);
2450 }
2451 
2452 WN *WN_Binary(OPERATOR opr, TYPE_ID rtype, WN *l, WN *r)
2453 {
2454  return WN_CreateExp2(opr, rtype, MTYPE_V, l, r);
2455 }
2456 
2457 WN *WN_Ternary(OPERATOR opr, TYPE_ID rtype, WN *kid0, WN *kid1, WN *kid2)
2458 {
2459  return WN_CreateExp3(opr, rtype, MTYPE_V, kid0, kid1, kid2);
2460 }
2461 
2462 WN *
2463 WN_IloadLdid (TYPE_ID desc, WN_OFFSET offset, TY_IDX align, ST* sym,
2464  WN_OFFSET symOffset)
2465 {
2466  WN *ldid = WN_Ldid(Pointer_type, symOffset, sym, ST_type(sym));
2467 
2468  return WN_Iload(desc, offset, align, ldid);
2469 }
2470 
2471 WN *WN_Cvt(TYPE_ID desc, TYPE_ID rtype, WN *l)
2472 {
2473  return WN_CreateExp1(OPR_CVT, rtype, desc, l);
2474 }
2475 
2476 WN *WN_Trunc(TYPE_ID desc, TYPE_ID rtype, WN *l)
2477 {
2478  return WN_CreateExp1(OPR_TRUNC, rtype, desc, l);
2479 }
2480 
2481 WN *WN_Rnd(TYPE_ID desc, TYPE_ID rtype, WN *l)
2482 {
2483  return WN_CreateExp1(OPR_RND, rtype, desc, l);
2484 }
2485 
2486 WN *WN_Ceil(TYPE_ID desc, TYPE_ID rtype, WN *l)
2487 {
2488  return WN_CreateExp1(OPR_CEIL, rtype, desc, l);
2489 }
2490 
2491 WN *WN_Floor(TYPE_ID desc, TYPE_ID rtype, WN *l)
2492 {
2493  return WN_CreateExp1(OPR_FLOOR, rtype, desc, l);
2494 }
2495 
2496 WN *WN_Relational(OPERATOR opr, TYPE_ID rtype, WN *l, WN *r)
2497 {
2498  return WN_CreateExp2(opr, Boolean_type, rtype, l, r);
2499 }
2500 
2502 {
2503 
2504  switch(type)
2505  {
2506  case MTYPE_F4:
2507  case MTYPE_F8:
2508  case MTYPE_F16:
2509  case MTYPE_FQ:
2510  case MTYPE_C4:
2511  case MTYPE_C8:
2512  case MTYPE_CQ:
2513  {
2514  double val = pow( 2.0, n);
2515 
2516  return Make_Const (Host_To_Targ_Float (type, val));
2517  }
2518  default: /* integral constant */
2519  {
2520  INT64 one= 1;
2521  UINT64 val= one << n;
2522  Is_True(((0<=n) && (n <= 63)), ("invalid power of 2"));
2523  return WN_Intconst(type, val);
2524  }
2525  }
2526 
2527 }
2528 
2529 WN *WN_Floatconst( TYPE_ID type, double value)
2530 {
2531 
2532  switch(type)
2533  {
2534  case MTYPE_F4:
2535  case MTYPE_F8:
2536  case MTYPE_FQ:
2537  case MTYPE_F16:
2538  case MTYPE_C4:
2539  case MTYPE_C8:
2540  case MTYPE_CQ:
2541  return Make_Const (Host_To_Targ_Float (type, value));
2542  }
2543  Is_True(FALSE, ("expected floating const type"));
2544  return NULL;
2545 }
2546 
2548 {
2549  switch(type)
2550  {
2551  case MTYPE_I1:
2552  case MTYPE_U1:
2553  return WN_Intconst( Mtype_TransferSign(type, MTYPE_I4), 0x5a);
2554  case MTYPE_I2:
2555  case MTYPE_U2:
2556  return WN_Intconst( Mtype_TransferSign(type, MTYPE_I4), 0x5a5a);
2557  case MTYPE_I4:
2558  case MTYPE_U4:
2559  return WN_Intconst(type, 0xfffa5a5a);
2560  case MTYPE_I8:
2561  case MTYPE_U8:
2562  return WN_Intconst(type, 0xfffa5a5afffa5a5all);
2563  case MTYPE_F4:
2564  case MTYPE_F8:
2565  case MTYPE_FQ:
2566  case MTYPE_F16:
2567  case MTYPE_C4:
2568  case MTYPE_C8:
2569  case MTYPE_CQ:
2570  return Make_Const (Host_To_Targ_UV(type));
2571  case MTYPE_STR:
2572  case MTYPE_M:
2573  case MTYPE_V:
2574  case MTYPE_B:
2575  break;
2576  }
2577 
2578  Is_True(FALSE, ("expected Uninitialized Variable const type"));
2579  return NULL;
2580 }
2581 
2582 #define NBITMASK(x) ((1ll<<(x))-1)
2583 WN *WN_RotateIntconst(WN *tree, INT32 rotate)
2584 {
2585  TYPE_ID type= WN_rtype(tree);
2586  INT32 size= MTYPE_size_reg(type);
2587  UINT64 n= WN_const_val(tree);
2588  UINT64 t;
2589 
2590  Is_True(WN_operator_is(tree, OPR_INTCONST), ("expected INTCONST"));
2591 
2592  rotate= rotate % size;
2593 
2594  if (rotate>0)
2595  {
2596  UINT64 t= n & NBITMASK(rotate);
2597 
2598  n >>= rotate;
2599  n &= NBITMASK(size-rotate);
2600  n = n | (t << (size - rotate));
2601  WN_const_val(tree)= n;
2602  }
2603  else if (rotate < 0)
2604  {
2605  rotate= -rotate;
2606 
2607  t = n & ~NBITMASK(size - rotate);
2608  n <<= rotate;
2609  n &= NBITMASK(rotate);
2610  n = n | (t >> (size - rotate));
2611  WN_const_val(tree)= n;
2612  }
2613 
2614  return tree;
2615 }
2616 
2617 WN *WN_Inverse(TYPE_ID type, WN *tree)
2618 {
2619  /*
2620  * there are no integer recips.
2621  * there are no quad emulations for recip either
2622  */
2623  if (MTYPE_float(type))
2624  {
2625  if (MTYPE_is_quad(type)==FALSE && Recip_Allowed == TRUE)
2626  {
2627  return WN_Recip(type, tree);
2628  }
2629  return WN_Div(type, WN_Floatconst(type, 1.0), tree);
2630  }
2631  return WN_Div(type, WN_Intconst(type, 1), tree);
2632 }
2633 
2634 WN *
2635 WN_Lda (TYPE_ID rtype, WN_OFFSET ldaOffset, ST* sym, UINT field_id)
2636 {
2637  TY_IDX pty;
2638 
2639 
2640  TY_IDX ty;
2641 
2642  if (ST_class (sym) == CLASS_BLOCK)
2643  ty = Make_Align_Type (MTYPE_To_TY(rtype), STB_align(sym));
2644  else
2645  ty = ST_class (sym) == CLASS_FUNC ? ST_pu_type (sym) : ST_type(sym);
2646  Is_True (ty != 0, ("WN_lda(): NULL ty"));
2647  pty = Make_Pointer_Type (ty);
2648 
2649 
2650  return WN_CreateLda(OPR_LDA, rtype, MTYPE_V, ldaOffset, pty, sym, field_id);
2651 }
2652 
2653 WN *
2654 WN_LdaLabel (TYPE_ID rtype, INT32 label_number)
2655 {
2656  WN *wn;
2657  TY_IDX ty;
2659  wn = WN_Create(OPR_LDA_LABEL, rtype, MTYPE_V, 0);
2660  WN_label_number (wn) = label_number;
2661  WN_set_ty (wn, ty);
2662  return wn;
2663 } /* WN_LdaLabel */
2664 
2666 {
2667  WN *call;
2668 
2669  call = WN_Create(OPR_ICALL, rtype, desc, n);
2670  WN_set_ty(call,ty);
2671 
2672  return call;
2673 }
2674 
2675 /* ---------------------------------------------------------------------
2676  *
2677  * WN *WN_generic_call(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, INT32 n, ST *sym)
2678  *
2679  * generic for macros
2680  * WN_Call
2681  * WN_Piccall
2682  *
2683  * ---------------------------------------------------------------------
2684  */
2685 WN *
2687  ST_IDX sym)
2688 {
2689  WN *call;
2690 
2691  if (MTYPE_is_complex(rtype))
2692  rtype = Mtype_complex_to_real(rtype);
2693 
2694  if (MTYPE_is_complex(desc))
2695  desc = Mtype_complex_to_real(desc);
2696 
2697  call = WN_Create(opr, rtype, desc, n);
2698  WN_st_idx(call) = sym;
2699 
2700  return call;
2701 }
2702 
2703 void WN_CopyMap(WN *dst, WN_MAP map, const WN *src)
2704 {
2705  if ( map == WN_MAP_UNDEFINED )
2706  return;
2707 
2708  switch ( Current_Map_Tab->_kind[map] ) {
2709  case WN_MAP_KIND_VOIDP:
2710  WN_MAP_Set( map, dst, WN_MAP_Get( map, src ) );
2711  break;
2712  case WN_MAP_KIND_INT32:
2713  WN_MAP32_Set( map, dst, WN_MAP32_Get( map, src ) );
2714  break;
2715  case WN_MAP_KIND_INT64:
2716  WN_MAP64_Set( map, dst, WN_MAP64_Get( map, src ) );
2717  break;
2718  default:
2719  Is_True( FALSE, ("WN_CopyMap: unknown map kind") );
2720  }
2721 }
2722 
2723 
2724 /*----------------------------------------------------------------------
2725  * WN_Int_Type_Conversion( WN *wn, TYPE_ID to_type )
2726  *
2727  * returns original wn if no conversion is necessary
2728  * otherwise returns a CVT or CVTL WN as appropriate.
2729  *----------------------------------------------------------------------
2730  */
2731 
2732 extern WN *
2734 {
2735  /* infer the "from" type from the given whirl */
2736  TYPE_ID from_type = WN_rtype(wn);
2737 
2738  Is_True( from_type == MTYPE_I1 ||
2739  from_type == MTYPE_I2 ||
2740  from_type == MTYPE_I4 ||
2741  from_type == MTYPE_I8 ||
2742  from_type == MTYPE_U1 ||
2743  from_type == MTYPE_U2 ||
2744  from_type == MTYPE_U4 ||
2745  from_type == MTYPE_U8,
2746  ("WN_Int_Type_Conversion: bad from_type: %d\n", from_type) );
2747 
2748  /* quickie check */
2749  if ( from_type == to_type )
2750  return wn;
2751 
2752  /* pretty long-winded way to do it, but it's cleaner and faster than
2753  * any other way I could figure out.
2754  */
2755  switch ( to_type ) {
2756  case MTYPE_I1:
2757  switch ( from_type ) {
2758  case MTYPE_I1:
2759  return wn;
2760  case MTYPE_I2:
2761  case MTYPE_I4:
2762  case MTYPE_U1:
2763  case MTYPE_U2:
2764  case MTYPE_U4:
2765  return WN_CreateCvtl( OPC_I4CVTL, 8, wn );
2766  case MTYPE_I8:
2767  case MTYPE_U8:
2768  return WN_CreateCvtl( OPC_I8CVTL, 8, wn );
2769  } /* end to_type = I1 */
2770  case MTYPE_I2:
2771  switch ( from_type ) {
2772  case MTYPE_I1:
2773  case MTYPE_I2:
2774  return wn;
2775  case MTYPE_I4:
2776  case MTYPE_U1:
2777  case MTYPE_U2:
2778  case MTYPE_U4:
2779  return WN_CreateCvtl( OPC_I4CVTL, 16, wn );
2780  case MTYPE_I8:
2781  case MTYPE_U8:
2782  return WN_CreateCvtl( OPC_I8CVTL, 16, wn );
2783  } /* end to_type = I2 */
2784  case MTYPE_I4:
2785  switch ( from_type ) {
2786  case MTYPE_I1:
2787  case MTYPE_I2:
2788  case MTYPE_I4:
2789  case MTYPE_U1:
2790  case MTYPE_U2:
2791  case MTYPE_U4:
2792  return wn;
2793  case MTYPE_I8:
2794  case MTYPE_U8:
2795  return WN_Cvt( from_type, to_type, wn );
2796  } /* end to_type = I4 */
2797  case MTYPE_I8:
2798  switch ( from_type ) {
2799  case MTYPE_I1:
2800  case MTYPE_I2:
2801  case MTYPE_I4:
2802  case MTYPE_U1:
2803  case MTYPE_U2:
2804  case MTYPE_U4:
2805  return WN_Cvt( from_type, to_type, wn );
2806  case MTYPE_I8:
2807  case MTYPE_U8:
2808  return wn;
2809  } /* end to_type = I8 */
2810  case MTYPE_U1:
2811  switch ( from_type ) {
2812  case MTYPE_I1:
2813  return wn;
2814  case MTYPE_I2:
2815  case MTYPE_I4:
2816  case MTYPE_U1:
2817  case MTYPE_U2:
2818  case MTYPE_U4:
2819  return WN_CreateCvtl( OPC_U4CVTL, 8, wn );
2820  case MTYPE_I8:
2821  case MTYPE_U8:
2822  return WN_CreateCvtl( OPC_U8CVTL, 8, wn );
2823  } /* end to_type = U1 */
2824  case MTYPE_U2:
2825  switch ( from_type ) {
2826  case MTYPE_I1:
2827  case MTYPE_I2:
2828  case MTYPE_I4:
2829  case MTYPE_U4:
2830  return WN_CreateCvtl( OPC_U4CVTL, 16, wn );
2831  case MTYPE_U1:
2832  case MTYPE_U2:
2833  return wn;
2834  case MTYPE_I8:
2835  case MTYPE_U8:
2836  return WN_CreateCvtl( OPC_U8CVTL, 16, wn );
2837  } /* end to_type = U2 */
2838  case MTYPE_U4:
2839  switch ( from_type ) {
2840  case MTYPE_I1:
2841  case MTYPE_I2:
2842  case MTYPE_I4:
2843  case MTYPE_U1:
2844  case MTYPE_U2:
2845  case MTYPE_U4:
2846  return wn;
2847  case MTYPE_I8:
2848  case MTYPE_U8:
2849  return WN_Cvt( from_type, to_type, wn );
2850  } /* end to_type = U4 */
2851  case MTYPE_U8:
2852  switch ( from_type ) {
2853  case MTYPE_I1:
2854  case MTYPE_I2:
2855  case MTYPE_I4:
2856  case MTYPE_U1:
2857  case MTYPE_U2:
2858  case MTYPE_U4:
2859  return WN_Cvt( from_type, to_type, wn );
2860  case MTYPE_I8:
2861  case MTYPE_U8:
2862  return wn;
2863  } /* end to_type = U8 */
2864  default:
2865  FmtAssert( FALSE,
2866  ("WN_Int_Type_Conversion: bad to_type: %d\n", to_type) );
2867  return wn;
2868  }
2869 }
2870 
2871 /*----------------------------------------------------------------------
2872  * WN_Float_Type_Conversion( WN *wn, TYPE_ID to_type )
2873  *
2874  * returns original wn if no conversion is necessary
2875  * otherwise returns a CVT as appropriate.
2876  *----------------------------------------------------------------------
2877  */
2878 
2879 extern WN *
2881 {
2882  /* infer the "from" type from the given whirl */
2883  TYPE_ID from_type = WN_rtype(wn);
2884 
2885  Is_True( from_type == MTYPE_F4 ||
2886  from_type == MTYPE_F8 ||
2887  from_type == MTYPE_FQ,
2888  ("WN_Float_Type_Conversion: unexpected from_type: %d\n",from_type));
2889  Is_True( to_type == MTYPE_F4 ||
2890  to_type == MTYPE_F8 ||
2891  to_type == MTYPE_FQ,
2892  ("WN_Float_Type_Conversion: unexpected to_type: %d\n", to_type) );
2893 
2894  /* quickie check */
2895  if ( from_type == to_type )
2896  return wn;
2897  else
2898  return WN_Cvt( from_type, to_type, wn );
2899 }
2900 
2901 /*----------------------------------------------------------------------
2902  * WN_Type_Conversion( WN *wn, TYPE_ID to_type )
2903  *
2904  * returns original wn if no conversion is necessary
2905  * otherwise returns a CVT or CVTL WN as appropriate.
2906  *
2907  * NOTE that it may be necessary to add multiple conversions to get
2908  * from/to the given types, but this function handles that for you.
2909  *----------------------------------------------------------------------
2910  */
2911 
2912 extern WN *
2914 {
2915  /* infer the "from" type from the given whirl */
2916  TYPE_ID from_type = WN_rtype(wn);
2917  BOOL from_flt,to_flt; /* is type a floating type? */
2918 
2919  /* quickie check of no-op */
2920  if ( from_type == to_type )
2921  return wn;
2922 
2923  Is_True( from_type == MTYPE_I1 ||
2924  from_type == MTYPE_I2 ||
2925  from_type == MTYPE_I4 ||
2926  from_type == MTYPE_I8 ||
2927  from_type == MTYPE_U1 ||
2928  from_type == MTYPE_U2 ||
2929  from_type == MTYPE_U4 ||
2930  from_type == MTYPE_U8 ||
2931  from_type == MTYPE_F4 ||
2932  from_type == MTYPE_F8 ||
2933  from_type == MTYPE_FQ,
2934  ("WN_Type_Conversion: unexpected from_type: %d\n", from_type) );
2935  Is_True( to_type == MTYPE_I1 ||
2936  to_type == MTYPE_I2 ||
2937  to_type == MTYPE_I4 ||
2938  to_type == MTYPE_I8 ||
2939  to_type == MTYPE_U1 ||
2940  to_type == MTYPE_U2 ||
2941  to_type == MTYPE_U4 ||
2942  to_type == MTYPE_U8 ||
2943  to_type == MTYPE_F4 ||
2944  to_type == MTYPE_F8 ||
2945  to_type == MTYPE_FQ,
2946  ("WN_Type_Conversion: unexpected to_type: %d\n", to_type) );
2947 
2948  from_flt = MTYPE_is_float(from_type);
2949  to_flt = MTYPE_is_float(to_type);
2950 
2951  /* to or from floating point type? */
2952  if ( from_flt ) {
2953  if ( to_flt ) {
2954  /* both are floating point types, so bypass heavy-duty call */
2955  return WN_Cvt( from_type, to_type, wn );
2956  }
2957 
2958  /* from float to int */
2959  if ( MTYPE_size_min(to_type) >= 32/* bits */ ) {
2960  /* appropriately sized target, so just do the conversion */
2961  return WN_Cvt( from_type, to_type, wn );
2962  }
2963  else {
2964  /* need to first convert to 4-byte integer with correct sign */
2965  TYPE_ID tmp_to_type = Mtype_TransferSign( to_type, MTYPE_I4 );
2966  WN *tmp_wn = WN_Cvt( from_type, tmp_to_type, wn );
2967  /* ok, we have a 4-byte integer, so let the all-integer
2968  * code handle the conversion from this 4-byte thing to the
2969  * ultimate type
2970  */
2971  return WN_Int_Type_Conversion( tmp_wn, to_type );
2972  }
2973  }
2974  else if ( to_flt ) {
2975  /* from int to float */
2976  if ( MTYPE_size_min(from_type) >= 32/* bits */ ) {
2977  /* appropriately sized source, so just do the conversion */
2978  return WN_Cvt( from_type, to_type, wn );
2979  }
2980  else {
2981  /* need to first convert to appropriately sized integer */
2982  TYPE_ID tmp_to_type = Mtype_TransferSign( to_type, MTYPE_I4 );
2983  WN *tmp_wn = WN_Int_Type_Conversion( wn, tmp_to_type );
2984 
2985  /* and then convert that to float */
2986  return WN_Cvt( tmp_to_type, to_type, tmp_wn );
2987  }
2988  }
2989  else {
2990  /* all integers */
2991  return WN_Int_Type_Conversion( wn, to_type );
2992  }
2993 }
2994 
2995 
2996 WN *WN_Iloadx(TYPE_ID rtype, TY_IDX ty, TY_IDX addr_ty, WN *base, WN *index)
2997 {
2998  return WN_CreateIloadx(OPR_ILOADX, rtype, MTYPE_V, ty, addr_ty, base, index);
2999 }
3000 
3001 
3002 WN *WN_Istorex(TYPE_ID desc, TY_IDX ty, WN *value, WN *base, WN *index)
3003 {
3004  return WN_CreateIstorex(OPR_ISTOREX, MTYPE_V, desc, ty, value, base, index);
3005 }
3006 
3007 WN *WN_LdaString(char *str, WN_OFFSET ldaOffset, INT32 len)
3008 {
3009  TCON tc;
3010  ST *st;
3011 
3012  tc = Host_To_Targ_String(MTYPE_STRING, str, len);
3014  return WN_Lda (Pointer_type, ldaOffset, st);
3015 }
3016 
3017 
3018 WN*
3019 WN_CreateAffirm (WN* condition)
3020 {
3021  WN* wn;
3022  wn = WN_Create (OPR_AFFIRM, MTYPE_V, MTYPE_V, 1);
3023  WN_kid0(wn) = condition;
3024  return wn;
3025 } /* WN_CreateAffirm */
3026 
3027 WN*
3029 {
3030  WN* wn;
3032  WN_kid0(wn) = size;
3033  return wn;
3034 } /* WN_CreateAlloca */
3035 
3036 WN*
3038 {
3039  WN* wn;
3040  wn = WN_Create (OPR_DEALLOCA, MTYPE_V, MTYPE_V, nkids);
3041  return wn;
3042 } /* WN_CreateDealloca */
3043 
3044 WN*
3045 WN_CreateLdma (TYPE_ID rtype, WN_OFFSET offset, TY_IDX ty, ST_IDX st,
3046  UINT field_id)
3047 {
3048  WN *wn;
3049 
3050  wn = WN_Create (OPR_LDMA, rtype, MTYPE_V, 0);
3051  WN_load_offset(wn) = offset;
3052  WN_st_idx(wn) = st;
3053  WN_set_ty(wn,ty);
3054  WN_set_field_id(wn, field_id);
3055 
3056  return(wn);
3057 } /* WN_CreateLdma */
3058 
3059 
3060 // Traverse the tree and set the address saved bits appropriately.
3061 
3062 void
3064 {
3065  ST* st;
3066 
3067  switch (WN_operator (wn)) {
3068 
3069  case OPR_LDA:
3070  case OPR_LDMA:
3071 
3072  st = WN_st(wn);
3073 
3074  if ( ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_FUNC )
3075  Set_ST_addr_saved(st);
3076  break;
3077 
3078  case OPR_ARRAY:
3079 
3081  break;
3082 
3083  case OPR_LDID:
3084  case OPR_CONST:
3085  case OPR_ILOAD:
3086  case OPR_MLOAD:
3087  case OPR_INTCONST:
3088  case OPR_INTRINSIC_OP:
3089  case OPR_CALL:
3090  case OPR_EQ:
3091  case OPR_NE:
3092  case OPR_GT:
3093  case OPR_GE:
3094  case OPR_LT:
3095  case OPR_LE:
3096  case OPR_ALLOCA:
3097 
3098  break;
3099 
3100  case OPR_EVAL:
3101  case OPR_TAS:
3102  case OPR_CVT:
3103  case OPR_CVTL:
3104  case OPR_NEG:
3105  case OPR_ABS:
3106  case OPR_SQRT:
3107  case OPR_REALPART:
3108  case OPR_IMAGPART:
3109  case OPR_PAREN:
3110  case OPR_RND:
3111  case OPR_TRUNC:
3112  case OPR_CEIL:
3113  case OPR_FLOOR:
3114  case OPR_BNOT:
3115  case OPR_LNOT:
3116  case OPR_LOWPART:
3117  case OPR_HIGHPART:
3118  case OPR_MINPART:
3119  case OPR_MAXPART:
3120  case OPR_RECIP:
3121  case OPR_RSQRT:
3122  case OPR_PARM:
3123  case OPR_OPTPARM:
3124 
3126  break;
3127 
3128  case OPR_CSELECT:
3129 
3132  break;
3133 
3134  case OPR_SELECT:
3135  case OPR_ADD:
3136  case OPR_SUB:
3137  case OPR_MPY:
3138  case OPR_DIV:
3139  case OPR_MOD:
3140  case OPR_REM:
3141  case OPR_DIVREM:
3142  case OPR_MAX:
3143  case OPR_MIN:
3144  case OPR_MINMAX:
3145  case OPR_BAND:
3146  case OPR_BIOR:
3147  case OPR_BXOR:
3148  case OPR_BNOR:
3149  case OPR_LAND:
3150  case OPR_LIOR:
3151  case OPR_SHL:
3152  case OPR_ASHR:
3153  case OPR_LSHR:
3154  case OPR_COMPLEX:
3155  case OPR_HIGHMPY:
3156 
3159  break;
3160 
3161  case OPR_CAND:
3162  case OPR_CIOR:
3163 
3164  break;
3165 
3166  case OPR_COMMA:
3167 
3169  break;
3170 
3171  case OPR_RCOMMA:
3172 
3174  break;
3175 
3176  default:
3177 
3178  Fail_FmtAssertion ("WN_set_st_addr_saved not implemented for %s",
3179  OPERATOR_name (WN_operator (wn)));
3180  break;
3181  }
3182 } /* WN_set_st_addr_saved */
3183 
3184 // Traverse the tree and check whether it has side effects.
3185 
3186 BOOL
3188 {
3189  switch (WN_operator (wn)) {
3190 
3191  case OPR_ABS:
3192  case OPR_BNOT:
3193  case OPR_CEIL:
3194  case OPR_CVT:
3195  case OPR_CVTL:
3196  case OPR_FIRSTPART:
3197  case OPR_FLOOR:
3198  case OPR_HIGHPART:
3199  case OPR_LOWPART:
3200  case OPR_LNOT:
3201  case OPR_MAXPART:
3202  case OPR_MINPART:
3203  case OPR_NEG:
3204  case OPR_PAREN:
3205  case OPR_PARM:
3206  case OPR_OPTPARM:
3207  case OPR_RND:
3208  case OPR_RSQRT:
3209  case OPR_RECIP:
3210  case OPR_SECONDPART:
3211  case OPR_SQRT:
3212  case OPR_TAS:
3213  case OPR_TRUNC:
3214  case OPR_EXTRACT_BITS:
3215 
3216  return WN_has_side_effects (WN_kid0(wn));
3217 
3218  case OPR_ADD:
3219  case OPR_ASHR:
3220  case OPR_BAND:
3221  case OPR_BIOR:
3222  case OPR_BXOR:
3223  case OPR_BNOR:
3224  case OPR_DIV:
3225  case OPR_DIVREM:
3226  case OPR_EQ:
3227  case OPR_GT:
3228  case OPR_GE:
3229  case OPR_HIGHMPY:
3230  case OPR_LAND:
3231  case OPR_LE:
3232  case OPR_LIOR:
3233  case OPR_LSHR:
3234  case OPR_LT:
3235  case OPR_MAX:
3236  case OPR_MIN:
3237  case OPR_MINMAX:
3238  case OPR_MOD:
3239  case OPR_MPY:
3240  case OPR_NE:
3241  case OPR_PAIR:
3242  case OPR_REM:
3243  case OPR_SHL:
3244  case OPR_SUB:
3245  case OPR_XMPY:
3246  case OPR_COMPOSE_BITS:
3247 
3248  if (WN_has_side_effects (WN_kid0(wn)))
3249  return TRUE;
3250 
3251  return WN_has_side_effects (WN_kid1(wn));
3252 
3253  case OPR_SELECT:
3254  case OPR_MADD:
3255  case OPR_MSUB:
3256  case OPR_NMADD:
3257  case OPR_NMSUB:
3258 
3259  if (WN_has_side_effects (WN_kid0(wn)))
3260  return TRUE;
3261 
3262  if (WN_has_side_effects (WN_kid1(wn)))
3263  return TRUE;
3264 
3265  return WN_has_side_effects (WN_kid2(wn));
3266 
3267  case OPR_ARRAY:
3268 
3269  if (WN_has_side_effects (WN_kid0(wn)))
3270  return TRUE;
3271 
3272  else {
3273 
3274  INT32 n = (WN_kid_count (wn)) >> 1;
3275 
3276  for (INT32 i = n + 1; i <= 2 * n; i++) {
3277 
3278  if (WN_has_side_effects (WN_kid (wn, i)))
3279  return TRUE;
3280  }
3281 
3282  return FALSE;
3283  }
3284 
3285  case OPR_INTRINSIC_OP: {
3286 
3287  INT32 n = WN_kid_count (wn);
3288 
3289  for (INT32 i = 0; i < n; i++) {
3290 
3291  if (WN_has_side_effects (WN_kid (wn, i)))
3292  return TRUE;
3293  }
3294 
3295  return FALSE;
3296  }
3297 
3298  case OPR_LDID:
3299 
3300  if (TY_is_volatile (WN_ty(wn)))
3301  return (TRUE);
3302 
3303  return FALSE;
3304 
3305  case OPR_ILOAD:
3306  case OPR_ILOADX:
3307  case OPR_ILDBITS:
3308 
3310  return (TRUE);
3311 
3312  return WN_has_side_effects (WN_kid0(wn));
3313 
3314  case OPR_MLOAD:
3315 
3316  if (TY_is_volatile (WN_ty(wn)))
3317  return (TRUE);
3318 
3319  if (WN_has_side_effects (WN_kid0(wn)))
3320  return TRUE;
3321 
3322  return WN_has_side_effects (WN_kid1(wn));
3323 
3324  case OPR_CONST:
3325  case OPR_IDNAME:
3326  case OPR_INTCONST:
3327  case OPR_LDA:
3328  case OPR_LDMA:
3329 
3330  return FALSE;
3331 
3332  case OPR_ALLOCA:
3333 
3334  return TRUE;
3335 
3336  case OPR_CAND:
3337  case OPR_CIOR:
3338 
3339  return TRUE;
3340 
3341  case OPR_COMMA:
3342  case OPR_RCOMMA:
3343 
3344  return TRUE;
3345 
3346  case OPR_CSELECT:
3347 
3348  return TRUE;
3349 
3350  default:
3351 
3352  Fail_FmtAssertion ("WN_has_side_effects not implemented for %s",
3353  OPERATOR_name (WN_operator (wn)));
3354  return FALSE;
3355  }
3356 } /* WN_has_side_effects */
3357 
3358 
3359 WN *
3360 WN_Rrotate (TYPE_ID desc, WN *src, WN *cnt)
3361 {
3363  return WN_CreateExp2 (OPR_RROTATE, Mtype_comparison (desc), desc, src, cnt);
3364 } /* WN_Rotate */