Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

IL Overview

The Intermediate Language (IL) is EDG's central data structure -- a typed, scope-linked graph of every declaration, type, expression, statement, and template in the translation unit. cudafe++ (EDG 6.6) builds the IL during parsing, walks it for CUDA device/host separation, and emits it as the .int.c output. The IL never touches disk: IL_SHOULD_BE_WRITTEN_TO_FILE=0 forces in-memory-only operation. All IL nodes live in a region-based arena allocator, organized into file-scope (region 1) and per-function (region N) memory pools.

The IL is versioned as IL_VERSION_NUMBER="6.6" and carries the compile-time flag ALL_TEMPLATE_INFO_IN_IL=1, meaning template definitions, specializations, and instantiation directives are fully represented in the IL graph rather than deferred to a separate template database.

Key Configuration Constants

ConstantValueMeaning
IL_VERSION_NUMBER"6.6"IL format version, matches EDG version
IL_SHOULD_BE_WRITTEN_TO_FILE0IL is never serialized to disk
ALL_TEMPLATE_INFO_IN_IL1Full template data in IL graph
IL_FILE_SUFFIX(string)Suffix for IL file names if serialization were enabled
sizeof_il_entry sentinel9999Validated at init time (guard value in qword_E6C580)

IL Entry Kind System

Every IL node carries an entry_kind byte that identifies its type. The name table off_E6DD80 (aliased as il_entry_kind_names at off_E6E020) maps these bytes to human-readable strings. The il_one_time_init function (sub_5CF7F0) validates that this table ends with a "last" sentinel.

There are 85 defined entry kind values (0-84). Some are primary node types with their own linked lists; others are auxiliary records displayed inline by their parent.

Complete il_entry_kind Table

KindHexNameBytesDisplayNotes
00x00none----Null/invalid sentinel
10x01source_file_entry80Case 1File name, line ranges, include flags
20x02constant184Case 216 sub-kinds (ck_*)
30x03param_type80Case 3Parameter type in function signature
40x04routine_type_supplement64InlineEmbedded in routine type node
50x05routine_type_extra--InlineAdditional routine type data
60x06type176Case 622 sub-kinds (tk_*)
70x07variable232Case 7Variables, parameters, structured bindings
80x08field176Case 8Class/struct/union members
90x09exception_specification16Case 9noexcept, throw() specs
100x0Aexception_spec_type24Case 0xAType in exception specification
110x0Broutine288Case 0xBFunctions, methods, constructors, destructors
120x0Clabel128Case 0xCGoto labels, break/continue targets
130x0Dexpr_node72Case 0xD36 sub-kinds (enk_*)
140x0E(reserved)--InlineSkipped in display
150x0F(reserved)--InlineSkipped in display
160x10switch_case_entry56Case 0x10Case value + range for switch
170x11switch_info24Case 0x11Switch statement descriptor
180x12handler40Case 0x12try/catch handler entry
190x13try_supplement32InlineTry block extra info
200x14asm_supplement--InlineInline asm statement data
210x15statement80Case 0x1526 sub-kinds (stmk_*)
220x16object_lifetime64Case 0x16Destruction ordering
230x17scope288Case 0x179 sub-kinds (sck_*)
240x18base_class112Case 0x18Inheritance record
250x19string_text1*--Raw string literal bytes
260x1Aother_text1*--Compiler version, misc text
270x1Btemplate_parameter136Case 0x1BTemplate param with supplement
280x1Cnamespace128Case 0x1CNamespace declarations
290x1Dusing_declaration80Case 0x1DUsing declarations/directives
300x1Edynamic_init104Case 0x1E9 sub-kinds (dik_*)
310x1Flocal_static_variable_init40Case 0x1FStatic local init records
320x20vla_dimension48Case 0x20Variable-length array bound
330x21overriding_virtual_func40Case 0x21Virtual override info
340x22(reserved)--InlineSkipped in display
350x23derivation_path24Case 0x23Base-class derivation step
360x24base_class_derivation32--Derivation detail record
370x25(reserved)--InlineSkipped in display
380x26(reserved)--InlineSkipped in display
390x27class_info208Case 0x27Class type supplement
400x28(reserved)----Skipped in display
410x29constructor_init48Case 0x29Ctor member/base initializer
420x2Aasm_entry152Case 0x2AInline assembly block
430x2Basm_operand--Case 0x2BAsm constraint + expression
440x2Casm_clobber--Case 0x2CAsm clobber register
450x2D(reserved)--InlineSkipped in display
460x2E(reserved)--InlineSkipped in display
470x2F(reserved)--InlineSkipped in display
480x30(reserved)--InlineSkipped in display
490x31element_position24--Designator element position
500x32source_sequence_entry32Case 0x32Declaration ordering
510x33full_entity_decl_info56Case 0x33Full declaration info
520x34instantiation_directive40Case 0x34Explicit instantiation
530x35src_seq_sublist24Case 0x35Source sequence sub-list
540x36explicit_instantiation_decl--Case 0x36extern template
550x37orphaned_entities56Case 0x37Entities without parent scope
560x38hidden_name32Case 0x38Hidden name entry
570x39pragma64Case 0x39Pragma records (43 kinds)
580x3Atemplate208Case 0x3ATemplate declaration
590x3Btemplate_decl40Case 0x3BTemplate declaration head
600x3Crequires_clause16Case 0x3CC++20 requires clause
610x3Dtemplate_param136Case 0x3DTemplate parameter entry
620x3Ename_reference40Case 0x3EName lookup reference
630x3Fname_qualifier40Case 0x3FQualified name qualifier
640x40seq_number_lookup32Case 0x40Sequence number index
650x41local_expr_node_ref--Case 0x41Local expression reference
660x42static_assert24Case 0x42Static assertion
670x43linkage_spec32Case 0x43extern "C"/"C++" block
680x44scope_ref32Case 0x44Scope back-reference
690x45(reserved)--InlineSkipped in display
700x46lambda--Case 0x46Lambda expression
710x47lambda_capture--Case 0x47Lambda capture entry
720x48attribute72Case 0x48C++11/GNU attribute
730x49attribute_argument40Case 0x49Attribute argument
740x4Aattribute_group8Case 0x4AAttribute group
750x4B(reserved)--InlineSkipped in display
760x4C(reserved)--InlineSkipped in display
770x4D(reserved)--InlineSkipped in display
780x4E(reserved)--InlineSkipped in display
790x4Ftemplate_info--Case 0x4FTemplate instantiation info
800x50subobject_path24Case 0x50Address constant sub-path
810x51(reserved)--InlineSkipped in display
820x52module_info--Case 0x52C++20 module metadata
830x53module_decl--Case 0x53Module declaration
840x54last----Sentinel for table validation

