111
|
1 /* brig-util.cc -- gccbrig utility functions
|
131
|
2 Copyright (C) 2016-2018 Free Software Foundation, Inc.
|
111
|
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
|
4 for General Processor Tech.
|
|
5
|
|
6 This file is part of GCC.
|
|
7
|
|
8 GCC is free software; you can redistribute it and/or modify it under
|
|
9 the terms of the GNU General Public License as published by the Free
|
|
10 Software Foundation; either version 3, or (at your option) any later
|
|
11 version.
|
|
12
|
|
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
16 for more details.
|
|
17
|
|
18 You should have received a copy of the GNU General Public License
|
|
19 along with GCC; see the file COPYING3. If not see
|
|
20 <http://www.gnu.org/licenses/>. */
|
|
21
|
|
22 #include <sstream>
|
|
23
|
|
24 #include "stdint.h"
|
|
25 #include "hsa-brig-format.h"
|
|
26 #include "brig-util.h"
|
|
27 #include "errors.h"
|
|
28 #include "diagnostic-core.h"
|
131
|
29 #include "print-tree.h"
|
111
|
30
|
|
31 bool
|
|
32 group_variable_offset_index::has_variable (const std::string &name) const
|
|
33 {
|
|
34 varname_offset_table::const_iterator i = m_group_offsets.find (name);
|
|
35 return i != m_group_offsets.end ();
|
|
36 }
|
|
37
|
|
38 /* Adds a new group segment variable. */
|
|
39
|
|
40 void
|
|
41 group_variable_offset_index::add (const std::string &name, size_t size,
|
|
42 size_t alignment)
|
|
43 {
|
|
44 size_t align_padding = m_next_group_offset % alignment == 0 ?
|
|
45 0 : (alignment - m_next_group_offset % alignment);
|
|
46 m_next_group_offset += align_padding;
|
|
47 m_group_offsets[name] = m_next_group_offset;
|
|
48 m_next_group_offset += size;
|
|
49 }
|
|
50
|
|
51 size_t
|
|
52 group_variable_offset_index::segment_offset (const std::string &name) const
|
|
53 {
|
|
54 varname_offset_table::const_iterator i = m_group_offsets.find (name);
|
|
55 gcc_assert (i != m_group_offsets.end ());
|
|
56 return (*i).second;
|
|
57 }
|
|
58
|
|
59 /* Return true if operand number OPNUM of instruction with OPCODE is an output.
|
|
60 False if it is an input. Some code reused from Martin Jambor's gcc-hsa
|
|
61 tree. */
|
|
62
|
|
63 bool
|
|
64 gccbrig_hsa_opcode_op_output_p (BrigOpcode16_t opcode, int opnum)
|
|
65 {
|
|
66 switch (opcode)
|
|
67 {
|
|
68 case BRIG_OPCODE_BR:
|
|
69 case BRIG_OPCODE_SBR:
|
|
70 case BRIG_OPCODE_CBR:
|
|
71 case BRIG_OPCODE_ST:
|
|
72 case BRIG_OPCODE_ATOMICNORET:
|
|
73 case BRIG_OPCODE_SIGNALNORET:
|
|
74 case BRIG_OPCODE_INITFBAR:
|
|
75 case BRIG_OPCODE_JOINFBAR:
|
|
76 case BRIG_OPCODE_WAITFBAR:
|
|
77 case BRIG_OPCODE_ARRIVEFBAR:
|
|
78 case BRIG_OPCODE_LEAVEFBAR:
|
|
79 case BRIG_OPCODE_RELEASEFBAR:
|
|
80 case BRIG_OPCODE_DEBUGTRAP:
|
|
81 return false;
|
|
82 default:
|
|
83 return opnum == 0;
|
|
84 }
|
|
85 }
|
|
86
|
|
87 unsigned
|
|
88 gccbrig_hsa_type_bit_size (BrigType16_t t)
|
|
89 {
|
|
90
|
|
91 unsigned pack_type = t & ~BRIG_TYPE_BASE_MASK;
|
|
92
|
|
93 if (pack_type == BRIG_TYPE_PACK_32)
|
|
94 return 32;
|
|
95 else if (pack_type == BRIG_TYPE_PACK_64)
|
|
96 return 64;
|
|
97 else if (pack_type == BRIG_TYPE_PACK_128)
|
|
98 return 128;
|
|
99
|
|
100 switch (t)
|
|
101 {
|
|
102 case BRIG_TYPE_NONE:
|
|
103 return 0;
|
|
104
|
|
105 case BRIG_TYPE_B1:
|
|
106 return 1;
|
|
107
|
|
108 case BRIG_TYPE_U8:
|
|
109 case BRIG_TYPE_S8:
|
|
110 case BRIG_TYPE_B8:
|
|
111 return 8;
|
|
112
|
|
113 case BRIG_TYPE_U16:
|
|
114 case BRIG_TYPE_S16:
|
|
115 case BRIG_TYPE_B16:
|
|
116 case BRIG_TYPE_F16:
|
|
117 return 16;
|
|
118
|
|
119 case BRIG_TYPE_U32:
|
|
120 case BRIG_TYPE_S32:
|
|
121 case BRIG_TYPE_B32:
|
|
122 case BRIG_TYPE_F32:
|
|
123 case BRIG_TYPE_U8X4:
|
|
124 case BRIG_TYPE_U16X2:
|
|
125 case BRIG_TYPE_S8X4:
|
|
126 case BRIG_TYPE_S16X2:
|
|
127 case BRIG_TYPE_F16X2:
|
|
128 case BRIG_TYPE_SIG32:
|
|
129 return 32;
|
|
130
|
|
131 case BRIG_TYPE_U64:
|
|
132 case BRIG_TYPE_S64:
|
|
133 case BRIG_TYPE_F64:
|
|
134 case BRIG_TYPE_B64:
|
|
135 case BRIG_TYPE_U8X8:
|
|
136 case BRIG_TYPE_U16X4:
|
|
137 case BRIG_TYPE_U32X2:
|
|
138 case BRIG_TYPE_S8X8:
|
|
139 case BRIG_TYPE_S16X4:
|
|
140 case BRIG_TYPE_S32X2:
|
|
141 case BRIG_TYPE_F16X4:
|
|
142 case BRIG_TYPE_F32X2:
|
|
143 case BRIG_TYPE_SIG64:
|
|
144 return 64;
|
|
145
|
|
146 case BRIG_TYPE_B128:
|
|
147 case BRIG_TYPE_U8X16:
|
|
148 case BRIG_TYPE_U16X8:
|
|
149 case BRIG_TYPE_U32X4:
|
|
150 case BRIG_TYPE_U64X2:
|
|
151 case BRIG_TYPE_S8X16:
|
|
152 case BRIG_TYPE_S16X8:
|
|
153 case BRIG_TYPE_S32X4:
|
|
154 case BRIG_TYPE_S64X2:
|
|
155 case BRIG_TYPE_F16X8:
|
|
156 case BRIG_TYPE_F32X4:
|
|
157 case BRIG_TYPE_F64X2:
|
|
158 return 128;
|
|
159
|
|
160 default:
|
|
161 printf ("HMM %d %x\n", t, t);
|
|
162 gcc_unreachable ();
|
|
163 }
|
|
164 }
|
|
165
|
|
166 /* gcc-hsa borrowed code ENDS. */
|
|
167
|
|
168 uint64_t
|
|
169 gccbrig_to_uint64_t (const BrigUInt64 &brig_type)
|
|
170 {
|
|
171 return (uint64_t (brig_type.hi) << 32) | uint64_t (brig_type.lo);
|
|
172 }
|
|
173
|
|
174 int
|
|
175 gccbrig_reg_size (const BrigOperandRegister *brig_reg)
|
|
176 {
|
|
177 switch (brig_reg->regKind)
|
|
178 {
|
|
179 case BRIG_REGISTER_KIND_CONTROL:
|
|
180 return 1;
|
|
181 case BRIG_REGISTER_KIND_SINGLE:
|
|
182 return 32;
|
|
183 case BRIG_REGISTER_KIND_DOUBLE:
|
|
184 return 64;
|
|
185 case BRIG_REGISTER_KIND_QUAD:
|
|
186 return 128;
|
|
187 default:
|
|
188 gcc_unreachable ();
|
|
189 break;
|
|
190 }
|
|
191 }
|
|
192
|
|
193 std::string
|
|
194 gccbrig_reg_name (const BrigOperandRegister *reg)
|
|
195 {
|
|
196 std::ostringstream strstr;
|
|
197 switch (reg->regKind)
|
|
198 {
|
|
199 case BRIG_REGISTER_KIND_CONTROL:
|
|
200 strstr << 'c';
|
|
201 break;
|
|
202 case BRIG_REGISTER_KIND_SINGLE:
|
|
203 strstr << 's';
|
|
204 break;
|
|
205 case BRIG_REGISTER_KIND_DOUBLE:
|
|
206 strstr << 'd';
|
|
207 break;
|
|
208 case BRIG_REGISTER_KIND_QUAD:
|
|
209 strstr << 'q';
|
|
210 break;
|
|
211 default:
|
|
212 gcc_unreachable ();
|
|
213 return "";
|
|
214 }
|
|
215 strstr << reg->regNum;
|
|
216 return strstr.str ();
|
|
217 }
|
|
218
|
|
219 std::string
|
|
220 gccbrig_type_name (BrigType16_t type)
|
|
221 {
|
|
222 switch (type)
|
|
223 {
|
|
224 case BRIG_TYPE_U8:
|
|
225 return "u8";
|
|
226 case BRIG_TYPE_U16:
|
|
227 return "u16";
|
|
228 case BRIG_TYPE_U32:
|
|
229 return "u32";
|
|
230 case BRIG_TYPE_U64:
|
|
231 return "u64";
|
|
232 case BRIG_TYPE_S8:
|
|
233 return "s8";
|
|
234 case BRIG_TYPE_S16:
|
|
235 return "s16";
|
|
236 case BRIG_TYPE_S32:
|
|
237 return "s32";
|
|
238 case BRIG_TYPE_S64:
|
|
239 return "s64";
|
|
240 default:
|
|
241 gcc_unreachable ();
|
|
242 break;
|
|
243 }
|
|
244 }
|
|
245
|
|
246 std::string
|
|
247 gccbrig_segment_name (BrigSegment8_t segment)
|
|
248 {
|
|
249 if (segment == BRIG_SEGMENT_GLOBAL)
|
|
250 return "global";
|
|
251 else if (segment == BRIG_SEGMENT_GROUP)
|
|
252 return "group";
|
|
253 else if (segment == BRIG_SEGMENT_PRIVATE)
|
|
254 return "private";
|
|
255 else
|
|
256 gcc_unreachable ();
|
|
257 }
|
|
258
|
|
259 bool
|
|
260 gccbrig_is_float_type (BrigType16_t type)
|
|
261 {
|
|
262 return (type == BRIG_TYPE_F32 || type == BRIG_TYPE_F64
|
|
263 || type == BRIG_TYPE_F16);
|
|
264 }
|
|
265
|
|
266 BrigType16_t
|
|
267 gccbrig_tree_type_to_hsa_type (tree tree_type)
|
|
268 {
|
|
269 if (INTEGRAL_TYPE_P (tree_type))
|
|
270 {
|
|
271 if (TYPE_UNSIGNED (tree_type))
|
|
272 {
|
|
273 switch (int_size_in_bytes (tree_type))
|
|
274 {
|
|
275 case 1:
|
|
276 return BRIG_TYPE_U8;
|
|
277 case 2:
|
|
278 return BRIG_TYPE_U16;
|
|
279 case 4:
|
|
280 return BRIG_TYPE_U32;
|
|
281 case 8:
|
|
282 return BRIG_TYPE_U64;
|
|
283 default:
|
|
284 break;
|
|
285 }
|
|
286 }
|
|
287 else
|
|
288 {
|
|
289 switch (int_size_in_bytes (tree_type))
|
|
290 {
|
|
291 case 1:
|
|
292 return BRIG_TYPE_S8;
|
|
293 case 2:
|
|
294 return BRIG_TYPE_S16;
|
|
295 case 4:
|
|
296 return BRIG_TYPE_S32;
|
|
297 case 8:
|
|
298 return BRIG_TYPE_S64;
|
|
299 default:
|
|
300 break;
|
|
301 }
|
|
302 }
|
|
303 }
|
|
304 else if (VECTOR_TYPE_P (tree_type))
|
|
305 {
|
|
306 tree element_type = TREE_TYPE (tree_type);
|
|
307 size_t element_size = int_size_in_bytes (element_type) * 8;
|
|
308 BrigType16_t brig_element_type;
|
|
309 switch (element_size)
|
|
310 {
|
|
311 case 8:
|
|
312 brig_element_type
|
|
313 = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U8 : BRIG_TYPE_S8;
|
|
314 break;
|
|
315 case 16:
|
|
316 brig_element_type
|
|
317 = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U16 : BRIG_TYPE_S16;
|
|
318 break;
|
|
319 case 32:
|
|
320 brig_element_type
|
|
321 = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U32 : BRIG_TYPE_S32;
|
|
322 break;
|
|
323 case 64:
|
|
324 brig_element_type
|
|
325 = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U64 : BRIG_TYPE_S64;
|
|
326 break;
|
|
327 default:
|
|
328 gcc_unreachable ();
|
|
329 }
|
|
330
|
|
331 BrigType16_t pack_type;
|
|
332 switch (int_size_in_bytes (tree_type) * 8)
|
|
333 {
|
|
334 case 32:
|
|
335 pack_type = BRIG_TYPE_PACK_32;
|
|
336 break;
|
|
337 case 64:
|
|
338 pack_type = BRIG_TYPE_PACK_64;
|
|
339 break;
|
|
340 case 128:
|
|
341 pack_type = BRIG_TYPE_PACK_128;
|
|
342 break;
|
|
343 default:
|
|
344 gcc_unreachable ();
|
|
345 }
|
|
346 return brig_element_type | pack_type;
|
|
347 }
|
|
348 gcc_unreachable ();
|
|
349 }
|
|
350
|
|
351 /* Returns true in case the operation is a "bit level" operation,
|
|
352 that is, not having operand type depending semantical differences. */
|
|
353
|
|
354 bool
|
|
355 gccbrig_is_bit_operation (BrigOpcode16_t opcode)
|
|
356 {
|
|
357 return opcode == BRIG_OPCODE_CMOV || opcode == BRIG_OPCODE_SHUFFLE
|
|
358 || opcode == BRIG_OPCODE_UNPACK || opcode == BRIG_OPCODE_UNPACKLO
|
|
359 || opcode == BRIG_OPCODE_UNPACKHI || opcode == BRIG_OPCODE_ST
|
|
360 || opcode == BRIG_OPCODE_PACK;
|
|
361 }
|
|
362
|
|
363 /* The program scope definition can be left external within the
|
|
364 kernel binary which means it must be defined by the host via
|
|
365 HSA runtime. For these we have special treatment:
|
|
366 Create additional pointer indirection when accessing the variable
|
|
367 value from kernel code through a generated pointer
|
|
368 __gccbrig_ptr_variable_name. The pointer value then can be set either
|
|
369 within the kernel binary (in case of a later linked in definition)
|
|
370 or from the host. */
|
|
371
|
|
372 bool
|
|
373 gccbrig_might_be_host_defined_var_p (const BrigDirectiveVariable *brigVar)
|
|
374 {
|
|
375 bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
|
|
376 return (brigVar->segment == BRIG_SEGMENT_GLOBAL
|
|
377 || brigVar->segment == BRIG_SEGMENT_READONLY) && !is_definition
|
|
378 && brigVar->linkage == BRIG_LINKAGE_PROGRAM
|
|
379 && (brigVar->allocation == BRIG_ALLOCATION_PROGRAM
|
|
380 || brigVar->allocation == BRIG_ALLOCATION_AGENT);
|
|
381 }
|
|
382
|
|
383 /* Produce a GENERIC type for the given HSA/BRIG type. Returns the element
|
|
384 type in case of vector instructions. */
|
|
385
|
|
386 tree
|
|
387 gccbrig_tree_type_for_hsa_type (BrigType16_t brig_type)
|
|
388 {
|
|
389 tree tree_type = NULL_TREE;
|
|
390
|
|
391 if (hsa_type_packed_p (brig_type))
|
|
392 {
|
|
393 /* The element type is encoded in the bottom 5 bits. */
|
|
394 BrigType16_t inner_brig_type = brig_type & BRIG_TYPE_BASE_MASK;
|
|
395
|
|
396 unsigned full_size = gccbrig_hsa_type_bit_size (brig_type);
|
|
397
|
|
398 if (inner_brig_type == BRIG_TYPE_F16)
|
|
399 return build_vector_type (gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16),
|
|
400 full_size / 16);
|
|
401
|
|
402 tree inner_type = gccbrig_tree_type_for_hsa_type (inner_brig_type);
|
|
403
|
|
404 unsigned inner_size = gccbrig_hsa_type_bit_size (inner_brig_type);
|
|
405 unsigned nunits = full_size / inner_size;
|
|
406 tree_type = build_vector_type (inner_type, nunits);
|
|
407 }
|
|
408 else
|
|
409 {
|
|
410 switch (brig_type)
|
|
411 {
|
|
412 case BRIG_TYPE_NONE:
|
|
413 tree_type = void_type_node;
|
|
414 break;
|
|
415 case BRIG_TYPE_B1:
|
|
416 tree_type = boolean_type_node;
|
|
417 break;
|
|
418 case BRIG_TYPE_S8:
|
|
419 case BRIG_TYPE_S16:
|
|
420 case BRIG_TYPE_S32:
|
|
421 case BRIG_TYPE_S64:
|
|
422 /* Ensure a fixed width integer. */
|
|
423 tree_type
|
|
424 = build_nonstandard_integer_type
|
|
425 (gccbrig_hsa_type_bit_size (brig_type), false);
|
|
426 break;
|
|
427 case BRIG_TYPE_U8:
|
|
428 return unsigned_char_type_node;
|
|
429 case BRIG_TYPE_U16:
|
|
430 case BRIG_TYPE_U32:
|
|
431 case BRIG_TYPE_U64:
|
|
432 case BRIG_TYPE_B8: /* Handle bit vectors as unsigned ints. */
|
|
433 case BRIG_TYPE_B16:
|
|
434 case BRIG_TYPE_B32:
|
|
435 case BRIG_TYPE_B64:
|
|
436 case BRIG_TYPE_B128:
|
|
437 case BRIG_TYPE_SIG32: /* Handle signals as integers for now. */
|
|
438 case BRIG_TYPE_SIG64:
|
|
439 tree_type = build_nonstandard_integer_type
|
|
440 (gccbrig_hsa_type_bit_size (brig_type), true);
|
|
441 break;
|
|
442 case BRIG_TYPE_F16:
|
|
443 tree_type = uint16_type_node;
|
|
444 break;
|
|
445 case BRIG_TYPE_F32:
|
|
446 /* TODO: make sure that the alignment of the float are at least as
|
|
447 strict than mandated by HSA, and conform to IEEE (like mandated
|
|
448 by HSA). */
|
|
449 tree_type = float_type_node;
|
|
450 break;
|
|
451 case BRIG_TYPE_F64:
|
|
452 tree_type = double_type_node;
|
|
453 break;
|
|
454 case BRIG_TYPE_SAMP:
|
|
455 case BRIG_TYPE_ROIMG:
|
|
456 case BRIG_TYPE_WOIMG:
|
|
457 case BRIG_TYPE_RWIMG:
|
|
458 {
|
|
459 /* Handle images and samplers as target-specific blobs of data
|
|
460 that should be allocated earlier on from the runtime side.
|
|
461 Create a void* that should be initialized to point to the blobs
|
|
462 by the kernel launcher. Images and samplers are accessed
|
|
463 via builtins that take void* as the reference. TODO: who and
|
|
464 how these arrays should be initialized? */
|
|
465 tree void_ptr = build_pointer_type (void_type_node);
|
|
466 return void_ptr;
|
|
467 }
|
|
468 default:
|
|
469 gcc_unreachable ();
|
|
470 break;
|
|
471 }
|
|
472 }
|
|
473
|
|
474 /* Drop const qualifiers. */
|
|
475 return tree_type;
|
|
476 }
|
131
|
477
|
|
478 /* Calculates numeric identifier for the HSA register REG.
|
|
479
|
|
480 Returned value is bound to [0, BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT]. */
|
|
481
|
|
482 size_t
|
|
483 gccbrig_hsa_reg_id (const BrigOperandRegister ®)
|
|
484 {
|
|
485 size_t offset = reg.regNum;
|
|
486 switch (reg.regKind)
|
|
487 {
|
|
488 case BRIG_REGISTER_KIND_QUAD:
|
|
489 offset
|
|
490 += BRIG_2_TREE_HSAIL_D_REG_COUNT + BRIG_2_TREE_HSAIL_S_REG_COUNT
|
|
491 + BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
|
492 break;
|
|
493 case BRIG_REGISTER_KIND_DOUBLE:
|
|
494 offset += BRIG_2_TREE_HSAIL_S_REG_COUNT + BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
|
495 break;
|
|
496 case BRIG_REGISTER_KIND_SINGLE:
|
|
497 offset += BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
|
498 case BRIG_REGISTER_KIND_CONTROL:
|
|
499 break;
|
|
500 default:
|
|
501 gcc_unreachable ();
|
|
502 break;
|
|
503 }
|
|
504 return offset;
|
|
505 }
|
|
506
|
|
507 std::string
|
|
508 gccbrig_hsa_reg_name_from_id (size_t reg_id)
|
|
509 {
|
|
510 char reg_name[32];
|
|
511 long unsigned int reg_hash = (long unsigned int) reg_id;
|
|
512 if (reg_hash < BRIG_2_TREE_HSAIL_C_REG_COUNT)
|
|
513 {
|
|
514 sprintf (reg_name, "$c%lu", reg_hash);
|
|
515 return reg_name;
|
|
516 }
|
|
517
|
|
518 reg_hash -= BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
|
519 if (reg_hash < BRIG_2_TREE_HSAIL_S_REG_COUNT)
|
|
520 {
|
|
521 sprintf (reg_name, "$s%lu", reg_hash);
|
|
522 return reg_name;
|
|
523 }
|
|
524
|
|
525 reg_hash -= BRIG_2_TREE_HSAIL_S_REG_COUNT;
|
|
526 if (reg_hash < BRIG_2_TREE_HSAIL_D_REG_COUNT)
|
|
527 {
|
|
528 sprintf (reg_name, "$d%lu", reg_hash);
|
|
529 return reg_name;
|
|
530 }
|
|
531
|
|
532 reg_hash -= BRIG_2_TREE_HSAIL_D_REG_COUNT;
|
|
533 if (reg_hash < BRIG_2_TREE_HSAIL_Q_REG_COUNT)
|
|
534 {
|
|
535 sprintf (reg_name, "$q%lu", reg_hash);
|
|
536 return reg_name;
|
|
537 }
|
|
538
|
|
539 gcc_unreachable ();
|
|
540 return "$??";
|
|
541 }
|
|
542
|
|
543 /* Prints statistics of register usage to stdout. */
|
|
544
|
|
545 void
|
|
546 gccbrig_print_reg_use_info (FILE *dump, const regs_use_index &info)
|
|
547 {
|
|
548 regs_use_index::const_iterator begin_it = info.begin ();
|
|
549 regs_use_index::const_iterator end_it = info.end ();
|
|
550 for (regs_use_index::const_iterator it = begin_it; it != end_it; it++)
|
|
551 {
|
|
552 std::string hsa_reg = gccbrig_hsa_reg_name_from_id (it->first);
|
|
553 printf ("%s:\n", hsa_reg.c_str ());
|
|
554 const reg_use_info &info = it->second;
|
|
555 typedef std::vector<std::pair<tree, size_t> >::const_iterator reg_use_it;
|
|
556 reg_use_it begin_it2 = info.m_type_refs.begin ();
|
|
557 reg_use_it end_it2 = info.m_type_refs.end ();
|
|
558 for (reg_use_it it2 = begin_it2; it2 != end_it2; it2++)
|
|
559 {
|
|
560 fprintf (dump, "(%lu) ", (long unsigned int) it2->second);
|
|
561 print_node_brief (dump, "", it2->first, 0);
|
|
562 fprintf (dump, "\n");
|
|
563 }
|
|
564 }
|
|
565 }
|