1 /* 2 * Copyright (c) 2015-2018, 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 #ifndef LLASSEM_H_ 19 #define LLASSEM_H_ 20 21 #include "gbldefs.h" 22 #include "global.h" 23 #include "symtab.h" 24 #include "llutil.h" 25 26 typedef struct DTLIST { 27 LL_Type *lltype; 28 int byval; 29 30 /* XXX: sptr needs to go away, since fortran sptrs are only relevant for 31 * the function being compiled. This is for homing 32 * (process_formal_arguments) support. Which should only be called when 33 * this sptr data is valid. 34 */ 35 SPTR sptr; 36 struct DTLIST *tail; 37 struct DTLIST *next; 38 } DTLIST; 39 40 typedef struct uplevelpair { 41 int oldsptr; /* sptr from ilm file */ 42 SPTR newsptr; /* newsptr - from symbolxref[oldsptr] */ 43 int newmem; /* sptr member of struct for newsptr */ 44 } UPLEVEL_PAIR; 45 46 #define STACK_CAN_BE_32_BYTE_ALIGNED (aux.curr_entry->flags & 0x200) 47 #define ENFORCE_32_BYTE_STACK_ALIGNMENT (aux.curr_entry->flags |= 0x400) 48 49 #define IS_STABS (XBIT(120, 0x20)) 50 #define ASMFIL gbl.asmfil 51 52 /** general length suitable for creating names from a symbol name during 53 assembly, e.g., 1 for null, 3 for extra '_' , * 4 for @### with mscall */ 54 #define MXIDLN (3 * MAXIDLEN + 10) 55 56 /** 57 * structure to represent items being dinit'd -- used to generate 58 * a sorted list of dinit items for a given common block or local 59 * variable. 60 */ 61 typedef struct DSRT { 62 SPTR sptr; ///< sym being init'd (could be structure) 63 ISZ_T offset; ///< byte offset of item init'd 64 int sectionindex; ///< Fortran - section index 65 long filepos; ///< Fortran dinit file position for item's dinit(s) 66 int func_count; ///< Fortran save/restore func_count 67 DTYPE dtype; ///< used for C 68 int len; ///< used for C - character 69 ISZ_T conval; ///< used for C 70 struct DSRT *next; ///< next in list (sorted in ascending offset) 71 struct DSRT *ladd; ///< item last added - not used in C 72 } DSRT; 73 74 char *get_local_overlap_var(void); 75 char *put_next_member(char *ptr); 76 ISZ_T put_skip(ISZ_T old, ISZ_T New); 77 78 /* 79 * macros to get and put DSRT pointers in symbol table entry - this 80 * uses the XREF field 81 */ 82 #define DSRTG(s) ((DSRT *)get_getitem_p(XREFLKG(s))) 83 #define DSRTP(s, v) XREFLKP(s, put_getitem_p(v)) 84 85 #define GET_DSRT (DSRT *)getitem(2, sizeof(DSRT)) 86 87 /* structures and routines to process assembler globals for the entire file */ 88 89 #define AG_HASHSZ 19 90 #define AG_SIZE(s) agb.s_base[s].size 91 #define AG_ALIGN(s) agb.s_base[s].align 92 #define AG_DSIZE(s) agb.s_base[s].dsize 93 #define AG_SYMLK(s) agb.s_base[s].symlk 94 #define AG_HASHLK(s) agb.s_base[s].hashlk 95 #define AG_NMPTR(s) agb.s_base[s].nmptr 96 #define AG_TYPENMPTR(s) agb.s_base[s].type_nmptr 97 #define AG_OLDNMPTR(s) agb.s_base[s].old_nmptr 98 #define AG_TYPEDESC(s) agb.s_base[s].typedesc /* Boolean */ 99 #define AG_STYPE(s) agb.s_base[s].stype 100 #define AG_RET_LLTYPE(s) agb.s_base[s].ret_lltype 101 #define AG_LLTYPE(s) agb.s_base[s].lltype 102 #define AG_DTYPE(s) agb.s_base[s].dtype 103 #define AG_DTYPESC(s) agb.s_base[s].dtypesc 104 #define AG_SC(s) agb.s_base[s].sc /* Storage class */ 105 #define AG_ALLOC(s) agb.s_base[s].alloc 106 #define AG_REF(s) agb.s_base[s].ref 107 #define AG_DEFD(s) agb.s_base[s].defd 108 #define AG_DEVICE(s) agb.s_base[s].device 109 #define AG_ISMOD(s) agb.s_base[s].ismod 110 #define AG_ISTLS(s) agb.s_base[s].istls 111 #define AG_NEEDMOD(s) agb.s_base[s].needmod 112 #define AG_ISCTOR(s) agb.s_base[s].ctor 113 #define AG_ISIFACE(s) agb.s_base[s].iface 114 #define AG_FINAL(s) agb.s_base[s].final 115 #define AG_UPLEVEL_AVL(s) agb.s_base[s].uplevel_avl 116 #define AG_UPLEVEL_SZ(s) agb.s_base[s].uplevel_sz 117 #define AG_UPLEVELPTR(s) agb.s_base[s].uplist 118 #define AG_UPLEVEL_OLD(s, i) agb.s_base[s].uplist[i].oldsptr 119 #define AG_UPLEVEL_NEW(s, i) agb.s_base[s].uplist[i].newsptr 120 #define AG_UPLEVEL_MEM(s, i) agb.s_base[s].uplist[i].newmem 121 #define AG_DLL(s) agb.s_base[s].dll 122 #define AG_NAME(s) agb.n_base + agb.s_base[s].nmptr 123 #define AG_TYPENAME(s) agb.n_base + agb.s_base[s].type_nmptr 124 #define AG_OLDNAME(s) agb.n_base + agb.s_base[s].old_nmptr 125 #define AG_ARGDTLIST(s) agb.s_base[s].argdtlist 126 #define AG_ARGDTLIST_LENGTH(s) agb.s_base[s].n_argdtlist 127 #define AG_ARGDTLIST_IS_VALID(s) agb.s_base[s].argdtlist_is_set 128 #define AG_OBJTODBGLIST(s) agb.s_base[s].cmblk_mem_mdnode_list 129 130 #define FPTR_HASHLK(s) fptr_local.s_base[s].hashlk 131 #define FPTR_IFACENMPTR(s) fptr_local.s_base[s].ifacenmptr 132 #define FPTR_IFACENM(s) fptr_local.n_base + fptr_local.s_base[s].ifacenmptr 133 #define FPTR_NMPTR(s) fptr_local.s_base[s].nmptr 134 #define FPTR_NAME(s) fptr_local.n_base + fptr_local.s_base[s].nmptr 135 #define FPTR_SYMLK(s) fptr_local.s_base[s].symlk 136 137 LL_Value *gen_ptr_offset_val(int, LL_Type *, char *); 138 139 /** 140 \brief llassem global symbol table entries 141 */ 142 typedef struct { 143 ISZ_T size; /**< max size of common block in file 144 if entry/proc, 1 => defd, 0 => proc */ 145 ISZ_T dsize; /**< size of common block when init'd */ 146 INT nmptr; 147 INT type_nmptr; /**< Used for external function */ 148 INT farg_nmptr; /**< make all function that is not defined in same file 149 vararg with first argument specified if any */ 150 INT old_nmptr; /**< Used for interface to keep original function name */ 151 INT align; /**< alignment for BIND(C) variables */ 152 int symlk; /**< used to link ST_CMBLK and ST_PROC */ 153 SPTR hashlk; /**< hash collision field */ 154 int dtype; /**< used for keep track dtype which is created for static/ 155 bss area (only for AGL ag-local) */ 156 int dtypesc; /**< dtype scope */ 157 int n_argdtlist; /**< Number of items in argdtlist */ 158 bool argdtlist_is_set; /**< Argdtlist has built, perhaps with 0 args */ 159 char stype; /**< ST_ of global */ 160 char sc; /**< SC_ of global */ 161 char alloc; /**< ALLOCATABLE flag */ 162 char dll; /**< DLL_NONE, DLL_EXPORT, DLL_IMPORT */ 163 LL_Type *lltype; /**< LLVM representation of the ag symbol */ 164 LL_Type *ret_lltype; /**< If this is a func this is the return type */ 165 DTLIST *argdtlist; /**< linked listed of argument lltype */ 166 LL_ObjToDbgList *cmblk_mem_mdnode_list; ///< linked listed of cmem mdnode 167 int uplevel_avl; 168 int uplevel_sz; 169 UPLEVEL_PAIR *uplist; /**< uplevel list for internal procecure */ 170 unsigned ref : 1; /**< ST_PROC is referenced */ 171 unsigned defd : 1; /**< module ST_CMBLK is defined in file */ 172 unsigned device : 1; /**< CUDA device routine */ 173 unsigned ismod : 1; 174 unsigned needmod : 1; 175 unsigned ctor : 1; /**< set if this routine has attribute constructor */ 176 unsigned typedesc : 1; /**< set if this variable is a type descriptor */ 177 unsigned iface : 1; /**< set if this is part of interface */ 178 unsigned final : 1; /**< set if this is final table */ 179 unsigned istls : 1; /**< set if this is TLS */ 180 } AG; 181 182 /** 183 \brief storage allocation structure for assem's symtab 184 */ 185 typedef struct AGB_t { 186 AG *s_base; /**< pointer to table of common block nodes */ 187 int s_size; /**< size of CM table */ 188 int s_avl; /**< currently available entry */ 189 char *n_base; /**< pointer to names space */ 190 int n_size; 191 int n_avl; 192 SPTR hashtb[AG_HASHSZ]; 193 } AGB_t; 194 195 extern AGB_t agb; 196 197 /** similar to AG struct but smaller */ 198 typedef struct { 199 INT nmptr; 200 INT ifacenmptr; 201 int hashlk; 202 int symlk; 203 } FPTRSYM; 204 205 /** storage for function pointer */ 206 typedef struct fptr_local_t { 207 FPTRSYM *s_base; 208 int s_size; 209 int s_avl; 210 char *n_base; /* pointer to names space */ 211 int n_size; 212 int n_avl; 213 int hashtb[AG_HASHSZ]; 214 } fptr_local_t; 215 216 extern fptr_local_t fptr_local; 217 218 extern DSRT *lcl_inits; /* head list of DSRT's for local variables */ 219 extern DSRT *section_inits; /* head list of DSRT's for initialized 220 variables in named sections */ 221 extern DSRT *extern_inits; /* head list of DSRT's for BIND(C) module 222 variables */ 223 extern char static_name[MXIDLN]; /* name of STATIC area for a function */ 224 extern int first_data; 225 226 struct sec_t { 227 const char *name; 228 int align; 229 }; 230 231 /* ag entries */ 232 extern int ag_cmblks; /* list of common blocks in file */ 233 extern int ag_procs; /* list of procs in file */ 234 extern int ag_other; /* list of other externals in file */ 235 extern int ag_global; /* list of symbols that need to be declared 236 global */ 237 extern int ag_typedef; /* list of derived type that need to be 238 declared */ 239 extern int ag_static; /* keep name and type of static */ 240 extern int ag_intrin; /* intrinsic list generated by the bridge and 241 has no sptr */ 242 extern int ag_local; /* dummy arguments which is a subroutine - 243 need its signature and type */ 244 extern int ag_funcptr; /* list of function pointer - should be a member 245 of user defined type. Currently keep both 246 LOCAL(any?) and STATIC in same list */ 247 248 void put_i32(int); 249 void put_string_n(char *, ISZ_T, int); 250 void put_short(int); 251 void put_int4(INT); 252 253 #if defined(TARGET_LLVM_X8664) || defined(TARGET_LLVM_POWER) || defined(TARGET_LLVM_ARM64) 254 #define DIR_LONG_SIZE 64 255 #else 256 #define DIR_LONG_SIZE 32 257 #endif 258 259 #define MAXARGLEN 256 260 261 void ll_override_type_string(LL_Type *llt, const char *str); 262 int alignment(DTYPE); 263 int add_member_for_llvm(int, int, DTYPE, ISZ_T); 264 LL_Type *update_llvm_typedef(DTYPE dtype, int sptr, int rank); 265 int llvm_get_unique_sym(void); 266 void align_func(void); 267 void put_global(char *name); 268 void put_func_name(int sptr); 269 void put_type(int sptr); 270 void init_huge_tlb(void); 271 void init_flushz(void); 272 void init_daz(void); 273 void init_ktrap(void); 274 ISZ_T get_socptr_offset(int); 275 #if defined(PG0CL) 276 #define llassem_end_func(ignore1, arg2) assem_end_func(arg2) 277 #else 278 #define llassem_end_func(arg1, arg2) lldbg_function_end(arg1, arg2) 279 #endif 280 281 LL_Type *make_generic_dummy_lltype(void); 282 LL_Type *get_local_overlap_vartype(void); 283 284 #ifdef OMP_OFFLOAD_LLVM 285 /** 286 \brief ... 287 */ 288 void ompaccel_write_sharedvars(void); 289 #endif 290 291 /** 292 \brief ... 293 */ 294 bool get_byval_from_argdtlist(const char *argdtlist); 295 296 /** 297 \brief ... 298 */ 299 bool has_typedef_ag(int gblsym); 300 301 /** 302 \brief ... 303 */ 304 bool is_llvmag_entry(int gblsym); 305 306 /** 307 \brief ... 308 */ 309 bool is_llvmag_iface(int gblsym); 310 311 /** 312 \brief ... 313 */ 314 bool is_typedesc_defd(SPTR sptr); 315 316 /** 317 \brief ... 318 */ 319 char *getaddrdebug(SPTR sptr); 320 321 /** 322 \brief ... 323 */ 324 char *get_ag_name(int gblsym); 325 326 /** 327 \brief ... 328 */ 329 char *get_ag_typename(int gblsym); 330 331 /** 332 \brief ... 333 */ 334 char *get_argdtlist(int gblsym); 335 336 /** 337 \brief return external name for procedure 338 */ 339 char *getextfuncname(SPTR sptr); 340 341 /** 342 \brief ... 343 */ 344 char *get_llvm_name(SPTR sptr); 345 346 /** 347 \brief ... 348 */ 349 char *get_main_progname(void); 350 351 /** 352 \brief ... 353 */ 354 char *get_next_argdtlist(char *argdtlist); 355 356 /** 357 \brief ... 358 */ 359 char *getsname(SPTR sptr); 360 361 /** 362 \brief ... 363 */ 364 char *get_string_constant(int sptr); 365 366 /** 367 \brief ... 368 */ 369 DTYPE get_ftn_typedesc_dtype(SPTR sptr); 370 371 /** 372 \brief ... 373 */ 374 int add_ag_typename(int gblsym, const char *typeName); 375 376 /** 377 \brief ... 378 */ 379 SPTR find_ag(const char *ag_name); 380 381 /** 382 \brief ... 383 */ 384 int find_funcptr_name(SPTR sptr); 385 386 /** 387 \brief ... 388 */ 389 int get_ag_argdtlist_length(int gblsym); 390 391 /** 392 \brief ... 393 */ 394 SPTR get_ag(SPTR sptr); 395 396 /** 397 \brief ... 398 */ 399 int get_bss_addr(void); 400 401 /** 402 \brief ... 403 */ 404 SPTR get_dummy_ag(SPTR sptr); 405 406 /** 407 \brief ... 408 */ 409 int get_hollerith_size(int sptr); 410 411 /** 412 \brief ... 413 */ 414 SPTR get_intrin_ag(char *ag_name, DTYPE dtype); 415 416 /** 417 \brief ... 418 */ 419 SPTR get_llvm_funcptr_ag(SPTR sptr, const char *ag_name); 420 421 /** 422 \brief ... 423 */ 424 int get_private_size(void); 425 426 /** 427 \brief ... 428 */ 429 SPTR get_sptr_from_argdtlist(char *argdtlist); 430 431 /** 432 \brief ... 433 */ 434 int get_sptr_uplevel_address(int sptr); 435 436 /** 437 \brief ... 438 */ 439 int get_stack_size(void); 440 441 /** 442 \brief ... 443 */ 444 SPTR get_typedef_ag(char *ag_name, char *typeName); 445 446 /** 447 \brief ... 448 */ 449 int get_uplevel_address_size(void); 450 451 /** 452 \brief ... 453 */ 454 int has_valid_ag_argdtlist(int gblsym); 455 456 /** 457 \brief determine if the address represented by \p syma, an address constant, 458 is cache aligned. 459 */ 460 int is_cache_aligned(SPTR syma); 461 462 /** 463 \brief ... 464 */ 465 int ll_shallow_copy_uplevel(SPTR hostsptr, SPTR olsptr); 466 467 /** 468 Return the AG number associated to the local sptr value: 469 1) Search local-fnptr-table of function pointers 470 2) Get the ag name from (1) 471 3) Get the gblsym using the ag name from (2) 472 4) Return the AG gblsym from (3) 473 */ 474 SPTR local_funcptr_sptr_to_gblsym(SPTR sptr); 475 476 /** 477 \brief ... 478 */ 479 DTYPE make_uplevel_arg_struct(void); 480 481 /** 482 \brief the 32-byte alignment of the address constant \p acon_sptr 483 \param acon_sptr 484 \return the alignment or -1 if it's unknown. 485 */ 486 int runtime_32_byte_alignment(SPTR acon_sptr); 487 488 /** 489 \brief determine the alignment of the address represented by syma, an address 490 constant, within a cache-aligned container 491 492 \return -1 if unknown or the byte boundary of the address 493 494 For example, given a single precision quantity and a container which is 495 16-byte aligned the following values are possible: 496 \li 0 aligned with the beginning of the container. 497 \li 4 multiple of 4 bytes from the beginning of the container. 498 \li 8 multiple of 8 bytes from the beginning of the container. 499 \li 12 multiple of 12 bytes from the beginning of the container. 500 */ 501 int runtime_alignment(SPTR syma); 502 503 /** 504 \brief ... 505 */ 506 LL_ObjToDbgList **llassem_get_objtodbg_list(SPTR sptr); 507 508 /** 509 \brief ... 510 */ 511 LL_Type *get_ag_lltype(int gblsym); 512 513 /** 514 \brief ... 515 */ 516 LL_Type *get_ag_return_lltype(int gblsym); 517 518 /** 519 \brief ... 520 */ 521 LL_Type *get_lltype_from_argdtlist(char *argdtlist); 522 523 /** 524 \brief ... 525 */ 526 unsigned align_of_var(SPTR sptr); 527 528 /** 529 If arg_num in [1-n] where 1 is the first argument passed and the function 530 contains n arguments. If arg_num is 0, the function's return value. 531 532 Called by build_routine_parameters() 533 */ 534 void addag_llvm_argdtlist(SPTR gblsym, int arg_num, SPTR arg_sptr, 535 LL_Type *lltype); 536 537 /** 538 \brief ... 539 */ 540 void add_aguplevel_oldsptr(void); 541 542 /** 543 \brief ... 544 */ 545 void _add_llvm_uplevel_symbol(int oldsptr); 546 547 /** 548 \brief ... 549 */ 550 void add_uplevel_to_host(int *ptr, int cnt); 551 552 /** 553 \brief ... 554 */ 555 void arg_is_refd(int sptr); 556 557 /** 558 \brief ... 559 */ 560 void assem_begin_func(SPTR sptr); 561 562 /** 563 \brief ... 564 */ 565 void assemble_end(void); 566 567 /** 568 \brief ... 569 */ 570 void assemble_init(int argc, char *argv[], char *cmdline); 571 572 /** 573 \brief ... 574 */ 575 void assemble(void); 576 577 /** 578 \brief ... 579 */ 580 void assem_data(void); 581 582 /** 583 \brief ... 584 */ 585 void assem_dinit(void); 586 587 /** 588 \brief ... 589 */ 590 void assem_emit_align(int n); 591 592 /** 593 \brief ... 594 */ 595 void assem_emit_file_line(int findex, int lineno); 596 597 /** 598 \brief ... 599 */ 600 void assem_emit_line(int findex, int lineno); 601 602 /** 603 \brief ... 604 */ 605 void assem_end(void); 606 607 /** 608 \brief ... 609 */ 610 void assem_init(void); 611 612 /** 613 \brief ... 614 */ 615 void assem_put_linux_trace(int sptr); 616 617 /** 618 \brief ... 619 */ 620 void create_static_base(int num); 621 622 /** 623 \brief ... 624 */ 625 void create_static_name(char *name, int usestatic, int num); 626 627 /** 628 \brief ... 629 */ 630 void deleteag_llvm_argdtlist(int gblsym); 631 632 /** 633 \brief ... 634 */ 635 void fix_equiv_locals(SPTR loc_list, ISZ_T loc_addr); 636 637 /** 638 \brief ... 639 */ 640 void fix_equiv_statics(SPTR loc_list, ISZ_T loc_addr, bool dinitflg); 641 642 /** 643 \brief ... 644 */ 645 void fix_private_sym(int sptr); 646 647 /** 648 \brief ... 649 */ 650 void _fixup_llvm_uplevel_symbol(void); 651 652 /** 653 \brief ... 654 */ 655 void hostsym_is_refd(SPTR sptr); 656 657 /** 658 \brief ... 659 */ 660 void llvm_funcptr_store(SPTR sptr, char *ag_name); 661 662 /** 663 \brief ... 664 */ 665 void load_uplevel_addresses(SPTR display_temp); 666 667 /** 668 \brief ... 669 */ 670 void put_fstr(SPTR sptr, int add_null); 671 672 /** 673 \brief ... 674 */ 675 void put_section(int sect); 676 677 /** 678 \brief ... 679 */ 680 void set_ag_argdtlist_is_valid(int gblsym); 681 682 /** 683 \brief ... 684 */ 685 void set_ag_lltype(int gblsym, LL_Type *llt); 686 687 /** 688 \brief ... 689 */ 690 void set_ag_return_lltype(int gblsym, LL_Type *llt); 691 692 /** 693 \brief ... 694 */ 695 void set_bss_addr(int size); 696 697 /** 698 \brief ... 699 */ 700 void set_llvmag_entry(int gblsym); 701 702 /** 703 \brief ... 704 */ 705 void set_llvm_iface_oldname(int gblsym, char *nm); 706 707 /** 708 \brief ... 709 */ 710 void set_private_size(ISZ_T sz); 711 712 /** 713 \brief ... 714 */ 715 void sym_is_refd(SPTR sptr); 716 717 /** 718 \brief Writes libomptarget related initialization. 719 */ 720 void write_libomtparget(void); 721 722 #endif 723