Inline entries (kinds 4, 5, 14, 15, 19, 20, 27, 34, 37, 38, 40, 45-48, 69, 75-78, 81) are displayed as part of their parent node rather than as standalone IL entries. The display dispatcher (sub_5F4930) returns immediately for these kinds.

IL Header Structure

The IL header lives in the BSS segment at 0x126EB60 and is printed by display_il_header_and_file_scope (sub_5F76B0). It records translation-unit-level metadata:

struct il_header {                        // at xmmword_126EB60
    il_entry*   primary_source_file;      // +0x00  head of source file list
    scope*      primary_scope;            // +0x08  file-scope root
    routine*    main_routine;             // +0x10  main() if present
    char*       compiler_version;         // +0x18  "6.6" version string
    char*       time_of_compilation;      // +0x20  build timestamp
    uint8_t     plain_chars_are_signed;   // +0x28  signedness of plain char
    uint32_t    source_language;          // +0x2C  0=C++, 1=C (dword_126EBA8)
    uint32_t    std_version;             // +0x30  e.g. 201703 (dword_126EBAC)
    uint8_t     pcc_compatibility_mode;   // +0x34  PCC compat flag
    uint8_t     enum_type_is_integral;    // +0x35
    uint32_t    default_max_member_align; // +0x38
    uint8_t     gcc_mode;                // +0x3C  GCC compatibility
    uint8_t     gpp_mode;                // +0x3D  G++ compatibility
    uint32_t    gnu_version;             // +0x40  e.g. 40201
    uint8_t     short_enums;             // +0x44
    uint8_t     default_nocommon;         // +0x45
    uint8_t     UCN_identifiers_used;     // +0x46
    uint8_t     vla_used;                // +0x47
    uint8_t     any_templates_seen;       // +0x48
    uint8_t     prototype_instantiations_in_il;     // +0x49
    uint8_t     il_has_all_prototype_instantiations; // +0x4A
    uint8_t     il_has_C_semantics;       // +0x4B
    uint8_t     nontag_types_used_in_exception_or_rtti; // +0x4C
    il_entry*   seq_number_lookup_entries; // +0x50
    uint32_t    target_configuration_index; // +0x58
};

