1 /*
2 * Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include "gbldefs.h"
19 #include "error.h"
20 #include "ll_structure.h"
21 #include "ll_write.h"
22 #include "global.h"
23 #include "x86.h"
24 #include "dwarf2.h"
25 #include "llutil.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29
30 #ifdef OMP_OFFLOAD_LLVM
31 #include "ll_builder.h"
32 #endif
33
34 #define SPACES " "
35
36 #ifdef TARGET_POWER
37 #define POWER_STACK_32_BIT_NAN "2146959359" /* 0x7FF7FFFF */
38 /* Two consecutive 32 bit NaNs form a 64 bit SNan*/
39 #define POWER_STACK_64_BIT_NAN "9221120234893082623" /* 0x7FF7FFFF7FF7FFFF */
40 #endif
41
42 static LL_Function *called;
43 static int debug_calls = 0;
44 static int text_calls = 0;
45 static const char *ll_get_atomic_memorder(LL_Instruction *inst);
46
47 static const char *
ll_get_linkage_string(enum LL_LinkageType linkage)48 ll_get_linkage_string(enum LL_LinkageType linkage)
49 {
50 switch (linkage) {
51 case LL_INTERNAL_LINKAGE:
52 return "internal";
53 case LL_COMMON_LINKAGE:
54 return "common";
55 case LL_WEAK_LINKAGE:
56 return "weak";
57 case LL_EXTERNAL_LINKAGE:
58 return "external";
59 case LL_NO_LINKAGE:
60 break;
61 default:
62 break;
63 }
64 return "";
65 }
66
67 /**
68 \brief Write out the header of a module.
69
70 The header is: Module ID, target triple, and datalayout
71 */
72 void
ll_write_module_header(FILE * out,LLVMModuleRef module)73 ll_write_module_header(FILE *out, LLVMModuleRef module)
74 {
75 if (module->module_name[0])
76 fprintf(out, "; ModuleID = '%s'\n", module->module_name);
77 if (module->datalayout_string[0])
78 fprintf(out, "target datalayout = \"%s\"\n", module->datalayout_string);
79 if (module->target_triple[0])
80 fprintf(out, "target triple = \"%s\"\n", module->target_triple);
81 }
82
83 /**
84 \brief Write out definitions for named struct types in module.
85
86 If this function is called more than once, only the new types added since
87 the last call are written.
88 */
89 void
ll_write_user_structs(FILE * out,LLVMModuleRef module)90 ll_write_user_structs(FILE *out, LLVMModuleRef module)
91 {
92 unsigned i, j;
93
94 for (i = module->written_user_structs; i < module->num_user_structs; i++) {
95 LL_Value *val = module->user_structs.values[i];
96 LL_Type *type = val->type_struct;
97 int packed = type->flags & LL_TYPE_IS_PACKED_STRUCT;
98
99 /* TODO: Should we support opaque struct types too? */
100 if (type->sub_elements == 0) {
101 fprintf(out, "%s = type %s\n", type->str, packed ? "<{}>" : "{}");
102 continue;
103 }
104
105 fprintf(out, "%s = type %s{%s", type->str, packed ? "<" : "",
106 type->sub_types[0]->str);
107 for (j = 1; j < type->sub_elements; j++)
108 fprintf(out, ", %s", type->sub_types[j]->str);
109 fprintf(out, "}%s\n", packed ? ">" : "");
110 }
111
112 /* Avoid rewriting these structs if called again. */
113 module->written_user_structs = i;
114 }
115
116 static const char *
get_op_name(enum LL_Op op)117 get_op_name(enum LL_Op op)
118 {
119 switch (op) {
120 case LL_FPTRUNC:
121 return "fptrunc";
122 case LL_FPEXT:
123 return "fpext";
124 case LL_SEXT:
125 return "sext";
126 case LL_ZEXT:
127 return "zext";
128 case LL_TRUNC:
129 return "trunc";
130 case LL_BITCAST:
131 return "bitcast";
132 case LL_SITOFP:
133 return "sitofp";
134 case LL_UITOFP:
135 return "uitofp";
136 case LL_FPTOSI:
137 return "fptosi";
138 case LL_FPTOUI:
139 return "fptoui";
140 case LL_ADD:
141 return "add";
142 case LL_FADD:
143 return "fadd";
144 case LL_SUB:
145 return "sub";
146 case LL_FSUB:
147 return "fsub";
148 case LL_MUL:
149 return "mul";
150 case LL_FMUL:
151 return "fmul";
152 case LL_UDIV:
153 return "udiv";
154 case LL_SDIV:
155 return "sdiv";
156 case LL_SREM:
157 return "srem";
158 case LL_UREM:
159 return "urem";
160 case LL_FDIV:
161 return "fdiv";
162 case LL_OR:
163 return "or";
164 case LL_ASHR:
165 return "ashr";
166 case LL_LSHR:
167 return "lshr";
168 case LL_AND:
169 return "and";
170 case LL_XOR:
171 return "xor";
172 case LL_SHL:
173 return "shl";
174 case LL_INTTOPTR:
175 return "inttoptr";
176 case LL_PTRTOINT:
177 return "ptrtoint";
178 case LL_ICMP:
179 return "icmp";
180 case LL_FCMP:
181 return "fcmp";
182 case LL_ATOMICRMW:
183 return "atomicrmw";
184 case LL_CMPXCHG:
185 return "cmpxchg";
186 case LL_EXTRACTVALUE:
187 return "extractvalue";
188 case LL_INSERTVALUE:
189 return "insertvalue";
190 case LL_EXTRACTELEM:
191 return "extractelement";
192 case LL_INSERTELEM:
193 return "insertelement";
194 case LL_FNEG:
195 return "fneg";
196 default:
197 return "thisisnotacceptable";
198 }
199 }
200
201 static void
add_prototype(LL_Instruction * instruction)202 add_prototype(LL_Instruction *instruction)
203 {
204 LL_Function *scan_function = called;
205 LL_Function *new_function;
206 LL_Value *function = instruction->operands[1];
207 int i;
208
209 if (function->data == NULL) {
210 fprintf(stderr, "Attempting to add prototype for function with no name.\n");
211 return;
212 }
213
214 while (scan_function != NULL) {
215 if (strcmp(scan_function->name, function->data) == 0) {
216 /* We've already prototyped this function. Exit. */
217 return;
218 }
219 scan_function = scan_function->next;
220 }
221 new_function = (LL_Function *)malloc(sizeof(LL_Function));
222 ll_set_function_num_arguments(new_function, instruction->num_operands - 2);
223 new_function->next = called;
224 new_function->name = function->data;
225 new_function->num_args = instruction->num_operands - 2;
226
227 new_function->return_type = function->type_struct;
228 called = new_function;
229
230 for (i = 2; i < instruction->num_operands; i++) {
231 new_function->arguments[i - 2] = instruction->operands[i];
232 }
233 }
234
235 static bool
defined_in_module(LL_Function * function,LLVMModuleRef module)236 defined_in_module(LL_Function *function, LLVMModuleRef module)
237 {
238 LL_Function *scan_function;
239 scan_function = module->first;
240 while (scan_function != NULL) {
241 if (strcmp(scan_function->name, function->name) == 0)
242 return true;
243 scan_function = scan_function->next;
244 }
245 return false;
246 }
247
248 static void
write_prototypes(FILE * out,LLVMModuleRef module)249 write_prototypes(FILE *out, LLVMModuleRef module)
250 {
251 LL_Function *cur_function = called;
252 int i;
253
254 while (cur_function != NULL) {
255 if (!defined_in_module(cur_function, module)) {
256 fprintf(out, "\ndeclare %s @%s(", cur_function->return_type->str,
257 cur_function->name);
258 for (i = 0; i < cur_function->num_args; i++) {
259 fprintf(out, "%s", cur_function->arguments[i]->type_struct->str);
260
261 if (i + 1 < cur_function->num_args) {
262 fprintf(out, ", ");
263 }
264 }
265 fprintf(out, ") nounwind");
266 }
267 cur_function = cur_function->next;
268 }
269 fprintf(out, "\n");
270 if (debug_calls) {
271 fprintf(out, "declare void @llvm.dbg.declare(metadata, metadata) nounwind "
272 "readnone\n");
273 fprintf(out, "declare void @llvm.dbg.value(metadata, i64, metadata) "
274 "nounwind readnone\n\n");
275 }
276
277 if (text_calls) {
278 fprintf(out, "declare i64 @llvm.nvvm.texsurf.handle.p1i64(metadata, i64 "
279 "addrspace(1)*) nounwind readnone\n");
280 }
281
282 for (i = 0; i < module->num_refs; i++) {
283 if (module->extern_func_refs[i] != NULL)
284 fprintf(out, "declare void %s()\n", module->extern_func_refs[i]->data);
285 }
286 }
287
288 static void
clear_prototypes(void)289 clear_prototypes(void)
290 {
291 LL_Function *scan_function = called;
292 LL_Function *next_function;
293
294 while (scan_function != NULL) {
295 free(scan_function->arguments);
296 next_function = scan_function->next;
297 free(scan_function);
298 scan_function = next_function;
299 }
300 called = NULL;
301 }
302
303 static void
render_bitcast(FILE * out,LL_Instruction * inst)304 render_bitcast(FILE *out, LL_Instruction *inst)
305 {
306 const char *cast_operand = inst->operands[1]->data;
307
308 if (inst->operands[1]->type_struct->data_type == LL_PTR &&
309 strcmp(inst->operands[1]->data, "0") == 0) {
310 /* Replace "0" with "null" */
311 cast_operand = "null";
312 }
313 fprintf(out, "%s%s = bitcast %s %s to %s", SPACES, inst->operands[0]->data,
314 inst->operands[1]->type_struct->str, cast_operand,
315 inst->operands[0]->type_struct->str);
316 }
317
318 static void
render_store(FILE * out,LL_Instruction * inst)319 render_store(FILE *out, LL_Instruction *inst)
320 {
321 const char *store_operand = inst->operands[0]->data;
322 char szatomic[25];
323 char szmemorder[128];
324 sprintf(szatomic, "");
325 sprintf(szmemorder, "");
326
327 if (inst->operands[0]->type_struct->data_type == LL_PTR &&
328 strcmp(inst->operands[0]->data, "0") == 0) {
329 /* Replace "0" with "null" */
330 store_operand = "null";
331 } else if (inst->operands[0]->type_struct->data_type == LL_FLOAT) {
332 if (strcmp(inst->operands[0]->data, "inf") == 0) {
333 store_operand = "0x7FF0000000000000";
334 } else if (strcmp(inst->operands[0]->data, "-inf") == 0) {
335 store_operand = "0xFFF0000000000000";
336 } else if (strcmp(inst->operands[0]->data, "nan") == 0) {
337 store_operand = "0x7FF8000000000000";
338 }
339 }
340 fprintf(out, "%sstore%s%s %s %s, %s %s %s", SPACES, szatomic,
341 (inst->flags & INST_VOLATILE) ? " volatile" : "",
342 inst->operands[0]->type_struct->str, store_operand,
343 inst->operands[1]->type_struct->str, inst->operands[1]->data,
344 szmemorder);
345
346 if (inst->num_operands >= 3)
347 fprintf(out, ", align %s", inst->operands[2]->data);
348 }
349
350 static const char *szatomic_opr[10] = {"none", "xchg", "add", "sub", "and",
351 "nand", "or", "xor", "max", "min"};
352 static const char *
ll_get_atomic_opr(LL_Instruction * inst)353 ll_get_atomic_opr(LL_Instruction *inst)
354 {
355 int flags = (inst->flags & ATOMIC_RMW_OP_FLAGS);
356 const char *szopr = NULL;
357 int idx = flags >> 13;
358
359 switch (flags) {
360 case ATOMIC_XCHG_FLAG:
361 case ATOMIC_ADD_FLAG:
362 case ATOMIC_SUB_FLAG:
363 case ATOMIC_AND_FLAG:
364 case ATOMIC_OR_FLAG:
365 case ATOMIC_XOR_FLAG:
366 case ATOMIC_MIN_FLAG:
367 case ATOMIC_MAX_FLAG:
368 szopr = szatomic_opr[idx];
369 break;
370 default:
371 assert(false, "unimplemented op in ll_get_atomic_opr", flags, ERR_Fatal);
372 }
373 return szopr;
374 }
375
376 static const char *szmemorder[7] = {"undef", "monotonic", "undef", "acquire",
377 "release", "acq_rel", "seq_cst"};
378 static const char *
ll_get_atomic_memorder(LL_Instruction * inst)379 ll_get_atomic_memorder(LL_Instruction *inst)
380 {
381 int instr_flags = inst->flags;
382 int idx = (instr_flags & ATOMIC_MEM_ORD_FLAGS) >> 18;
383 const char *memorder = NULL;
384 switch (instr_flags & ATOMIC_MEM_ORD_FLAGS) {
385 case ATOMIC_MONOTONIC_FLAG:
386 case ATOMIC_ACQUIRE_FLAG:
387 case ATOMIC_RELEASE_FLAG:
388 case ATOMIC_ACQ_REL_FLAG:
389 case ATOMIC_SEQ_CST_FLAG:
390 memorder = szmemorder[idx];
391 break;
392 default:
393 interr("Unexpected atomic mem ord flag: ",
394 instr_flags & ATOMIC_MEM_ORD_FLAGS, ERR_Severe);
395 }
396 return memorder;
397 }
398
399 void
ll_write_instruction(FILE * out,LL_Instruction * inst,LL_Module * module,int no_return)400 ll_write_instruction(FILE *out, LL_Instruction *inst, LL_Module *module, int no_return)
401 {
402 const char *opname;
403 int i;
404 int print_branch_target;
405
406 if (inst->flags & INST_CANCELED)
407 return;
408 print_branch_target = 0;
409 opname = get_op_name(inst->op);
410 switch (inst->op) {
411 case LL_ASM: {
412 if(inst->num_operands==2) {
413 fprintf(out, "%scall void asm sideeffect \"%s\", \"\"()", SPACES,
414 inst->operands[1]->data);
415 } else {
416 int noperands = inst->num_operands;
417 if(inst->operands[0]->type_struct->data_type!=LL_VOID)
418 fprintf(out, "%s%s = ", SPACES, inst->operands[0]->data);
419 else
420 fprintf(out, "%s", SPACES);
421 fprintf(out, "call %s asm sideeffect \"%s\", \"%s\"",
422 inst->operands[0]->type_struct->str,
423 inst->operands[1]->data, inst->operands[2]->data);
424 fprintf(out, "(");
425 for(i=3; i<noperands; i++) {
426 fprintf(out, "%s %s", inst->operands[i]->type_struct->str, inst->operands[i]->data);
427 if(i<(noperands-1))
428 fprintf(out, ",");
429 }
430 fprintf(out, ")");
431 }
432 }
433 break;
434 case LL_ATOMICRMW: {
435 const char *atomicopr;
436 const char *memorder;
437 atomicopr = ll_get_atomic_opr(inst);
438 memorder = ll_get_atomic_memorder(inst);
439 fprintf(out, "%s%s = %s %s %s %s, %s %s %s", SPACES,
440 inst->operands[0]->data, opname, atomicopr,
441 inst->operands[1]->type_struct->str, inst->operands[1]->data,
442 inst->operands[2]->type_struct->str, inst->operands[2]->data,
443 memorder);
444
445 } break;
446 case LL_CMPXCHG: {
447 const char *memorder;
448 memorder = ll_get_atomic_memorder(inst);
449 fprintf(out, "%s%s = %s %s %s, %s %s, %s %s %s", SPACES,
450 inst->operands[0]->data, opname,
451 inst->operands[1]->type_struct->str, inst->operands[1]->data,
452 inst->operands[2]->type_struct->str, inst->operands[2]->data,
453 inst->operands[3]->type_struct->str, inst->operands[3]->data,
454 memorder);
455 } break;
456 case LL_EXTRACTVALUE: {
457 fprintf(out, "%s%s = %s %s %s, %s", SPACES, inst->operands[0]->data, opname,
458 inst->operands[1]->type_struct->str, inst->operands[1]->data,
459 inst->operands[2]->data);
460 } break;
461 case LL_INSERTVALUE: {
462 fprintf(out, "%s%s = %s %s %s, %s %s, %s", SPACES, inst->operands[0]->data, opname,
463 inst->operands[1]->type_struct->str, inst->operands[1]->data,
464 inst->operands[2]->type_struct->str, inst->operands[2]->data,
465 inst->operands[3]->data);
466 } break;
467 case LL_EXTRACTELEM: {
468 fprintf(out, "%s%s = %s %s %s, %s %s", SPACES, inst->operands[0]->data, opname,
469 inst->operands[1]->type_struct->str, inst->operands[1]->data,
470 inst->operands[2]->type_struct->str, inst->operands[2]->data);
471 } break;
472 case LL_INSERTELEM: {
473 fprintf(out, "%s%s = %s %s %s, %s %s, %s %s", SPACES, inst->operands[0]->data, opname,
474 inst->operands[1]->type_struct->str, inst->operands[1]->data,
475 inst->operands[2]->type_struct->str, inst->operands[2]->data,
476 inst->operands[3]->type_struct->str, inst->operands[3]->data);
477 } break;
478 case LL_ADD:
479 case LL_FADD:
480 case LL_SUB:
481 case LL_FSUB:
482 case LL_MUL:
483 case LL_FMUL:
484 case LL_UDIV:
485 case LL_SDIV:
486 case LL_FDIV:
487 case LL_UREM:
488 case LL_SREM:
489 case LL_ASHR:
490 case LL_OR:
491 case LL_AND:
492 case LL_XOR:
493 case LL_LSHR:
494 case LL_SHL:
495 /* Group all binary operations */
496 fprintf(out, "%s%s = %s %s %s, %s", SPACES, inst->operands[0]->data, opname,
497 inst->operands[1]->type_struct->str, inst->operands[1]->data,
498 inst->operands[2]->data);
499 break;
500 case LL_FNEG:
501 /* unary ops */
502 fprintf(out, "%s%s = %s %s %s", SPACES, inst->operands[0]->data, opname,
503 inst->operands[1]->type_struct->str, inst->operands[1]->data);
504 break;
505 case LL_STORE:
506 render_store(out, inst);
507 break;
508 case LL_LOAD:
509 fprintf(out, "%s%s = load %s", SPACES, inst->operands[0]->data,
510 (inst->flags & INST_VOLATILE) ? "volatile " : "");
511 if (ll_feature_explicit_gep_load_type(&module->ir))
512 fprintf(out, "%s, ", inst->operands[1]->type_struct->sub_types[0]->str);
513 fprintf(out, "%s %s", inst->operands[1]->type_struct->str,
514 inst->operands[1]->data);
515 if (inst->num_operands >= 3)
516 fprintf(out, ", align %s", inst->operands[2]->data);
517 break;
518 case LL_SEXT:
519 case LL_ZEXT:
520 case LL_TRUNC:
521 case LL_FPTRUNC:
522 case LL_FPEXT:
523 case LL_SITOFP:
524 case LL_UITOFP:
525 case LL_PTRTOINT:
526 case LL_INTTOPTR:
527 case LL_FPTOSI:
528 case LL_FPTOUI:
529 /* Group all conversion operations */
530 fprintf(out, "%s%s = %s %s %s to %s", SPACES, inst->operands[0]->data,
531 opname, inst->operands[1]->type_struct->str,
532 inst->operands[1]->data, inst->operands[0]->type_struct->str);
533 break;
534 case LL_BITCAST:
535 render_bitcast(out, inst);
536 break;
537 case LL_RET:
538 if (no_return) {
539 fprintf(out, "%scall void @llvm.nvvm.exit()\n",SPACES);
540 fprintf(out, "%sunreachable",SPACES);
541 }
542 else
543 fprintf(out, "%sret %s %s", SPACES, inst->operands[0]->type_struct->str,
544 inst->operands[0]->data);
545 break;
546 case LL_ICMP:
547 case LL_FCMP:
548 fprintf(out, "%s%s = %s %s %s %s, %s", SPACES, inst->operands[0]->data,
549 opname, inst->operands[1]->data,
550 inst->operands[2]->type_struct->str, inst->operands[2]->data,
551 inst->operands[3]->data);
552 break;
553 case LL_SELECT:
554 fprintf(out, "%s%s = select i1 %s, %s %s, %s %s", SPACES,
555 inst->operands[0]->data, inst->operands[1]->data,
556 inst->operands[2]->type_struct->str, inst->operands[2]->data,
557 inst->operands[3]->type_struct->str, inst->operands[3]->data);
558 break;
559 case LL_BR:
560 fprintf(out, "%sbr i1 %s, label %%%s, label %%%s", SPACES,
561 inst->operands[0]->data, inst->operands[1]->data,
562 inst->operands[2]->data);
563 print_branch_target = 1;
564 break;
565 case LL_UBR:
566 fprintf(out, "%sbr label %%%s", SPACES, inst->operands[0]->data);
567 break;
568 case LL_CALL:
569 /* TODO: support fancier calls */
570 if (inst->operands[0]->type_struct->data_type != LL_VOID) {
571 fprintf(out, "%s%s = call %s @%s(", SPACES, inst->operands[0]->data,
572 inst->operands[1]->type_struct->str, inst->operands[1]->data);
573 } else {
574 fprintf(out, "%scall %s @%s(", SPACES,
575 inst->operands[1]->type_struct->str, inst->operands[1]->data);
576 }
577 for (i = 2; i < inst->num_operands; i++) {
578 fprintf(out, "%s %s", inst->operands[i]->type_struct->str,
579 inst->operands[i]->data);
580 if (i + 1 < inst->num_operands) {
581 fprintf(out, ", ");
582 }
583 }
584 fprintf(out, ")");
585 if (!(inst->flags & IN_MODULE_CALL)) {
586 add_prototype(inst);
587 }
588 break;
589 case LL_TEXTCALL:
590 if (inst->operands[0]->type_struct->data_type != LL_VOID) {
591 fprintf(out, "%s%s = call %s @%s(", SPACES, inst->operands[0]->data,
592 inst->operands[1]->type_struct->str, inst->operands[1]->data);
593 } else {
594 fprintf(out, "%scall %s @%s(", SPACES,
595 inst->operands[1]->type_struct->str, inst->operands[1]->data);
596 }
597 fprintf(out, "metadata !{%s %s}, ", inst->operands[2]->type_struct->str,
598 inst->operands[2]->data);
599 fprintf(out, "%s %s", inst->operands[2]->type_struct->str,
600 inst->operands[2]->data);
601 fprintf(out, ")");
602 text_calls = 1;
603 break;
604 case LL_GEP:
605 fprintf(out, "%s%s = getelementptr ", SPACES, inst->operands[0]->data);
606 if(inst->flags&INST_INBOUND)
607 fprintf(out, "inbounds ");
608 if (ll_feature_explicit_gep_load_type(&module->ir))
609 fprintf(out, "%s, ", inst->operands[1]->type_struct->sub_types[0]->str);
610 fprintf(out, "%s %s", inst->operands[1]->type_struct->str,
611 inst->operands[1]->data);
612 for (i = 2; i < inst->num_operands; i++) {
613 fprintf(out, ", %s %s", inst->operands[i]->type_struct->str,
614 inst->operands[i]->data);
615 }
616 break;
617 case LL_ALLOCA:
618 fprintf(out, "%s%s = alloca %s", SPACES, inst->operands[0]->data,
619 inst->operands[1]->type_struct->str);
620 /* alloca size */
621 if (inst->num_operands >= 4)
622 fprintf(out, ", %s %s", inst->operands[3]->type_struct->str, inst->operands[3]->data);
623 /* alignment */
624 if (inst->num_operands >= 3)
625 fprintf(out, ", align %s", inst->operands[2]->data);
626 break;
627 case LL_UNREACHABLE:
628 fprintf(out, "%sunreachable", SPACES);
629 break;
630 case LL_SWITCH:
631 fprintf(out, "%sswitch %s %s, label %%%s [\n", SPACES,
632 inst->operands[0]->type_struct->str, inst->operands[0]->data,
633 inst->operands[1]->data);
634 for (i = 2; i < inst->num_operands; i += 2) {
635 fprintf(out, "%s %s %s, label %%%s\n", SPACES,
636 inst->operands[i + 0]->type_struct->str,
637 inst->operands[i + 0]->data, inst->operands[i + 1]->data);
638 }
639 fprintf(out, "%s]", SPACES);
640 break;
641 case LL_NONE:
642 break;
643 default:
644 fprintf(stderr, "Error: unrendered instruction %d\n", inst->op);
645 break;
646 }
647 if (!LL_MDREF_IS_NULL(inst->dbg_line_op)) {
648 fprintf(out, ", !dbg !%u", LL_MDREF_value(inst->dbg_line_op));
649 }
650 #if DEBUG
651 if (inst->comment)
652 fprintf(out, " ; %s", inst->comment);
653 #endif
654
655 fputc('\n', out);
656 if (print_branch_target)
657 fprintf(out, "%s:\n", inst->operands[2]->data);
658 fflush(out);
659 }
660
661 /**
662 \brief Emit a list of \c !dbg \e n annotations
663 \param ods the object to \c !dbg list
664
665 In LLVM 4.0, we can generate a list of comma separated \c !dbg metadata to
666 link the object to a number of debug metadata descriptions.
667 */
668 void
ll_write_object_dbg_references(FILE * out,LL_Module * m,LL_ObjToDbgList * ods)669 ll_write_object_dbg_references(FILE *out, LL_Module *m, LL_ObjToDbgList *ods)
670 {
671 LL_ObjToDbgListIter i;
672 if (!ll_feature_from_global_to_md(&m->ir))
673 return;
674 for (llObjtodbgFirst(ods, &i); !llObjtodbgAtEnd(&i); llObjtodbgNext(&i)) {
675 LL_MDRef mdnode = llObjtodbgGet(&i);
676 fprintf(out, ", !dbg !%u", LL_MDREF_value(mdnode));
677 }
678 llObjtodbgFree(ods);
679 }
680
681 void
ll_write_basicblock(FILE * out,LL_Function * function,LL_BasicBlock * block,LL_Module * module,int no_return)682 ll_write_basicblock(FILE *out, LL_Function *function, LL_BasicBlock *block,
683 LL_Module *module, int no_return)
684 {
685 LL_Instruction *inst = block->first;
686
687 if (block->name)
688 fprintf(out, "%s:\n", block->name);
689
690 if (block == function->first)
691 ll_write_local_objects(out, function);
692
693 while (inst) {
694 ll_write_instruction(out, inst, module, no_return);
695 inst = inst->next;
696 }
697 }
698
699 /**
700 \brief Write out definitions of local objects in function as a series of
701 alloca instructions.
702
703 Unlike ll_write_global_objects(), this function only expects to be called
704 once per function.
705 */
706 void
ll_write_local_objects(FILE * out,LL_Function * function)707 ll_write_local_objects(FILE *out, LL_Function *function)
708 {
709 LL_Object *object;
710 #ifdef TARGET_POWER
711 int i;
712 int curr_nan_label_count = 0;
713 const char *name;
714 #endif
715
716 for (object = function->first_local; object; object = object->next) {
717 fprintf(out, "\t%s = alloca %s", object->address.data, object->type->str);
718 if (object->align_bytes)
719 fprintf(out, ", align %u", object->align_bytes);
720 fputc('\n', out);
721
722 #ifdef TARGET_POWER
723 if (XBIT(217, 0x1)) {
724 name = object->address.data;
725 if (ll_type_bytes(object->type) == 4) {
726 if (object->type->data_type == LL_I32) {
727 fprintf(out, "\tstore i32 %s, i32* %s, align 4\n",
728 POWER_STACK_32_BIT_NAN, name);
729 } else {
730 fprintf(out, "\t%s.temp = bitcast %s* %s to i32*\n", name,
731 object->type->str, name);
732 fprintf(out, "\tstore i32 %s, i32* %s.temp, align 4\n",
733 POWER_STACK_32_BIT_NAN, name);
734 }
735 } else if (ll_type_bytes(object->type) == 8) {
736 if (object->type->data_type == LL_I64) {
737 fprintf(out, "\tstore i64 %s, i64* %s, align 8\n",
738 POWER_STACK_64_BIT_NAN, name);
739 } else {
740 fprintf(out, "\t%s.temp = bitcast %s* %s to i64*\n", name,
741 object->type->str, name);
742 fprintf(out, "\tstore i64 %s, i64* %s.temp, align 8\n",
743 POWER_STACK_64_BIT_NAN, name);
744 }
745 } else if (ll_type_bytes(object->type) > 4) {
746 fprintf(out, "\t%s.temp = bitcast %s* %s to i32*\n", name,
747 object->type->str, name);
748 fprintf(out, "\t%s.ptr = alloca i32*, align 4\n", name);
749 fprintf(out, "\t%s.count = alloca i32, align 4\n", name);
750 fprintf(out, "\tstore i32 %d, i32* %s.count, align 4\n",
751 (int)(ll_type_bytes(object->type) / 4), name);
752 fprintf(out, "\t%s.temp0 = bitcast i32* %s.temp to i8*\n", name, name);
753 fprintf(out, "\t%s.temp1 = bitcast i32** %s.ptr to i8**\n", name, name);
754 fprintf(out, "\tstore i8* %s.temp0, i8** %s.temp1, align 4\n", name,
755 name);
756 fprintf(out, "\tbr label %%L.st.init.%04d.1\n", curr_nan_label_count);
757 fprintf(out, "L.st.init.%04d.1:\n", curr_nan_label_count);
758 fprintf(out, "\t%s.temp2 = load i32, i32* %s.count, align 4\n", name,
759 name);
760 fprintf(out, "\t%s.temp3 = icmp sle i32 %s.temp2, 0\n", name, name);
761 fprintf(out,
762 "\tbr i1 %s.temp3, label %%L.st.init.%04d.0,"
763 " label %%L.st.init.%04d.2\n",
764 name, curr_nan_label_count + 1, curr_nan_label_count);
765 fprintf(out, "L.st.init.%04d.2:\n", curr_nan_label_count);
766 fprintf(out, "\t%s.temp4 = load i32*, i32** %s.ptr, align 4\n", name,
767 name);
768 fprintf(out, "\tstore i32 %s, i32* %s.temp4, align 4\n",
769 POWER_STACK_32_BIT_NAN, name);
770 fprintf(out, "\t%s.temp5 = bitcast i32* %s.temp4 to i8*\n", name, name);
771 fprintf(out, "\t%s.temp6 = getelementptr i8, i8* %s.temp5, i32 4\n",
772 name, name);
773 fprintf(out, "\t%s.temp7 = bitcast i32** %s.ptr to i8**\n", name, name);
774 fprintf(out, "\tstore i8* %s.temp6, i8** %s.temp7, align 4\n", name,
775 name);
776 fprintf(out, "\t%s.temp8 = load i32, i32* %s.count, align 4\n", name,
777 name);
778 fprintf(out, "\t%s.temp9 = sub i32 %s.temp8, 1\n", name, name);
779 fprintf(out, "\tstore i32 %s.temp9, i32* %s.count, align 4\n", name,
780 name);
781 fprintf(out, "\tbr label %%L.st.init.%04d.1\n", curr_nan_label_count);
782 curr_nan_label_count++;
783 fprintf(out, "L.st.init.%04d.0:\n", curr_nan_label_count);
784 }
785 }
786 #endif
787 }
788 }
789 void
ll_write_function(FILE * out,LL_Function * function,LL_Module * module,bool no_return,const char * prefix)790 ll_write_function(FILE *out, LL_Function *function, LL_Module *module, bool no_return, const char *prefix)
791 {
792 int i;
793 char attribute[256];
794 LL_BasicBlock *block = function->first;
795
796 fprintf(out, "define %s %s %s ", ll_get_linkage_string(function->linkage),
797 function->calling_convention, function->return_type->str);
798 fprintf(out, "@%s%s(", prefix, function->name);
799 for (i = 0; i < function->num_args; i++) {
800 fputs(function->arguments[i]->type_struct->str, out);
801
802 if (function->arguments[i]->flags & VAL_IS_NOALIAS_PARAM) {
803 fputs(" noalias", out);
804 }
805
806 fputc(' ', out);
807 fputs(function->arguments[i]->data, out);
808 if (i + 1 < function->num_args)
809 fputs(", ", out);
810 }
811 fputs(") nounwind ", out);
812 if (no_return)
813 fputs("noreturn ", out);
814 fputs("{\n", out);
815
816 while (block) {
817 ll_write_basicblock(out, function, block, module, no_return);
818 block = block->next;
819 }
820 fputs("}\n\n", out);
821 }
822
823 void
ll_write_function_signature(FILE * out,LL_Function * function)824 ll_write_function_signature(FILE *out, LL_Function *function)
825 {
826 int j;
827 fprintf(out, "%s (", function->return_type->str);
828 for (j = 0; j < function->num_args; j++) {
829 fprintf(out, "%s", function->arguments[j]->type_struct->str);
830 if (j + 1 < function->num_args)
831 fprintf(out, ", ");
832 }
833 fprintf(out, ")* @%s", function->name);
834 }
835
836 /*
837 * Metadata
838 */
839
840 enum FieldType {
841 UnsignedField,
842 SignedField,
843 BoolField,
844 NodeField,
845 StringField,
846 ValueField,
847 DWTagField,
848 DWLangField,
849 DWVirtualityField,
850 DWEncodingField,
851 DWEmissionField
852 };
853
854 enum FieldFlags {
855 FlgMandatory = 0x1, /**< Field must be present, even with a default value */
856 FlgOptional = 0x2, /**< Field does not have to be present in the MDNode */
857 FlgHidden = 0x4, /**< Field is never printed */
858 FlgSkip1 = 0x8, /**< special skip handling of signed constant */
859 };
860
861 /**
862 * \brief Templates for printing specialized metadata nodes.
863 *
864 * A template is an array of MDTemplate structs with nf+1 elements where nf is
865 * the number of fields.
866 *
867 * The first entry of the array is the class name without the leading bang
868 * (e.g., "MDLocation"), and the "flags" field contains nf.
869 *
870 * The remaining entries correspond to the node elements, the names are field
871 * names without the trailing colon.
872 */
873 typedef struct MDTemplate {
874 const char *name;
875 enum FieldType type;
876 unsigned flags;
877 } MDTemplate;
878
879 #define TF ((enum FieldType)0)
880
881 /* clang-format off */
882
883 /* !DILocation(line: 2900, column: 42, scope: !1, inlinedAt: !2) */
884 static const MDTemplate Tmpl_DILocation[] = {
885 { "DILocation", TF, 4 },
886 { "line", UnsignedField },
887 { "column", UnsignedField },
888 { "scope", NodeField, FlgMandatory },
889 { "inlinedAt", NodeField}
890 };
891
892 /* !MDLocation(line: 2900, column: 42, scope: !1, inlinedAt: !2) */
893 static const MDTemplate Tmpl_MDLocation[] = {
894 { "MDLocation", TF, 4 },
895 { "line", UnsignedField },
896 { "column", UnsignedField },
897 { "scope", NodeField, FlgMandatory },
898 { "inlinedAt", NodeField }
899 };
900
901 /* An DIFile(filename: "...", directory: "...") pair */
902 static const MDTemplate Tmpl_DIFile_pair[] = {
903 { "DIFile", TF, 2 },
904 { "filename", StringField },
905 { "directory", StringField }
906 };
907
908 /* A tagged MDFile node. Not used by LLVM. */
909 static const MDTemplate Tmpl_DIFile_tagged[] = {
910 { "DIFile", TF, 2 },
911 { "tag", DWTagField },
912 { "pair", NodeField }
913 };
914
915 /* MDFile before 3.4 */
916 static const MDTemplate Tmpl_DIFile_pre34[] = {
917 { "DIFile", TF, 4 },
918 { "tag", DWTagField },
919 { "filename", StringField },
920 { "directory", StringField },
921 { "context", NodeField }
922 };
923
924 static const MDTemplate Tmpl_DICompileUnit[] = {
925 { "DICompileUnit", TF, 13 },
926 { "tag", DWTagField, FlgHidden },
927 { "file", NodeField },
928 { "language", DWLangField },
929 { "producer", StringField },
930 { "isOptimized", BoolField },
931 { "flags", StringField },
932 { "runtimeVersion", UnsignedField },
933 { "enums", NodeField },
934 { "retainedTypes", NodeField },
935 { "subprograms", NodeField },
936 { "globals", NodeField },
937 { "imports", NodeField },
938 { "splitDebugFilename", StringField }
939 };
940
941 /* "subprograms" removed from DICompileUnit in LLVM 3.9 */
942 static const MDTemplate Tmpl_DICompileUnit_ver39[] = {
943 { "DICompileUnit", TF, 13 },
944 { "tag", DWTagField, FlgHidden },
945 { "file", NodeField },
946 { "language", DWLangField },
947 { "producer", StringField },
948 { "isOptimized", BoolField },
949 { "flags", StringField },
950 { "runtimeVersion", UnsignedField },
951 { "enums", NodeField },
952 { "retainedTypes", NodeField },
953 { "globals", NodeField },
954 { "emissionKind", DWEmissionField },
955 { "imports", NodeField },
956 { "splitDebugFilename", StringField }
957 };
958
959 static const MDTemplate Tmpl_DICompileUnit_pre34[] = {
960 { "DICompileUnit", TF, 14 },
961 { "tag", DWTagField, FlgHidden },
962 { "unused", NodeField, FlgHidden },
963 { "language", DWLangField },
964 { "filename", StringField },
965 { "directory", StringField },
966 { "producer", StringField },
967 { "isMain", BoolField },
968 { "isOptimized", BoolField },
969 { "flags", StringField },
970 { "runtimeVersion", UnsignedField },
971 { "enums", NodeField },
972 { "retainedTypes", NodeField },
973 { "subprograms", NodeField },
974 { "globals", NodeField }
975 };
976
977 static const MDTemplate Tmpl_DINamespace_pre34[] = {
978 { "DINamespace", TF, 5 },
979 { "tag", DWTagField },
980 { "scope", NodeField },
981 { "name", StringField },
982 { "file", NodeField },
983 { "line", UnsignedField }
984 };
985
986 static const MDTemplate Tmpl_DINamespace_post34[] = {
987 { "DINamespace", TF, 5 },
988 { "tag", DWTagField, FlgHidden },
989 { "file", NodeField },
990 { "scope", NodeField },
991 { "name", StringField },
992 { "line", UnsignedField }
993 };
994
995 static const MDTemplate Tmpl_DINamespace_5[] = {
996 { "DINamespace", TF, 5 },
997 { "tag", DWTagField, FlgHidden },
998 { "file", NodeField, FlgHidden },
999 { "scope", NodeField },
1000 { "name", StringField },
1001 { "line", UnsignedField, FlgHidden }
1002 };
1003
1004 static const MDTemplate Tmpl_DIModule[] = {
1005 { "DIModule", TF, 3 },
1006 { "tag", DWTagField, FlgHidden },
1007 { "scope", NodeField },
1008 { "name", StringField }
1009 //,{ "configMacros", StringField, FlgOptional },
1010 //{ "includePath", StringField, FlgOptional },
1011 //{ "isysroot", StringField, FlgOptional }
1012 };
1013
1014 static const MDTemplate Tmpl_DISubprogram[] = {
1015 { "DISubprogram", TF, 20 },
1016 { "tag", DWTagField, FlgHidden },
1017 { "file", NodeField },
1018 { "scope", NodeField },
1019 { "name", StringField },
1020 { "displayName", StringField, FlgHidden },
1021 { "linkageName", StringField },
1022 { "line", UnsignedField },
1023 { "type", NodeField },
1024 { "isLocal", BoolField },
1025 { "isDefinition", BoolField },
1026 { "virtuality", DWVirtualityField },
1027 { "virtualIndex", UnsignedField },
1028 { "containingType", NodeField },
1029 { "flags", UnsignedField }, /* TBD: DIFlag... */
1030 { "isOptimized", BoolField },
1031 { "function", ValueField },
1032 { "templateParams", NodeField },
1033 { "declaration", NodeField },
1034 { "variables", NodeField },
1035 { "scopeLine", UnsignedField }
1036 };
1037
1038 static const MDTemplate Tmpl_DISubprogram_70[] = {
1039 { "DISubprogram", TF, 20 },
1040 { "tag", DWTagField, FlgHidden },
1041 { "file", NodeField },
1042 { "scope", NodeField },
1043 { "name", StringField },
1044 { "displayName", StringField, FlgHidden },
1045 { "linkageName", StringField },
1046 { "line", UnsignedField },
1047 { "type", NodeField },
1048 { "isLocal", BoolField },
1049 { "isDefinition", BoolField },
1050 { "virtuality", DWVirtualityField },
1051 { "virtualIndex", UnsignedField },
1052 { "containingType", NodeField },
1053 { "flags", UnsignedField }, /* TBD: DIFlag... */
1054 { "isOptimized", BoolField },
1055 { "function", ValueField, FlgHidden },
1056 { "templateParams", NodeField },
1057 { "declaration", NodeField },
1058 { "unit", NodeField },
1059 { "scopeLine", UnsignedField }
1060 };
1061
1062 static const MDTemplate Tmpl_DISubprogram_38[] = {
1063 { "DISubprogram", TF, 20 },
1064 { "tag", DWTagField, FlgHidden },
1065 { "file", NodeField },
1066 { "scope", NodeField },
1067 { "name", StringField },
1068 { "displayName", StringField, FlgHidden },
1069 { "linkageName", StringField },
1070 { "line", UnsignedField },
1071 { "type", NodeField },
1072 { "isLocal", BoolField },
1073 { "isDefinition", BoolField },
1074 { "virtuality", DWVirtualityField },
1075 { "virtualIndex", UnsignedField },
1076 { "containingType", NodeField },
1077 { "flags", UnsignedField }, /* TBD: DIFlag... */
1078 { "isOptimized", BoolField },
1079 { "function", ValueField, FlgHidden },
1080 { "templateParams", NodeField },
1081 { "declaration", NodeField },
1082 { "variables", NodeField },
1083 { "scopeLine", UnsignedField }
1084 };
1085
1086 /** "unit" was added in LLVM 3.9 for DISubprogram */
1087 static const MDTemplate Tmpl_DISubprogram_39[] = {
1088 { "DISubprogram", TF, 21 },
1089 { "tag", DWTagField, FlgHidden },
1090 { "file", NodeField },
1091 { "scope", NodeField },
1092 { "name", StringField },
1093 { "displayName", StringField, FlgHidden },
1094 { "linkageName", StringField },
1095 { "line", UnsignedField },
1096 { "type", NodeField },
1097 { "isLocal", BoolField },
1098 { "isDefinition", BoolField },
1099 { "virtuality", DWVirtualityField },
1100 { "virtualIndex", UnsignedField },
1101 { "containingType", NodeField },
1102 { "flags", UnsignedField }, /* TBD: DIFlag... */
1103 { "isOptimized", BoolField },
1104 { "function", ValueField, FlgHidden },
1105 { "templateParams", NodeField },
1106 { "declaration", NodeField },
1107 { "unit", NodeField },
1108 { "variables", NodeField },
1109 { "scopeLine", UnsignedField }
1110 };
1111
1112 static const MDTemplate Tmpl_DILexicalBlock[] = {
1113 { "DILexicalBlock", TF, 6 },
1114 { "tag", DWTagField, FlgHidden },
1115 { "file", NodeField },
1116 { "scope", NodeField },
1117 { "line", UnsignedField },
1118 { "column", UnsignedField },
1119 { "discriminator", UnsignedField, FlgHidden | FlgOptional }
1120 };
1121
1122 static const MDTemplate Tmpl_DILexicalBlock_pre34[] = {
1123 { "DILexicalBlock", TF, 6 },
1124 { "tag", DWTagField, FlgHidden },
1125 { "scope", NodeField },
1126 { "line", UnsignedField },
1127 { "column", UnsignedField },
1128 { "file", NodeField },
1129 { "discriminator", UnsignedField, FlgOptional }
1130 };
1131
1132 static const MDTemplate Tmpl_DILexicalBlockFile[] = {
1133 { "DILexicalBlock", TF, 4 },
1134 { "tag", DWTagField, FlgHidden },
1135 { "file", NodeField },
1136 { "scope", NodeField },
1137 { "discriminator", UnsignedField }
1138 };
1139
1140 static const MDTemplate Tmpl_DIExpression[] = {
1141 { "DIExpression", TF, 0 }
1142 };
1143
1144 static const MDTemplate Tmpl_DILocalVariable[] = {
1145 { "DILocalVariable", TF, 9 },
1146 { "tag", DWTagField },
1147 { "scope", NodeField },
1148 { "name", StringField },
1149 { "arg", UnsignedField },
1150 { "file", NodeField },
1151 { "line", UnsignedField },
1152 { "type", NodeField },
1153 { "flags", UnsignedField }, /* TBD: DIFlag... */
1154 { "inlinedAt", UnsignedField } /* TBD: NodeField */
1155 };
1156
1157 static const MDTemplate Tmpl_DILocalVariable_38[] = {
1158 { "DILocalVariable", TF, 8 },
1159 { "scope", NodeField },
1160 { "name", StringField },
1161 { "arg", UnsignedField },
1162 { "file", NodeField },
1163 { "line", UnsignedField },
1164 { "type", NodeField },
1165 { "flags", UnsignedField },/* TBD: DIFlag... */
1166 { "inlinedAt", UnsignedField } /* TBD: NodeField */
1167 };
1168
1169 static const MDTemplate Tmpl_DILocalVariable_embedded_argnum[] = {
1170 { "DILocalVariable", TF, 8 },
1171 { "tag", DWTagField },
1172 { "scope", NodeField },
1173 { "name", StringField },
1174 { "file", NodeField },
1175 { "line_and_arg", UnsignedField },
1176 { "type", NodeField },
1177 { "flags", UnsignedField }, /* TBD: DIFlag... */
1178 { "inlinedAt", UnsignedField } /* TBD: NodeField */
1179 };
1180
1181 static const MDTemplate Tmpl_DIGlobalVariable[] = {
1182 { "DIGlobalVariable", TF, 14 },
1183 { "tag", DWTagField, FlgHidden },
1184 { "unused", NodeField, FlgHidden },
1185 { "scope", NodeField },
1186 { "name", StringField },
1187 { "displayName", StringField, FlgHidden },
1188 { "linkageName", StringField },
1189 { "file", NodeField },
1190 { "line", UnsignedField },
1191 { "type", NodeField },
1192 { "isLocal", BoolField },
1193 { "isDefinition", BoolField },
1194 { "variable", ValueField },
1195 { "flags", UnsignedField },
1196 { "addrspace", UnsignedField, FlgOptional } /* nvvm extension */
1197 /* Missing: declaration */
1198 };
1199
1200 static const MDTemplate Tmpl_DIGlobalVariable4[] = {
1201 { "DIGlobalVariable", TF, 13 },
1202 { "tag", DWTagField, FlgHidden },
1203 { "unused", NodeField, FlgHidden },
1204 { "scope", NodeField },
1205 { "name", StringField, FlgMandatory },
1206 { "displayName", StringField, FlgHidden },
1207 { "linkageName", StringField },
1208 { "file", NodeField },
1209 { "line", UnsignedField },
1210 { "type", NodeField },
1211 { "isLocal", BoolField },
1212 { "isDefinition", BoolField },
1213 { "flags", UnsignedField },
1214 { "addrspace", UnsignedField, FlgOptional } /* nvvm extension */
1215 };
1216
1217 static const MDTemplate Tmpl_DIGlobalVariableExpression[] = {
1218 { "DIGlobalVariableExpression", TF, 2 },
1219 { "var", NodeField },
1220 { "expr", NodeField }
1221 };
1222
1223 static const MDTemplate Tmpl_DIBasicType_pre34[] = {
1224 { "DIBasicType", TF, 10 },
1225 { "tag", DWTagField },
1226 { "scope", NodeField },
1227 { "name", StringField },
1228 { "file", NodeField },
1229 { "line", UnsignedField },
1230 { "size", UnsignedField },
1231 { "align", UnsignedField },
1232 { "offset", UnsignedField },
1233 { "flags", UnsignedField }, /* TBD: DIFlag... */
1234 { "encoding", DWEncodingField }
1235 };
1236
1237 static const MDTemplate Tmpl_DIBasicType[] = {
1238 { "DIBasicType", TF, 10 },
1239 { "tag", DWTagField },
1240 { "unused", NodeField, FlgHidden },
1241 { "unused", NodeField, FlgHidden },
1242 { "name", StringField },
1243 { "line", UnsignedField },
1244 { "size", UnsignedField },
1245 { "align", UnsignedField },
1246 { "offset", UnsignedField },
1247 { "flags", UnsignedField }, /* TBD: DIFlag... */
1248 { "encoding", DWEncodingField }
1249 };
1250
1251 /* deprecated */
1252 static const MDTemplate Tmpl_DIStringType_old[] = {
1253 { "DIBasicType", TF, 5 },
1254 { "tag", DWTagField },
1255 { "name", StringField },
1256 { "size", UnsignedField },
1257 { "align", UnsignedField },
1258 { "encoding", DWEncodingField }
1259 };
1260
1261 static const MDTemplate Tmpl_DIStringType[] = {
1262 { "DIStringType", TF, 7 },
1263 { "tag", DWTagField, FlgHidden },
1264 { "name", StringField },
1265 { "size", UnsignedField },
1266 { "align", UnsignedField },
1267 { "encoding", UnsignedField, FlgHidden },
1268 { "stringLength", NodeField },
1269 { "stringLengthExpression", NodeField}
1270 };
1271
1272 static const MDTemplate Tmpl_DISubroutineType[] = {
1273 { "DISubroutineType", TF, 15 },
1274 { "tag", DWTagField, FlgHidden },
1275 { "unused", UnsignedField },
1276 { "unused", NodeField },
1277 { "name", StringField },
1278 { "unused", UnsignedField },
1279 { "unused", UnsignedField },
1280 { "unused", UnsignedField },
1281 { "unused", UnsignedField },
1282 { "unused", UnsignedField },
1283 { "unused", NodeField },
1284 { "types", NodeField },
1285 { "unused", UnsignedField },
1286 { "unused", NodeField },
1287 { "unused", NodeField },
1288 { "cc", UnsignedField }
1289 };
1290
1291 static const MDTemplate Tmpl_DIDerivedType_pre34[] = {
1292 { "DIDerivedType", TF, 10 },
1293 { "tag", DWTagField },
1294 { "scope", NodeField },
1295 { "name", StringField },
1296 { "file", NodeField },
1297 { "line", UnsignedField },
1298 { "size", UnsignedField },
1299 { "align", UnsignedField },
1300 { "offset", UnsignedField },
1301 { "flags", UnsignedField }, /* TBD: DIFlag... */
1302 { "baseType", NodeField }
1303 };
1304
1305 static const MDTemplate Tmpl_DIDerivedType[] = {
1306 { "DIDerivedType", TF, 10 },
1307 { "tag", DWTagField },
1308 { "file", NodeField },
1309 { "scope", NodeField },
1310 { "name", StringField },
1311 { "line", UnsignedField },
1312 { "size", UnsignedField },
1313 { "align", UnsignedField },
1314 { "offset", UnsignedField },
1315 { "flags", UnsignedField }, /* TBD: DIFlag... */
1316 { "baseType", NodeField }
1317 };
1318
1319 static const MDTemplate Tmpl_DICompositeType_pre34[] = {
1320 { "DICompositeType", TF, 13 },
1321 { "tag", DWTagField },
1322 { "scope", NodeField },
1323 { "name", StringField },
1324 { "file", NodeField },
1325 { "line", UnsignedField },
1326 { "size", UnsignedField },
1327 { "align", UnsignedField },
1328 { "offset", UnsignedField },
1329 { "flags", UnsignedField }, /* TBD: DIFlag... */
1330 { "baseType", NodeField },
1331 { "elements", NodeField },
1332 { "runtimeLang", DWLangField },
1333 { "unused", NodeField, FlgHidden }
1334 };
1335
1336 static const MDTemplate Tmpl_DICompositeType[] = {
1337 { "DICompositeType", TF, 15 },
1338 { "tag", DWTagField },
1339 { "file", NodeField },
1340 { "scope", NodeField },
1341 { "name", StringField },
1342 { "line", UnsignedField },
1343 { "size", UnsignedField },
1344 { "align", UnsignedField },
1345 { "offset", UnsignedField },
1346 { "flags", UnsignedField }, /* TBD: DIFlag... */
1347 { "baseType", NodeField },
1348 { "elements", NodeField },
1349 { "runtimeLang", DWLangField },
1350 { "vtableHolder", NodeField },
1351 { "templateParams", NodeField },
1352 { "identifier", StringField }
1353 };
1354
1355 static const MDTemplate Tmpl_DIFortranArrayType[] = {
1356 { "DIFortranArrayType", TF, 7 },
1357 { "tag", DWTagField },
1358 { "scope", NodeField },
1359 { "line", UnsignedField },
1360 { "size", UnsignedField },
1361 { "align", UnsignedField },
1362 { "baseType", NodeField },
1363 { "elements", NodeField }
1364 };
1365
1366 static const MDTemplate Tmpl_DISubrange[] = {
1367 { "DISubrange", TF, 3 },
1368 { "tag", DWTagField, FlgHidden },
1369 { "lowerBound", SignedField },
1370 { "count", SignedField, FlgMandatory }
1371 };
1372
1373 static const MDTemplate Tmpl_DISubrange_pre37[] = {
1374 { "DISubrange", TF, 3 },
1375 { "tag", DWTagField, FlgHidden },
1376 { "lowerBound", SignedField },
1377 { "upperBound", SignedField }
1378 };
1379
1380 static const MDTemplate Tmpl_DIFortranSubrange[] = {
1381 { "DIFortranSubrange", TF, 7 },
1382 { "tag", DWTagField, FlgHidden },
1383 { "constLowerBound", SignedField },
1384 { "constUpperBound", SignedField, FlgSkip1 },
1385 { "lowerBound", NodeField },
1386 { "lowerBoundExpression", NodeField },
1387 { "upperBound", NodeField },
1388 { "upperBoundExpression", NodeField }
1389 };
1390
1391 static const MDTemplate Tmpl_DIEnumerator[] = {
1392 { "DIEnumerator", TF, 3 },
1393 { "tag", DWTagField, FlgHidden },
1394 { "name", StringField },
1395 { "value", SignedField, FlgMandatory }
1396 };
1397
1398 static const MDTemplate Tmpl_DIImportedEntity[] = {
1399 { "DIImportedEntity", TF, 6 },
1400 { "tag", DWTagField },
1401 { "entity", NodeField },
1402 { "scope", NodeField },
1403 { "file", NodeField },
1404 { "line", UnsignedField },
1405 { "name", StringField }
1406 };
1407
1408 static const MDTemplate Tmpl_DICommonBlock[] = {
1409 { "DICommonBlock", TF, 3 },
1410 { "scope", NodeField },
1411 { "declaration", NodeField },
1412 { "name", StringField }
1413 };
1414
1415 /* clang-format on */
1416
1417 #undef TF
1418
1419 /**
1420 \brief Write out an \ref LL_MDRef from \p module.
1421 \param out output file
1422 \param module the LLVM module
1423 \param rmdref the metadata node to be written
1424 \param omit_metadata_type if true then omit \c metadata keyword
1425
1426 This functions writes a metadata reference as it appears in metadata context,
1427 such as inside a metadata node definition, or following a \c !dbg tag.
1428
1429 Metadata references may use a different syntax when used as function
1430 arguments, depending on the LLVM version. That is \e not dealt with by this
1431 function.
1432 */
1433 void
write_mdref(FILE * out,LL_Module * module,LL_MDRef rmdref,int omit_metadata_type)1434 write_mdref(FILE *out, LL_Module *module, LL_MDRef rmdref,
1435 int omit_metadata_type)
1436 {
1437 const char *tag = "metadata ";
1438 LL_MDRef mdref = rmdref;
1439
1440 /* The metadata type tag is omitted in metadata context in LLVM 3.6+, and
1441 * always in named metadata definitions. */
1442 if (omit_metadata_type)
1443 tag = "";
1444
1445 switch (LL_MDREF_kind(mdref)) {
1446 case MDRef_Node:
1447 if (LL_MDREF_value(mdref))
1448 fprintf(out, "%s!%u", tag, LL_MDREF_value(mdref));
1449 else
1450 fprintf(out, "null");
1451 break;
1452
1453 case MDRef_String:
1454 assert(LL_MDREF_value(mdref) < module->mdstrings_count, "Bad string MDRef",
1455 LL_MDREF_value(mdref), ERR_Fatal);
1456 fprintf(out, "%s%s", tag, module->mdstrings[LL_MDREF_value(mdref)]);
1457 break;
1458
1459 case MDRef_Constant:
1460 assert(LL_MDREF_value(mdref) < module->constants_count,
1461 "Bad constant MDRef", LL_MDREF_value(mdref), ERR_Fatal);
1462 fprintf(out, "%s %s",
1463 module->constants[LL_MDREF_value(mdref)]->type_struct->str,
1464 module->constants[LL_MDREF_value(mdref)]->data);
1465 break;
1466
1467 case MDRef_SmallInt1:
1468 fprintf(out, "i1 %u", LL_MDREF_value(mdref));
1469 break;
1470
1471 case MDRef_SmallInt32:
1472 fprintf(out, "i32 %u", LL_MDREF_value(mdref));
1473 break;
1474
1475 case MDRef_SmallInt64:
1476 fprintf(out, "i64 %u", LL_MDREF_value(mdref));
1477 break;
1478
1479 default:
1480 interr("Invalid MDRef kind", LL_MDREF_kind(mdref), ERR_Fatal);
1481 }
1482 }
1483
1484 /**
1485 \brief generate full DWARF debug emission mode
1486 */
1487 static const char *
dwarf_emission_name(int value)1488 dwarf_emission_name(int value)
1489 {
1490 switch (value) {
1491 case 2:
1492 return "NoDebug";
1493 case 3:
1494 return "LineTablesOnly";
1495 default:
1496 return "FullDebug";
1497 }
1498 }
1499
1500 /**
1501 \brief Write out an an LL_MDRef as a field in a specialised MDNode class
1502 \param out file to write to
1503 \param module module containing the metadata
1504 \param node the metadata node to be written
1505 \param needs_comma If true, print a ", " before the field label
1506 \return true iff the field was actually printed
1507
1508 Includes priting the "name:" label. The field is not printed if it has its
1509 default value.
1510
1511 The formatting is guided by the field type from the MDTemplate, and the
1512 MDRef types are validated.
1513 */
1514 static int
write_mdfield(FILE * out,LL_Module * module,int needs_comma,LL_MDRef mdref,const MDTemplate * tmpl)1515 write_mdfield(FILE *out, LL_Module *module, int needs_comma, LL_MDRef mdref,
1516 const MDTemplate *tmpl)
1517 {
1518 unsigned value = LL_MDREF_value(mdref);
1519 const char *prefix = needs_comma ? ", " : "";
1520 const bool mandatory = (tmpl->flags & FlgMandatory) != 0;
1521
1522 if (tmpl->flags & FlgHidden)
1523 return false;
1524
1525 switch (LL_MDREF_kind(mdref)) {
1526 case MDRef_Node:
1527 if (value) {
1528 assert(tmpl->type == NodeField, "metadata elem should not be a mdnode",
1529 tmpl->type, ERR_Fatal);
1530 fprintf(out, "%s%s: !%u", prefix, tmpl->name, value);
1531 } else if (mandatory) {
1532 fprintf(out, "%s%s: null", prefix, tmpl->name);
1533 } else {
1534 return false;
1535 }
1536 break;
1537
1538 case MDRef_String:
1539 assert(tmpl->type == StringField, "metadata elem should not be a string",
1540 tmpl->type, ERR_Fatal);
1541 assert(value < module->mdstrings_count, "Bad string MDRef", value,
1542 ERR_Fatal);
1543 if (!mandatory && strcmp(module->mdstrings[value], "!\"\"") == 0)
1544 return false;
1545 /* The mdstrings[] entry is formatted as !"...". String the leading !. */
1546 fprintf(out, "%s%s: %s", prefix, tmpl->name, module->mdstrings[value] + 1);
1547 break;
1548
1549 case MDRef_Constant:
1550 assert(value < module->constants_count, "Bad constant MDRef", value,
1551 ERR_Fatal);
1552 switch (tmpl->type) {
1553 case ValueField:
1554 fprintf(out, "%s%s: %s %s", prefix, tmpl->name,
1555 module->constants[value]->type_struct->str,
1556 module->constants[value]->data);
1557 break;
1558
1559 #ifdef HOST_WIN
1560 #define strtoll _strtoi64
1561 #endif
1562 case UnsignedField:
1563 if (module->constants[value]->data[0] == '-') {
1564 /* The value stored is negative. LLVM expects it to be unsigned, so
1565 convert it to be positive. */
1566 long long intval = strtoll(module->constants[value]->data, NULL, 10);
1567 if ((long long)INT_MIN <= intval && intval < 0) {
1568 /* It was most likely a 32 bit value originally. */
1569 fprintf(out, "%s%s: %u", prefix, tmpl->name, (unsigned)(int)intval);
1570 } else {
1571 fprintf(out, "%s%s: %llu", prefix, tmpl->name, intval);
1572 }
1573 } else {
1574 fprintf(out, "%s%s: %s", prefix, tmpl->name,
1575 module->constants[value]->data);
1576 }
1577 break;
1578
1579 case SignedField: {
1580 bool doOutput = true;
1581 const char *dv = module->constants[value]->data;
1582 if (tmpl->flags & FlgSkip1) {
1583 const ISZ_T M = 1ul << ((sizeof(ISZ_T) * 8) - 1);
1584 ISZ_T idv;
1585 sscanf(dv, "%" ISZ_PF "d", &idv);
1586 doOutput = (idv != M);
1587 }
1588 if (!doOutput)
1589 return false;
1590 fprintf(out, "%s%s: %s", prefix, tmpl->name, dv);
1591 } break;
1592
1593 default:
1594 interr("metadata elem should not be a value", tmpl->type, ERR_unused);
1595 }
1596 break;
1597
1598 case MDRef_SmallInt1:
1599 case MDRef_SmallInt32:
1600 case MDRef_SmallInt64:
1601 if (!value && !mandatory)
1602 return false;
1603 switch (tmpl->type) {
1604 case UnsignedField:
1605 case SignedField:
1606 fprintf(out, "%s%s: %u", prefix, tmpl->name, value);
1607 break;
1608
1609 case BoolField:
1610 assert(value <= 1, "boolean value expected", value, ERR_Fatal);
1611 fprintf(out, "%s%s: %s", prefix, tmpl->name, value ? "true" : "false");
1612 break;
1613
1614 case DWTagField:
1615 fprintf(out, "%s%s: %s", prefix, tmpl->name,
1616 dwarf_tag_name(value & 0xffff));
1617 break;
1618
1619 case DWLangField:
1620 fprintf(out, "%s%s: %s", prefix, tmpl->name, dwarf_lang_name(value));
1621 break;
1622
1623 case DWVirtualityField:
1624 fprintf(out, "%s%s: %s", prefix, tmpl->name,
1625 dwarf_virtuality_name(value));
1626 break;
1627
1628 case DWEncodingField:
1629 fprintf(out, "%s%s: %s", prefix, tmpl->name, dwarf_encoding_name(value));
1630 break;
1631
1632 case DWEmissionField:
1633 fprintf(out, "%s%s: %s", prefix, tmpl->name, dwarf_emission_name(value));
1634 break;
1635
1636 default:
1637 interr("metadata elem should not be an int", tmpl->type, ERR_unused);
1638 }
1639 break;
1640
1641 default:
1642 interr("Invalid MDRef kind", LL_MDREF_kind(mdref), ERR_Fatal);
1643 }
1644
1645 return true;
1646 }
1647
1648 /*
1649 * Write out a metadata node definition in the "plain" style: !{ !1, ... }.
1650 *
1651 * When omit_metadata_type is set, don't print out the leading "metadata" type
1652 * tag. This doesn't affect the printing of the internal mdnode contents.
1653 */
1654 static void
write_mdnode_plain(FILE * out,LL_Module * module,const LL_MDNode * node,int omit_metadata_type)1655 write_mdnode_plain(FILE *out, LL_Module *module, const LL_MDNode *node,
1656 int omit_metadata_type)
1657 {
1658 unsigned i;
1659
1660 if (!omit_metadata_type)
1661 fprintf(out, "metadata ");
1662
1663 if (ll_feature_use_distinct_metadata(&module->ir) && node->is_distinct)
1664 fprintf(out, "distinct ");
1665
1666 fprintf(out, "!{ ");
1667 for (i = 0; i < node->num_elems; i++) {
1668 LL_MDRef mdref = LL_MDREF_INITIALIZER(0, 0);
1669 mdref = node->elem[i];
1670 if (i > 0)
1671 fprintf(out, ", ");
1672 write_mdref(out, module, mdref, omit_metadata_type);
1673 }
1674 fprintf(out, " }\n");
1675 }
1676
1677 /*
1678 * Write out a metadata node in the specialized form: !MDLocation(line: 42,
1679 * ...).
1680 *
1681 * Also perform some basic schema validation against the provided template.
1682 */
1683 static void
write_mdnode_spec(FILE * out,LL_Module * module,const LL_MDNode * node,const MDTemplate * tmpl)1684 write_mdnode_spec(FILE *out, LL_Module *module, const LL_MDNode *node,
1685 const MDTemplate *tmpl)
1686 {
1687 const unsigned num_fields = tmpl->flags;
1688 unsigned i;
1689 int needs_comma = false;
1690
1691 if (ll_feature_use_distinct_metadata(&module->ir) && node->is_distinct)
1692 fprintf(out, "distinct ");
1693
1694 assert(node->num_elems <= num_fields, "metadata node has too many fields.",
1695 node->num_elems, ERR_Fatal);
1696
1697 fprintf(out, "!%s(", tmpl->name);
1698 for (i = 0; i < node->num_elems; i++)
1699 if (write_mdfield(out, module, needs_comma, node->elem[i], &tmpl[i + 1]))
1700 needs_comma = true;
1701 fprintf(out, ")\n");
1702 }
1703
1704 /**
1705 \brief Get the textual name for module-level named metadata.
1706 */
1707 static const char *
get_metadata_name(LL_MDName name)1708 get_metadata_name(LL_MDName name)
1709 {
1710 switch (name) {
1711 case MD_llvm_module_flags:
1712 return "!llvm.module.flags";
1713 case MD_llvm_dbg_cu:
1714 return "!llvm.dbg.cu";
1715 case MD_opencl_kernels:
1716 return "!opencl.kernels";
1717 case MD_nvvm_annotations:
1718 return "!nvvm.annotations";
1719 case MD_nvvmir_version:
1720 return "!nvvmir.version";
1721 default:
1722 interr("Unknown metadata name", name, ERR_Fatal);
1723 }
1724 return NULL;
1725 }
1726
1727 typedef const LL_MDNode *MDNodeRef;
1728
1729 static void emitRegular(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1730 static void emitDICompileUnit(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1731 static void emitDIFile(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1732 static void emitDIBasicType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1733 static void emitDIBasicStringType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1734 static void emitDIStringType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1735 static void emitDISubroutineType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1736 static void emitDIDerivedType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1737 static void emitDICompositeType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1738 static void emitDIFortranArrayType(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1739 static void emitDISubRange(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1740 static void emitDIFortranSubrange(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1741 static void emitDIEnumerator(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1742 static void emitDINamespace(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1743 static void emitDIModule(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1744 static void emitDIGlobalVariable(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1745 static void emitDISubprogram(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1746 static void emitDILexicalBlock(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1747 static void emitDILexicalBlockFile(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1748 static void emitDILocation(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1749 static void emitDILocalVariable(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1750 static void emitDIExpression(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1751 static void emitDIGlobalVariableExpression(FILE *, LLVMModuleRef, MDNodeRef,
1752 unsigned);
1753 static void emitDIImportedEntity(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1754 static void emitDICommonBlock(FILE *, LLVMModuleRef, MDNodeRef, unsigned);
1755
1756 typedef void (*MDDispatchMethod)(FILE *out, LLVMModuleRef mod, MDNodeRef mdnode,
1757 unsigned mdi);
1758
1759 typedef struct MDDispatch {
1760 MDDispatchMethod method;
1761 } MDDispatch;
1762
1763 static MDDispatch mdDispTable[LL_MDClass_MAX] = {
1764 {emitRegular}, // LL_PlainMDNode
1765 {emitDICompileUnit}, // LL_DICompileUnit
1766 {emitDIFile}, // LL_DIFile
1767 {emitDIBasicType}, // LL_DIBasicType
1768 {emitDISubroutineType}, // LL_DISubroutineType
1769 {emitDIDerivedType}, // LL_DIDerivedType
1770 {emitDICompositeType}, // LL_DICompositeType
1771 {emitDIFortranArrayType}, // LL_DIFortranArrayType
1772 {emitDISubRange}, // LL_DISubRange
1773 {emitDIFortranSubrange}, // LL_DIFortranSubrange
1774 {emitDIEnumerator}, // LL_DIEnumerator
1775 {emitRegular}, // LL_DITemplateTypeParameter
1776 {emitRegular}, // LL_DITemplateValueParameter
1777 {emitDINamespace}, // LL_DINamespace
1778 {emitDIModule}, // LL_DIModule
1779 {emitDIGlobalVariable}, // LL_DIGlobalVariable
1780 {emitDISubprogram}, // LL_DISubprogram
1781 {emitDILexicalBlock}, // LL_DILexicalBlock
1782 {emitDILexicalBlockFile}, // LL_DILexicalBlockFile
1783 {emitDILocation}, // LL_DILocation
1784 {emitDILocalVariable}, // LL_DILocalVariable
1785 {emitDIExpression}, // LL_DIExpression
1786 {emitRegular}, // LL_DIObjCProperty
1787 {emitDIImportedEntity}, // LL_DIImportedEntity
1788 {emitDIGlobalVariableExpression}, // LL_DIGlobalVariableExpression
1789 {emitDIBasicStringType}, // LL_DIBasicType_string - deprecated
1790 {emitDIStringType}, // LL_DIStringType
1791 {emitDICommonBlock}, // LL_DICommonBlock
1792 };
1793
1794 INLINE static void
emitRegularPrefix(FILE * out,unsigned mdi)1795 emitRegularPrefix(FILE *out, unsigned mdi)
1796 {
1797 fprintf(out, "!%u = ", mdi);
1798 }
1799
1800 /** Simple helper function */
1801 INLINE static bool
useSpecialized(LLVMModuleRef mod)1802 useSpecialized(LLVMModuleRef mod)
1803 {
1804 return ll_feature_use_specialized_mdnodes(&mod->ir);
1805 }
1806
1807 INLINE static void
emitRegular(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1808 emitRegular(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode, unsigned mdi)
1809 {
1810 emitRegularPrefix(out, mdi);
1811 write_mdnode_plain(out, mod, mdnode, ll_feature_omit_metadata_type(&mod->ir));
1812 }
1813
1814 INLINE static void
emitSpec(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi,const MDTemplate * tmpl)1815 emitSpec(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode, unsigned mdi,
1816 const MDTemplate *tmpl)
1817 {
1818 emitRegularPrefix(out, mdi);
1819 write_mdnode_spec(out, mod, mdnode, tmpl);
1820 }
1821
1822 INLINE static void
emitUnspec(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi,const MDTemplate * tmpl)1823 emitUnspec(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode, unsigned mdi,
1824 const MDTemplate *tmpl)
1825 {
1826 fputs("; ", out);
1827 emitSpec(out, mod, mdnode, mdi, tmpl);
1828 emitRegular(out, mod, mdnode, mdi);
1829 }
1830
1831 static void
emitTmpl(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi,const MDTemplate * tmpl)1832 emitTmpl(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode, unsigned mdi,
1833 const MDTemplate *tmpl)
1834 {
1835 if (useSpecialized(mod)) {
1836 emitSpec(out, mod, mdnode, mdi, tmpl);
1837 return;
1838 }
1839 emitUnspec(out, mod, mdnode, mdi, tmpl);
1840 }
1841
1842 static void
emitDICompileUnit(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1843 emitDICompileUnit(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1844 unsigned mdi)
1845 {
1846 if (ll_feature_debug_info_pre34(&mod->ir)) {
1847 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICompileUnit_pre34);
1848 return;
1849 }
1850 if (ll_feature_subprogram_not_in_cu(&mod->ir)) {
1851 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICompileUnit_ver39);
1852 return;
1853 }
1854 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICompileUnit);
1855 }
1856
1857 static void
emitDIFile(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1858 emitDIFile(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode, unsigned mdi)
1859 {
1860 if (ll_feature_debug_info_pre34(&mod->ir)) {
1861 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIFile_pre34);
1862 return;
1863 }
1864 if (LL_MDREF_kind(mdnode->elem[0]) == MDRef_String) {
1865 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIFile_pair);
1866 return;
1867 }
1868 emitUnspec(out, mod, mdnode, mdi, Tmpl_DIFile_tagged);
1869 }
1870
1871 static void
emitDIBasicType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1872 emitDIBasicType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1873 unsigned mdi)
1874 {
1875 if (ll_feature_debug_info_pre34(&mod->ir)) {
1876 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIBasicType_pre34);
1877 return;
1878 }
1879 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIBasicType);
1880 }
1881
1882 static void
emitDIStringType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1883 emitDIStringType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1884 unsigned mdi)
1885 {
1886 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIStringType);
1887 }
1888
1889 /* deprecated */
1890 static void
emitDIBasicStringType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1891 emitDIBasicStringType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1892 unsigned mdi)
1893 {
1894 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIStringType_old);
1895 }
1896
1897 static void
emitDISubroutineType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1898 emitDISubroutineType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1899 unsigned mdi)
1900 {
1901 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubroutineType);
1902 }
1903
1904 static void
emitDIDerivedType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1905 emitDIDerivedType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1906 unsigned mdi)
1907 {
1908 if (ll_feature_debug_info_pre34(&mod->ir)) {
1909 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIDerivedType_pre34);
1910 return;
1911 }
1912 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIDerivedType);
1913 }
1914
1915 static void
emitDICompositeType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1916 emitDICompositeType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1917 unsigned mdi)
1918 {
1919 if (ll_feature_debug_info_pre34(&mod->ir)) {
1920 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICompositeType_pre34);
1921 return;
1922 }
1923 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICompositeType);
1924 }
1925
1926 static void
emitDIFortranArrayType(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1927 emitDIFortranArrayType(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1928 unsigned mdi)
1929 {
1930 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIFortranArrayType);
1931 }
1932
1933 static void
emitDISubRange(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1934 emitDISubRange(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1935 unsigned mdi)
1936 {
1937 if (!ll_feature_debug_info_subrange_needs_count(&mod->ir)) {
1938 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubrange_pre37);
1939 return;
1940 }
1941 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubrange);
1942 }
1943
1944 static void
emitDIFortranSubrange(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1945 emitDIFortranSubrange(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1946 unsigned mdi)
1947 {
1948 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIFortranSubrange);
1949 }
1950
1951 static void
emitDIEnumerator(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1952 emitDIEnumerator(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1953 unsigned mdi)
1954 {
1955 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIEnumerator);
1956 }
1957
1958 static void
emitDINamespace(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1959 emitDINamespace(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1960 unsigned mdi)
1961 {
1962 if (ll_feature_debug_info_pre34(&mod->ir)) {
1963 emitTmpl(out, mod, mdnode, mdi, Tmpl_DINamespace_pre34);
1964 return;
1965 }
1966 if (ll_feature_no_file_in_namespace(&mod->ir)) {
1967 emitTmpl(out, mod, mdnode, mdi, Tmpl_DINamespace_5);
1968 return;
1969 }
1970 emitTmpl(out, mod, mdnode, mdi, Tmpl_DINamespace_post34);
1971 }
1972
1973 static void
emitDIModule(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnd,unsigned mdi)1974 emitDIModule(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnd, unsigned mdi)
1975 {
1976 emitTmpl(out, mod, mdnd, mdi, Tmpl_DIModule);
1977 }
1978
1979 static void
emitDIGlobalVariable(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1980 emitDIGlobalVariable(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1981 unsigned mdi)
1982 {
1983 if (ll_feature_from_global_to_md(&mod->ir)) {
1984 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIGlobalVariable4);
1985 return;
1986 }
1987 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIGlobalVariable);
1988 }
1989
1990 static void
emitDISubprogram(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)1991 emitDISubprogram(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
1992 unsigned mdi)
1993 {
1994 if (!ll_feature_debug_info_pre34(&mod->ir)) {
1995 if (ll_feature_debug_info_ver70(&mod->ir)) {
1996 // 7.0, 'variables:' was removed
1997 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubprogram_70);
1998 return;
1999 }
2000 if (ll_feature_subprogram_not_in_cu(&mod->ir)) {
2001 // 3.9, 'unit:' was added
2002 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubprogram_39);
2003 return;
2004 }
2005 if (ll_feature_debug_info_ver38(&mod->ir)) {
2006 // 3.8, 'function:' was removed
2007 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubprogram_38);
2008 return;
2009 }
2010 emitTmpl(out, mod, mdnode, mdi, Tmpl_DISubprogram);
2011 return;
2012 }
2013 emitRegular(out, mod, mdnode, mdi);
2014 }
2015
2016 static void
emitDILexicalBlock(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2017 emitDILexicalBlock(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2018 unsigned mdi)
2019 {
2020 if (ll_feature_debug_info_pre34(&mod->ir)) {
2021 emitTmpl(out, mod, mdnode, mdi, Tmpl_DILexicalBlock_pre34);
2022 return;
2023 }
2024 emitTmpl(out, mod, mdnode, mdi, Tmpl_DILexicalBlock);
2025 }
2026
2027 static void
emitDILexicalBlockFile(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2028 emitDILexicalBlockFile(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2029 unsigned mdi)
2030 {
2031 emitTmpl(out, mod, mdnode, mdi, Tmpl_DILexicalBlockFile);
2032 }
2033
2034 static void
emitDILocation(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2035 emitDILocation(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2036 unsigned mdi)
2037 {
2038 const MDTemplate *tmpl = ll_feature_debug_info_DI_syntax(&mod->ir)
2039 ? Tmpl_DILocation
2040 : Tmpl_MDLocation;
2041 if (ll_feature_debug_info_mdlocation(&mod->ir)) {
2042 emitTmpl(out, mod, mdnode, mdi, tmpl);
2043 return;
2044 }
2045 emitUnspec(out, mod, mdnode, mdi, tmpl);
2046 }
2047
2048 static void
emitDILocalVariable(FILE * out,LLVMModuleRef mod,const LL_MDNode * node,unsigned mdi)2049 emitDILocalVariable(FILE *out, LLVMModuleRef mod, const LL_MDNode *node,
2050 unsigned mdi)
2051 {
2052 if (ll_feature_dbg_local_variable_embeds_argnum(&mod->ir)) {
2053 emitTmpl(out, mod, node, mdi, Tmpl_DILocalVariable_embedded_argnum);
2054 return;
2055 }
2056 if (ll_feature_debug_info_ver38(&mod->ir)) {
2057 // 3.8, 'tag:' was removed
2058 emitTmpl(out, mod, node, mdi, Tmpl_DILocalVariable_38);
2059 return;
2060 }
2061 emitTmpl(out, mod, node, mdi, Tmpl_DILocation);
2062 }
2063
2064 static void
emitDIImportedEntity(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2065 emitDIImportedEntity(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2066 unsigned mdi)
2067 {
2068 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIImportedEntity);
2069 }
2070
2071 static void
emitDICommonBlock(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2072 emitDICommonBlock(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2073 unsigned mdi)
2074 {
2075 emitTmpl(out, mod, mdnode, mdi, Tmpl_DICommonBlock);
2076 }
2077
2078 INLINE static const char *
ll_dw_op_to_name(LL_DW_OP_t op)2079 ll_dw_op_to_name(LL_DW_OP_t op)
2080 {
2081 switch (op) {
2082 case LL_DW_OP_deref:
2083 return "DW_OP_deref";
2084 case LL_DW_OP_plus:
2085 return "DW_OP_plus";
2086 case LL_DW_OP_minus:
2087 return "DW_OP_minus";
2088 case LL_DW_OP_dup:
2089 return "DW_OP_dup";
2090 case LL_DW_OP_LLVM_fragment:
2091 return "DW_OP_LLVM_fragment";
2092 case LL_DW_OP_swap:
2093 return "DW_OP_swap";
2094 case LL_DW_OP_xderef:
2095 return "DW_OP_xderef";
2096 case LL_DW_OP_stack_value:
2097 return "DW_OP_stack_value";
2098 case LL_DW_OP_constu:
2099 return "DW_OP_constu";
2100 case LL_DW_OP_plus_uconst:
2101 return "DW_OP_plus_uconst";
2102 default:
2103 break;
2104 }
2105 DEBUG_ASSERT(false, "unhandled LL_DW_OP_t");
2106 return "*bug*";
2107 }
2108
2109 INLINE static const char *
decode_expression_op(LLVMModuleRef mod,LL_MDRef md,char * buff)2110 decode_expression_op(LLVMModuleRef mod, LL_MDRef md, char *buff)
2111 {
2112 int value;
2113 bool isLiteralOp;
2114
2115 if (LL_MDREF_kind(md) == MDRef_Constant) {
2116 strcpy(buff, mod->constants[LL_MDREF_value(md)]->data);
2117 return buff;
2118 }
2119 DEBUG_ASSERT(LL_MDREF_kind(md) == MDRef_SmallInt32, "not int");
2120 value = LL_MDREF_value(md);
2121 isLiteralOp = value & 1;
2122 value >>= 1;
2123 if (isLiteralOp)
2124 return ll_dw_op_to_name((LL_DW_OP_t)value);
2125 sprintf(buff, "%d", value);
2126 return buff;
2127 }
2128
2129 static void
emitComplexDIExpression(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2130 emitComplexDIExpression(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2131 unsigned mdi)
2132 {
2133 unsigned i;
2134 unsigned cnt = mdnode->num_elems;
2135 char buff[32];
2136
2137 emitRegularPrefix(out, mdi);
2138 fputs("!DIExpression(", out);
2139 for (i = 0; i < cnt; ++i) {
2140 if (i > 0)
2141 fputs(", ", out);
2142 fputs(decode_expression_op(mod, mdnode->elem[i], buff), out);
2143 }
2144 fputs(")\n", out);
2145 }
2146
2147 static void
emitDIExpression(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2148 emitDIExpression(FILE *out, LLVMModuleRef mod, const LL_MDNode *mdnode,
2149 unsigned mdi)
2150 {
2151 if (useSpecialized(mod)) {
2152 if (mdnode->num_elems > 0) {
2153 emitComplexDIExpression(out, mod, mdnode, mdi);
2154 return;
2155 }
2156 emitSpec(out, mod, mdnode, mdi, Tmpl_DIExpression);
2157 return;
2158 }
2159 if (mdnode->num_elems > 0) {
2160 fputs("; ", out);
2161 emitComplexDIExpression(out, mod, mdnode, mdi);
2162 }
2163 emitUnspec(out, mod, mdnode, mdi, Tmpl_DIExpression);
2164 }
2165
2166 static void
emitDIGlobalVariableExpression(FILE * out,LLVMModuleRef mod,const LL_MDNode * mdnode,unsigned mdi)2167 emitDIGlobalVariableExpression(FILE *out, LLVMModuleRef mod,
2168 const LL_MDNode *mdnode, unsigned mdi)
2169 {
2170 emitTmpl(out, mod, mdnode, mdi, Tmpl_DIGlobalVariableExpression);
2171 }
2172
2173 static void
write_metadata_node(FILE * out,LLVMModuleRef module,MDNodeRef node,unsigned mdi)2174 write_metadata_node(FILE *out, LLVMModuleRef module, MDNodeRef node,
2175 unsigned mdi)
2176 {
2177 const LL_MDClass mdClass = node->mdclass;
2178 DEBUG_ASSERT(mdClass < LL_MDClass_MAX, "mdclass out of bounds");
2179 mdDispTable[mdClass].method(out, module, node, mdi);
2180 }
2181
2182 #ifdef __cplusplus
2183 inline LL_MDName
NextMDName(LL_MDName & name)2184 NextMDName(LL_MDName &name)
2185 {
2186 name = static_cast<LL_MDName>(static_cast<unsigned>(name) + 1);
2187 return name;
2188 }
2189 #else
2190 #define NextMDName(N) ++(N)
2191 #endif
2192
2193 /**
2194 \brief Write out all the module metadata
2195
2196 Write out all the so-called named metadata and then the regular metadata
2197 */
2198 void
ll_write_metadata(FILE * out,LLVMModuleRef module)2199 ll_write_metadata(FILE *out, LLVMModuleRef module)
2200 {
2201 LL_MDName i;
2202 int j;
2203
2204 fprintf(out, "\n; Named metadata\n");
2205 for (i = MD_llvm_module_flags; i < MD_NUM_NAMES; NextMDName(i)) {
2206 const LL_MDNode *node = module->named_mdnodes[i];
2207 if (node) {
2208 fprintf(out, "%s = ", get_metadata_name(i));
2209 write_mdnode_plain(out, module, node, /* omit_metadata_type = */ true);
2210 }
2211 }
2212
2213 fprintf(out, "\n; Metadata\n");
2214 for (j = 0; j < module->mdnodes_count; j++) {
2215 write_metadata_node(out, module, module->mdnodes[j], j + 1);
2216 }
2217 }
2218
2219 void
ll_write_global_var_signature(FILE * out,LL_Value * variable)2220 ll_write_global_var_signature(FILE *out, LL_Value *variable)
2221 {
2222 if (variable->mvtype == LL_GLOBAL) {
2223 fprintf(out, "global [0 x double]*");
2224 } else {
2225 fprintf(out, "%s*", variable->type_struct->str);
2226 }
2227 fprintf(out, " %s", variable->data);
2228 }
2229
2230 /**
2231 \brief Write definition of the special <code>\@llvm.used</code> global
2232 */
2233 void
ll_write_llvm_used(FILE * out,LLVMModuleRef module)2234 ll_write_llvm_used(FILE *out, LLVMModuleRef module)
2235 {
2236 unsigned i;
2237
2238 if (!module->num_llvm_used)
2239 return;
2240
2241 fprintf(out, "@llvm.used = appending global [%u x i8*] [\n ",
2242 module->num_llvm_used);
2243 for (i = 0; i < module->num_llvm_used; i++) {
2244 LL_Value *ptr = module->llvm_used.values[i];
2245 if (i)
2246 fprintf(out, ",\n ");
2247 fprintf(out, "%s %s", ptr->type_struct->str, ptr->data);
2248 }
2249 fprintf(out, "\n], section \"llvm.metadata\"\n");
2250 }
2251 #ifdef OMP_OFFLOAD_LLVM
ll_build_metadata_device(FILE * out,LLVMModuleRef module)2252 void ll_build_metadata_device(FILE *out, LLVMModuleRef module)
2253 {
2254 LL_Function *function;
2255 /* Create kernel descriptors. */
2256 for (function = module->first; function; function = function->next) {
2257 LLMD_Builder mdb;
2258
2259 if (!function->is_kernel)
2260 continue;
2261
2262 mdb = llmd_init(module);
2263 llmd_add_value(mdb, ll_get_function_pointer(module, function));
2264 llmd_add_string(mdb, "kernel");
2265 llmd_add_i32(mdb, 1);
2266 ll_extend_named_md_node(module, MD_nvvm_annotations, llmd_finish(mdb));
2267
2268 mdb = llmd_init(module);
2269 llmd_add_value(mdb, ll_get_function_pointer(module, function));
2270 if (function->launch_bounds > 0) {
2271 llmd_add_string(mdb, "maxntidx");
2272 llmd_add_i32(mdb, function->launch_bounds);
2273 llmd_add_string(mdb, "maxntidy");
2274 llmd_add_i32(mdb, 1);
2275 llmd_add_string(mdb, "maxntidz");
2276 llmd_add_i32(mdb, 1);
2277 }
2278 //dunno whether I need it or not at the moment
2279 //ll_extend_named_md_node(module, MD_nvvm_annotations, llmd_finish(mdb));
2280 }
2281 }
2282 #endif
2283 /**
2284 \brief Write out definitions or declarations of global LL_Objects.
2285
2286 If this function is called more than once, only the new objects added since
2287 the last call will be written.
2288 */
2289 void
ll_write_global_objects(FILE * out,LLVMModuleRef module)2290 ll_write_global_objects(FILE *out, LLVMModuleRef module)
2291 {
2292 LL_Object *object;
2293
2294 for (object = module->first_global; object; object = object->next) {
2295 int addrspace = ll_get_pointer_addrspace(object->address.type_struct);
2296
2297 fprintf(out, "%s =", object->address.data);
2298
2299 /* TBD: [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
2300 * [unnamed_addr] */
2301
2302 if (addrspace && object->kind != LLObj_Alias)
2303 fprintf(out, " addrspace(%d)", addrspace);
2304
2305 /* Linkage */
2306 if (object->linkage != LL_EXTERNAL_LINKAGE)
2307 fprintf(out, " %s", ll_get_linkage_string(object->linkage));
2308
2309 /* Kind */
2310 switch (object->kind) {
2311 case LLObj_Global:
2312 fprintf(out, " global ");
2313 break;
2314 case LLObj_Const:
2315 fprintf(out, " constant ");
2316 break;
2317 case LLObj_Alias:
2318 fprintf(out, " alias ");
2319 break;
2320 default:
2321 interr("ll_write_global_objects: invalid global kind", object->kind,
2322 ERR_Fatal);
2323 }
2324
2325 /* Print an initializer following the type. */
2326 switch (object->init_style) {
2327 case LLInit_Declaration:
2328 fprintf(out, "%s", object->type->str);
2329 break;
2330 case LLInit_Zero:
2331 fprintf(out, "%s zeroinitializer", object->type->str);
2332 break;
2333 case LLInit_ConstExpr:
2334 fprintf(out, "%s %s", object->init_data.const_expr->type_struct->str,
2335 object->init_data.const_expr->data);
2336 break;
2337 case LLInit_Function:
2338 /* Call the provided function pointer which will print out the
2339 * initializer with the leading type. */
2340 object->init_data.function(out, object);
2341 break;
2342 }
2343
2344 /* Alignment */
2345 if (object->align_bytes)
2346 fprintf(out, ", align %u", object->align_bytes);
2347
2348 /* TBD: [, section "name"] [, comdat ...] */
2349 fprintf(out, "\n");
2350 }
2351
2352 /* Reset the list of global objects so this function can be called multiple
2353 * times without creating duplicates. */
2354 module->first_global = NULL;
2355 module->last_global = NULL;
2356 }
2357
2358 void
ll_write_module(FILE * out,LL_Module * module,int generate_no_return_variants,const char * no_return_prefix)2359 ll_write_module(FILE *out, LL_Module *module, int generate_no_return_variants, const char *no_return_prefix)
2360 {
2361 int i, j, met_idx;
2362 LL_Function *function = module->first;
2363 int num_functions;
2364
2365 clear_prototypes();
2366
2367 ll_write_module_header(out, module);
2368
2369 fprintf(out, "; Begin User structs\n");
2370 ll_write_user_structs(out, module);
2371 fprintf(out, "; End User structs\n\n");
2372
2373 fprintf(out, "; Begin module variables\n");
2374 /* HACKERY */
2375 for (i = 0; i < module->num_module_vars; i++) {
2376 const char *linkage_string;
2377 int addrspace;
2378 const char *type_str;
2379 const char *initializer;
2380
2381 switch (module->module_vars.values[i]->linkage) {
2382 case LL_EXTERNAL_LINKAGE:
2383 initializer = "";
2384 break;
2385 case LL_COMMON_LINKAGE:
2386 initializer = "zeroinitializer";
2387 break;
2388 case LL_INTERNAL_LINKAGE:
2389 initializer = "zeroinitializer";
2390 break;
2391 case LL_NO_LINKAGE:
2392 initializer = "zeroinitializer";
2393 break;
2394 case LL_WEAK_LINKAGE:
2395 /* ICE */
2396 initializer = "";
2397 break;
2398 }
2399 linkage_string =
2400 ll_get_linkage_string(module->module_vars.values[i]->linkage);
2401
2402 if (module->module_vars.values[i]->mvtype == LL_GLOBAL) {
2403 fprintf(out, "%s = external addrspace(%d) global [0 x double]\n",
2404 module->module_vars.values[i]->data,
2405 module->module_vars.values[i]->type_struct->addrspace);
2406 } else if (module->module_vars.values[i]->mvtype == LL_DEVICE) {
2407 unsigned int align_val;
2408
2409 align_val = module->module_vars.values[i]->align_bytes;
2410 if (align_val == 0) {
2411 /* Enforce alignment to 16-bytes, if no alignment specified */
2412 align_val = 16;
2413 }
2414 fprintf(out, "%s = %s addrspace(1) global %s %s, align %u\n",
2415 module->module_vars.values[i]->data, linkage_string,
2416 module->module_vars.values[i]->type_struct->str, initializer,
2417 align_val);
2418 } else if (module->module_vars.values[i]->mvtype == LL_CONSTANT) {
2419 fprintf(out, "%s = %s addrspace(4) global %s %s, align 16\n",
2420 module->module_vars.values[i]->data, linkage_string,
2421 module->module_vars.values[i]->type_struct->str, initializer);
2422 } else if (module->module_vars.values[i]->linkage == LL_EXTERNAL_LINKAGE) {
2423 fprintf(out, "%s = %s addrspace(%d) global %s\n",
2424 module->module_vars.values[i]->data, linkage_string,
2425 (module->module_vars.values[i]->storage
2426 ? module->module_vars.values[i]
2427 ->storage->type_struct->sub_types[0]
2428 ->addrspace
2429 : 0),
2430 module->module_vars.values[i]->type_struct->str);
2431 } else {
2432 char align_str[80];
2433 switch (module->module_vars.values[i]->type_struct->data_type) {
2434 case LL_I1:
2435 case LL_I8:
2436 case LL_I16:
2437 case LL_I32:
2438 case LL_I64:
2439 case LL_FLOAT:
2440 case LL_DOUBLE:
2441 case LL_PTR:
2442 if (module->module_vars.values[i]->flags & VAL_IS_TEXTURE)
2443 linkage_string = "";
2444 break;
2445 default:
2446 break;
2447 }
2448 addrspace = 0;
2449 if (module->module_vars.values[i]->storage) {
2450 addrspace = module->module_vars.values[i]
2451 ->storage->type_struct->sub_types[0]
2452 ->addrspace;
2453 }
2454 align_str[0] = '\0';
2455 if (module->module_vars.values[i]->align_bytes)
2456 sprintf(align_str, ", align %d",
2457 module->module_vars.values[i]->align_bytes);
2458 fprintf(out, "%s = %s addrspace(%d) global %s %s%s\n",
2459 module->module_vars.values[i]->data, linkage_string, addrspace,
2460 module->module_vars.values[i]->type_struct->str, initializer,
2461 align_str);
2462 }
2463 }
2464 ll_write_global_objects(out, module);
2465 /* TODO: This needs to be enabled generally */
2466 ll_write_llvm_used(out, module);
2467 fprintf(out, "; End module variables\n\n");
2468
2469 if (generate_no_return_variants) {
2470 fprintf(out, "declare void @llvm.nvvm.exit() noreturn\n");
2471 }
2472 num_functions = 0;
2473 while (function) {
2474 ll_write_function(out, function, module, false, "");
2475 if (generate_no_return_variants) {
2476 ll_write_function(out, function, module, true, no_return_prefix);
2477 }
2478 function = function->next;
2479 num_functions++;
2480 }
2481 write_prototypes(out, module);
2482 ll_write_metadata(out, module);
2483 }
2484