The source_language field selects the display string "sl_Cplusplus" or "sl_C". When source_language == 1 (C mode) and std_version > 199900, the routine display additionally prints C99 pragma state fields (fp_contract, fenv_access, cx_limited_range).

Memory Region System

IL entries are allocated in numbered memory regions managed by a bump allocator (sub_6B7D60):

RegionPurposeLifetimeGlobals
1File scopeEntire translation unitdword_126EC90 (region ID), dword_126F690/dword_126F694 (base offset / prefix size)
2..NPer-function scopeDuration of function body processingdword_126EB40 (current region), dword_126F688/dword_126F68C (base offset / prefix size)

Region 1 contains all file-scope declarations: types, global variables, function declarations, namespaces, templates. Regions 2+ are allocated one per function definition and hold that function's local variables, statements, expressions, labels, and temporaries. The region table at qword_126EC88 maps region indices to their memory, while qword_126EB90 maps region indices to their associated scope entries. dword_126EC80 tracks the total number of regions.

The allocator selects file-scope vs function-scope by comparing dword_126EB40 == dword_126EC90. When equal, the node goes into region 1; otherwise it goes into the current function region. Some node types force a specific region:

  • Labels (alloc_label at sub_5E5CA0): Assert that the current region is NOT file scope
  • Templates (alloc_template at sub_5E8D20): Always file-scope only
  • Sequence number lookups (sub_5E9170): Force region 1 by temporarily setting TU-copy mode

The display system (sub_5F7DF0) iterates all regions:

// File scope
printf("Intermediate language for memory region 1 (file scope):");
walk_file_scope_il(display_il_entry, ...);   // sub_60E4F0

// Per-function regions
for (int r = 2; r <= region_count; r++) {
    scope* s = scope_table[r];
    routine* fn = s->assoc_routine;
    printf("Intermediate language for memory region %ld (function \"%s\"):",
           r, fn->name);
    walk_routine_scope_il(r, display_il_entry, ...);  // sub_610200
}

IL Entry Prefix

Every IL node has a multi-qword prefix preceding the node body. The prefix size depends on allocation mode: 24 bytes (3 qwords) in normal file-scope mode, 16 bytes (2 qwords) in TU-copy mode, and 8 bytes (1 qword) for function-scope allocations. The allocator (sub_6B7D60) allocates a contiguous block and the caller returns a pointer past the prefix, so the prefix occupies negative offsets from the returned node pointer.

Normal file-scope mode (dword_106BA08 == 0, dword_126F694 = 24):

Raw allocation layout (normal file-scope, 24-byte prefix):
Offset  Size  Field
------  ----  -----
+0      8     translation_unit_copy_address   (qword, zeroed in normal mode)
+8      8     next_in_list                    (qword, linked list pointer)
+16     8     prefix flags qword              (flags byte at +16, 7 bytes padding)
+24     ...   node body starts here           (returned pointer)

Node pointer perspective (ptr = raw + 24):
ptr - 24  = TU copy address   (8 bytes at raw+0)
ptr - 16  = next pointer       (8 bytes at raw+8)
ptr - 8   = prefix flags byte  (8 bytes at raw+16, flags in low byte)
ptr + 0   = first byte of node body

TU-copy mode (dword_106BA08 != 0, dword_126F694 = 16):

Raw allocation layout (TU-copy mode, 16-byte prefix):
+0      8     next_in_list                    (no TU copy slot)
+8      8     prefix flags qword
+16     ...   node body starts here           (returned pointer)

Function-scope allocations (dword_126F68C = 8):

Raw allocation layout (function-scope, 8-byte prefix):
+0      8     prefix flags qword              (no TU copy, no orphan slot)
+8      ...   node body starts here           (returned pointer)

The prefix flags byte is at ptr - 8 from the returned node pointer (in all modes). The next_in_list pointer at ptr - 16 is the linked list link used by the IL walker to traverse all entries of a given kind (file-scope only). The translation_unit_copy_address at ptr - 24 stores the original address when a node is copied between translation units; it is zeroed in normal mode and absent in TU-copy and function-scope modes.

The keep_in_il test throughout cudafe++ uses *(signed char*)(entry - 8) < 0 to check bit 7 of the prefix flags byte -- this works because the flags byte is always at offset -8 from the node pointer regardless of allocation mode.

Prefix Flags Byte

The prefix flags byte (at offset -8 from the returned node pointer) encodes scope and language information:

BitMaskNameMeaning
00x01allocatedAlways set on allocation
10x02file_scopeSet when !dword_106BA08 (not in TU-copy mode)
20x04is_in_secondary_ilEntry came from secondary translation unit
30x08language_flagCopies dword_126E5FC & 1 (C++ vs C mode indicator)
70x80keep_in_ilCUDA-critical: marks entry for device IL output

Bit 7 (keep_in_il) is the mechanism by which cudafe++ selects device-relevant declarations. The mark_to_keep_in_il pass in il_walk.c sets this bit on all entries that are needed for device compilation. See Device/Host Separation and keep-in-il for details.

Sub-Kind Systems

Most primary IL entry kinds use a secondary kind byte to discriminate between variants. These sub-kind enums are the core classification taxonomy of the IL.

Type Kinds (tk_*)

The type kind byte lives at offset +132 in the type node body. 22 values, dispatched by set_type_kind (sub_5E2E80) and displayed by display_type (sub_5F06B0):

ValueNameSupplementSizeNotes
0tk_error----Error/placeholder type
1tk_void----void
2tk_integerinteger_type_supplement32int, char, bool, enum, wchar_t, char8/16/32_t
3tk_float----float, double, long double
4tk_complex----_Complex float/double/ldouble
5tk_imaginary----_Imaginary (C99)
6tk_pointer----Pointer, reference, rvalue reference
7tk_routineroutine_type_supplement64Function type (return + params)
8tk_array----Fixed and variable-length arrays
9tk_classclass_type_supplement208class types
10tk_structclass_type_supplement208struct types
11tk_unionclass_type_supplement208union types
12tk_typereftyperef_type_supplement56typedef, using, decltype, typeof
13tk_ptr_to_member----Pointer-to-member
14tk_template_paramtempl_param_supplement40Template type parameter
15tk_vector----SIMD vector type
16tk_scalable_vector----Scalable vector (SVE)
17tk_nullptr----std::nullptr_t
18tk_mfp8----8-bit floating point
19tk_scalable_vector_count----Scalable vector predicate
20(auto/decltype_auto)----Placeholder types
21(typeof_unqual/typeof_type)----C23 typeof

The display function references off_A6FE40 (22 string entries) for type kind names. The typeref sub-kind table at off_A6F640 has 28 entries covering typedef aliases, decltype expressions, auto, and concept-constrained placeholders.

Constant Kinds (ck_*)

The constant kind byte lives at offset +148 in the constant node. 16 values, dispatched by display_constant (sub_5F2720):

ValueNameNotes
0ck_errorError placeholder
1ck_integerInteger value (arbitrary precision via sub_602F20)
2ck_stringString/character literal (char kind + length + raw bytes)
3ck_floatFloating-point constant
4ck_complexComplex constant (real + imaginary)
5ck_imaginaryImaginary constant
6ck_addressAddress constant with 7 address sub-kinds (abk_*)
7ck_ptr_to_memberPointer-to-member constant
8ck_label_differenceGNU label address difference
9ck_dynamic_initDynamically initialized constant
10ck_aggregateAggregate initializer (linked list of sub-constants)
11ck_init_repeatRepeated initializer (constant + count)
12ck_template_paramTemplate parameter constant with 15 sub-kinds (tpck_*)
13ck_designatorDesignated initializer
14ck_voidVoid constant
15ck_reflectionReflection entity reference

Address constant sub-kinds (abk_*): abk_routine, abk_variable, abk_constant, abk_temporary, abk_uuidof, abk_typeid, abk_label.

Template parameter constant sub-kinds (tpck_*): tpck_param, tpck_expression, tpck_member, tpck_unknown_function, tpck_address, tpck_sizeof, tpck_datasizeof, tpck_alignof, tpck_uuidof, tpck_typeid, tpck_noexcept, tpck_template_ref, tpck_integer_pack, tpck_destructor.

Expression Node Kinds (enk_*)

The expression kind byte lives at offset +24 in the expression node. 36 values, dispatched by display_expr_node (sub_5ECFE0):

ValueNameNotes
0enk_errorError expression
1enk_operationBinary/unary/ternary operation (120 operator sub-kinds via eok_*)
2enk_constantConstant reference
3enk_variableVariable reference
4enk_fieldField access
5enk_temp_initTemporary initialization
6enk_lambdaLambda expression
7enk_new_deletenew/delete expression (56-byte supplement)
8enk_throwthrow expression (24-byte supplement)
9enk_conditionConditional expression (32-byte supplement)
10enk_object_lifetimeObject lifetime management
11enk_typeidtypeid expression
12enk_sizeofsizeof expression
13enk_sizeof_packsizeof...(pack)
14enk_alignofalignof expression
15enk_datasizeofNVIDIA __datasizeof extension
16enk_address_of_ellipsisAddress of variadic parameter
17enk_statementStatement expression (GCC extension)
18enk_reuse_valueReused value reference
19enk_routineFunction reference
20enk_type_operandType as operand (e.g., in sizeof)
21enk_builtin_operationCompiler builtin (indexed via off_E6C5A0)
22enk_param_refParameter reference
23enk_braced_init_listC++11 braced init list
24enk_c11_genericC11 _Generic selection
25enk_builtin_choose_exprGCC __builtin_choose_expr
26enk_yieldC++20 co_yield
27enk_awaitC++20 co_await
28enk_fold_expressionC++17 fold expression
29enk_initializerInitializer expression
30enk_concept_idC++20 concept-id
31enk_requiresC++20 requires expression
32enk_compound_reqCompound requirement
33enk_nested_reqNested requirement
34enk_const_eval_deferredDeferred constexpr evaluation
35enk_template_nameTemplate name expression

The enk_operation kind (value 1) carries an additional operation.kind byte dispatched through off_A6F840 (120 entries, the eok_* enum) and an operation.type_kind byte from off_A6FE40 (22 entries).

Expression Operation Kinds (eok_*)

The 120+ operation kinds cover all C++ operators. Key groups:

CategoryOperations
Arithmeticeok_add, eok_subtract, eok_multiply, eok_divide, eok_remainder, eok_negate, eok_unary_plus
Bitwiseeok_and, eok_or, eok_xor, eok_complement, eok_shiftl, eok_shiftr
Comparisoneok_eq, eok_ne, eok_lt, eok_gt, eok_le, eok_ge, eok_spaceship
Logicaleok_land, eok_lor, eok_not
Assignmenteok_assign, eok_add_assign, eok_subtract_assign, eok_multiply_assign, etc.
Pointereok_indirect, eok_address_of, eok_padd, eok_psubtract, eok_pdiff, eok_subscript
Member accesseok_dot_field, eok_points_to_field, eok_dot_static, eok_points_to_static, eok_pm_field, eok_points_to_pm_call
Castseok_cast, eok_lvalue_cast, eok_ref_cast, eok_dynamic_cast, eok_bool_cast, eok_base_class_cast, eok_derived_class_cast
Callseok_call, eok_dot_member_call, eok_points_to_member_call, eok_dot_pm_call, eok_points_to_pm_func_ptr
Incrementeok_pre_incr, eok_pre_decr, eok_post_incr, eok_post_decr
Complexeok_real_part, eok_imag_part, eok_xconj
Vectoreok_vector_fill, eok_vector_eq, eok_vector_ne, eok_vector_lt, eok_vector_gt, eok_vector_le, eok_vector_ge, eok_vector_subscript, eok_vector_question, eok_vector_land, eok_vector_lor, eok_vector_not
Controleok_comma, eok_question, eok_parens, eok_lvalue, eok_lvalue_adjust, eok_noexcept
Variadiceok_va_start, eok_va_end, eok_va_arg, eok_va_copy, eok_va_start_single_operand
Virtualeok_virtual_function_ptr, eok_dot_vacuous_destructor_call, eok_points_to_vacuous_destructor_call
Misceok_array_to_pointer, eok_reference_to, eok_ref_indirect, eok_ref_dynamic_cast, eok_pm_base_class_cast, eok_pm_derived_class_cast, eok_class_rvalue_adjust

Statement Kinds (stmk_*)

The statement kind byte lives at offset +32 in the statement node. 26 values:

ValueNameSupplementNotes
0stmk_expr--Expression statement
1stmk_if--if statement
2stmk_constexpr_if24 bytesif constexpr (C++17)
3stmk_if_consteval--if consteval (C++23)
4stmk_if_not_consteval--if !consteval (C++23)
5stmk_while--while loop
6stmk_goto--goto statement
7stmk_label--Label statement
8stmk_return--return statement
9stmk_coroutine128 bytesC++20 coroutine body (full coroutine descriptor)
10stmk_coroutine_return--co_return statement
11stmk_block32 bytesCompound statement / block
12stmk_end_test_while--do-while loop
13stmk_for24 bytesfor loop
14stmk_range_based_for--C++11 range-for (iterator, begin, end, incr)
15stmk_switch_case--case label
16stmk_switch24 bytesswitch statement
17stmk_init--Declaration with initializer
18stmk_asm--Inline assembly
19stmk_try_block32 bytestry block
20stmk_decl--Declaration statement
21stmk_set_vla_size--VLA size computation
22stmk_vla_decl--VLA declaration
23stmk_assigned_goto--GCC computed goto
24stmk_empty--Empty statement
25stmk_stmt_expr_result--GCC statement expression result

The coroutine statement (kind 9) carries the largest supplement at 128 bytes, containing traits, handle, promise, initial/final suspend calls, unhandled_exception call, get_return_object call, new/delete routines, and parameter copies. A preserved typo in the EDG source reads "paramter_copies" (missing 'e'), confirming genuine EDG lineage.

Scope Kinds (sck_*)

The scope kind byte lives at offset +28 in the scope node. 9 observed values:

ValueNameNotes
0sck_fileFile scope (translation unit root)
1sck_func_prototypeFunction prototype scope
2sck_blockBlock scope (compound statement)
3sck_namespaceNamespace scope
6sck_class_struct_unionClass/struct/union scope
8sck_template_declarationTemplate declaration scope
15sck_conditionCondition scope (if/while/for condition variable)
16sck_enumEnum scope (C++11 scoped enums)
17sck_functionFunction body scope (has routine ptr, parameters, ctor inits)

Scope kinds determine which child lists are displayed. The bitmask (1 << kind) & 0x20044 (bits 2, 6, 17 = block, class/struct/union, function) and (1 << kind) & 0x9 (bits 0, 3 = file, namespace) control whether namespaces, using_declarations, and using_directives lists appear.

Dynamic Init Kinds (dik_*)

The dynamic init kind byte lives at offset +48. 9 values:

ValueNameNotes
0dik_noneNo initialization
1dik_zeroZero initialization
2dik_constantConstant initializer
3dik_expressionExpression initializer
4dik_class_result_via_ctorClass value via constructor call
5dik_constructorConstructor call (routine + args)
6dik_nonconstant_aggregateNon-constant aggregate init
7dik_bitwise_copyBitwise copy from source
8dik_lambdaLambda initialization

Common IL Node Header

All primary IL node types (type, variable, field, routine, scope, namespace, template, etc.) share a 96-byte common header copied from a template at xmmword_126F6A0..126F6F0. This header is initialized by init_il_alloc (sub_5EAD80) and contains:

  • Source correspondence (source_corresp) block: name, position, parent scope, access specifier, linkage, flags
  • The display function display_source_corresp (sub_5EDF40) prints these fields for every entity type

Key source correspondence fields (printed for all entities):

  • name and unmangled_name_or_mangled_encoding
  • decl_position (line + column)
  • name_references list
  • is_class_member + access (from off_A6F760: public/protected/private/none)
  • parent_scope and enclosing_routine
  • name_linkage (from off_E6E040: none/internal/external/C/C++)
  • Flags: referenced, needed, is_local_to_function, marked_as_gnu_extension, externalized, maybe_unused, is_deprecated_or_unavailable

Initialization and Reset

The IL subsystem initializes in two phases:

One-Time Init (sub_5CF7F0)

Called once at program startup. Validates 7 name-table arrays end with "last" sentinels:

TableAddressContent
il_entry_kind_namesoff_E6E02085 IL entry kind names
db_storage_class_namesoff_E6CD78Storage class enum names
db_special_function_kindsoff_E6D228Special function kind names
db_operator_namesoff_E6CD20Operator kind names
name_linkage_kind_namesoff_E6E060Linkage kind names
decl_modifier_namesoff_E6CD88Declaration modifier names
pragma_idsoff_E6CF38Pragma identifier names

Also validates unsigned_int_kind_of table (byte_E6D1AD == 111 == 'o') and initializes 60+ allocation pools via sub_7A3C00 (pool_init) with element sizes ranging from 1 to 1344 bytes.

Per-TU Init (sub_5CFE20)

Called at the start of each translation unit compilation. Zeroes all pool heads, allocates the constant-sharing hash table (16,312 bytes = 2,039 buckets at qword_126F228), and the character-type hash table (3,240 bytes at qword_126F2F8). Sets sharing mode flags (byte_126E558..126E55A = 3). Tail-calls sub_5EAF00 to reset float constant caches.

Secondary Pool Reset (sub_5D0170)

Resets ~80 transient globals in the 126F680..126F978 range between template instantiation passes. Pure state zeroing, no allocation.

Constant Sharing

IL constants are deduplicated via a 2,039-bucket hash table at qword_126F228. The alloc_shareable_constant function (sub_5D2390) checks constant_is_shareable (sub_5D2210) -- which excludes aggregate constants (kind 10), template parameter constants (kind 12), and string literals when string sharing is disabled (dword_126E1C0).

On a cache hit, the existing constant is relinked to the front of its bucket chain. On a miss, a new 184-byte constant is allocated and inserted. Statistics are tracked: total allocations (qword_126F208), comparisons (qword_126F200), region hits (qword_126F218), global hits (qword_126F220), and new buckets (qword_126F210).

CUDA Extensions to IL

NVIDIA adds several CUDA-specific fields to standard EDG IL nodes:

  • Routine flags (bytes 182-183): nvvm_intrinsic, global (global), device (device), host (host)
  • Variable flags: shared (shared), constant (constant), device (device), managed (managed)
  • keep_in_il bit (prefix byte bit 7): The mechanism for device/host code separation
  • Lambda entries (kinds 0x46, 0x47): Extended lambda wrapper support

These extensions are what make cudafe++ the CUDA-aware C++ frontend rather than a stock EDG compiler.

Function Map

AddressFunctionSourceNotes
sub_5CF7F0il_one_time_initil.cValidates tables, inits 60+ pools
sub_5CFE20il_init / il_resetil.cPer-TU initialization
sub_5D0170il_reset_secondary_poolsil.cTemplate instantiation reset
sub_5D01F0il_rebuild_entry_indexil.cBuild entry pointer index
sub_5D02F0il_invalidate_entry_indexil.cClear entry index
sub_5D0750compare_expressionsil.cDeep structural equality
sub_5D1350compare_constantsil.cConstant comparison (525 lines)
sub_5D1FE0compare_dynamic_initsil.cDynamic init comparison
sub_5D2210constant_is_shareableil.cShareability predicate
sub_5D2390alloc_shareable_constantil.cHash-table dedup allocation
sub_5D2F90i_copy_expr_treeil.cDeep expression tree copy
sub_5D3B90i_copy_constant_fullil.cDeep constant copy
sub_5D47A0i_copy_dynamic_initil.cDeep dynamic init copy
sub_5E2E80set_type_kindil_alloc.cType kind dispatch (22 kinds)
sub_5E3D40alloc_typeil_alloc.c176-byte type node
sub_5E4D20alloc_variableil_alloc.c232-byte variable node
sub_5E4F70alloc_fieldil_alloc.c176-byte field node
sub_5E53D0alloc_routineil_alloc.c288-byte routine node
sub_5E5CA0alloc_labelil_alloc.c128-byte label node
sub_5E5F00set_expr_node_kindil_alloc.cExpression kind dispatch
sub_5E62E0alloc_expr_nodeil_alloc.c72-byte expression node
sub_5E6E20set_statement_kindil_alloc.cStatement kind dispatch
sub_5E7060alloc_statementil_alloc.c80-byte statement node
sub_5E7D80alloc_scopeil_alloc.c288-byte scope node
sub_5E7A70alloc_namespaceil_alloc.c128-byte namespace node
sub_5E8D20alloc_templateil_alloc.c208-byte template node
sub_5E99D0dump_il_table_statisticsil_alloc.cPrint allocation stats
sub_5EAD80init_il_allocil_alloc.cInitialize common header template
sub_5F4930display_il_entryil_to_str.cMain display dispatcher (~1,686 lines)
sub_5F76B0display_il_header_and_file_scopeil_to_str.cIL header + region 1
sub_5F7DF0display_il_fileil_to_str.cTop-level display entry point
sub_60E4F0walk_file_scope_ilil_walk.cFile-scope tree walker
sub_610200walk_routine_scope_ilil_walk.cPer-function tree walker

Cross-References