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

PTX-to-Ori Lowering

All addresses in this page apply to ptxas v13.0.88 (CUDA 13.0). Other versions will differ.

The PTX-to-Ori lowering is the transition from parsed PTX assembly into the Ori internal representation -- the SASS-level, virtual-register IR that all subsequent optimization operates on. Unlike a traditional compiler where the parser builds an AST and a separate lowering pass consumes it, ptxas has no materialized AST: the Bison parser's reduction actions directly construct Ori IR nodes, basic blocks, and CFG edges inline. What the --compiler-stats timer calls "DAGgen-time" measures this inline construction phase. The result is a raw Ori IR that still uses PTX-derived opcodes and has unresolved architecture-dependent constructs. Fourteen "bridge phases" (pipeline indices 0--13) then transform this raw IR into the optimizer-ready form where every instruction carries its final SASS opcode, the CFG is fully annotated, and architecture-incompatible operations have been legalized.

The key architectural consequence of this design: there is no separate "lowering" function that you can point at and say "this converts PTX to Ori." The conversion is distributed across (1) the Bison parser's 443 reduction actions, (2) a 44 KB operand processing function, (3) the MercConverter instruction legalization pass, and (4) six additional bridge phases that handle FP16 promotion, control flow canonicalization, macro fusion, and recipe application.

DAGgen timer"DAGgen-time : %.3f ms (%.2f%%)\n" (inline Bison -> Ori construction)
Bison parsersub_4CE6B0 (48 KB, 512 productions, 443 reductions, no AST)
Operand processingsub_6273E0 (44 KB, 6-bit operand type switch)
MercConvertersub_9F1A90 (35 KB, opcode-dispatched visitor)
MercConverter orchestratorsub_9F3340 (7 KB)
Opcode dispatchsub_9ED2D0 (25 KB, master switch on *(instr+72) & 0xCF)
Post-conversion loweringsub_9EF5E0 (27 KB, string "CONVERTING")
Bridge phasesPhases 0--13 (14 phases, first group in the 159-phase pipeline)
Diagnostic dumpPhase 9: ReportInitialRepresentation (sub_A3A7E0 stats emitter)
Intrinsic descriptorssub_9EE390 (20 KB, "IntrinsicDescrFile=%s")

Architecture

PTX source text
     |
     v
[Flex scanner]  sub_720F00 (15.8KB, 552 rules)
     |  token stream
     v
[Bison parser]  sub_4CE6B0 (48KB, 512 productions)
     |  NO AST -- reduction actions build IR directly:
     |    - allocate instruction nodes from pool
     |    - set opcode field (instruction +72)
     |    - build operand array (instruction +84)
     |    - link into doubly-linked list per basic block
     |    - create basic block entries (40B each)
     |    - populate CFG hash maps (Code Object +648, +680)
     |
     v                                             "DAGgen-time"
[Operand processing]  sub_6273E0 (44KB)            boundary
     |  6-bit type switch (v12 & 0x3F)             ----------
     |  address computation, state space annotation
     v
+----------------------------------------------------------+
|  RAW ORI IR (PTX-derived opcodes, virtual registers)     |
|  Instructions: PTX-level names (add.f32, ld.global, etc) |
|  Registers: virtual R-file, typed descriptors             |
|  CFG: basic blocks + edge hash maps (partially formed)    |
+----------------------------------------------------------+
     |
     |  Phase 0: OriCheckInitialProgram (validate)
     |  Phase 1: ApplyNvOptRecipes      (configure opt levels)
     |  Phase 2: PromoteFP16            (FP16 -> FP32 where needed)
     |  Phase 3: AnalyzeControlFlow     (finalize CFG + RPO + backedges)
     |  Phase 4: AdvancedPhaseBeforeConvUnSup (arch hook, no-op default)
     |  Phase 5: ConvertUnsupportedOps  (MercConverter: PTX ops -> SASS ops)
     |  Phase 6: SetControlFlowOpLastInBB (CFG structural fixup)
     |  Phase 7: AdvancedPhaseAfterConvUnSup (arch hook, no-op default)
     |  Phase 8: OriCreateMacroInsts    (fuse instruction sequences)
     |  Phase 9: ReportInitialRepresentation (diagnostic dump)
     |  Phase 10: EarlyOriSimpleLiveDead (dead code elimination)
     |  Phase 11: ReplaceUniformsWithImm (fold known constants)
     |  Phase 12: OriSanitize           (validate post-bridge IR)
     |  Phase 13: GeneralOptimizeEarly  (bundled copy-prop + const-fold)
     v                                             "OCG-time"
+----------------------------------------------------------+               begins
|  OPTIMIZER-READY ORI IR                                  |
|  Instructions: SASS opcodes (FADD, IMAD, LDG, STG, ...) |
|  Registers: virtual R/UR/P/UP files                       |
|  CFG: complete with RPO, backedge map, loop headers       |
+----------------------------------------------------------+
     |
     v
[Phase 14+: main optimization pipeline]

Inline IR Construction (Bison -> Ori)

The Bison parser at sub_4CE6B0 has 512 grammar productions with 443 reduction-action cases. Each reduction action constructs IR directly -- no intermediate AST is ever materialized. The instruction table builder (sub_46E000, 93 KB, 1,141 per-opcode registration calls to sub_46BED0) runs during parser initialization and registers the legal type combinations for every PTX instruction. The instruction lookup subsystem (sub_46C690 entry, sub_46C6E0 matcher at 6.4 KB) classifies operands into 12 categories at parse time.

When the parser encounters a PTX instruction like add.f32 %r1, %r2, %r3, it:

  1. Looks up add.f32 in the opcode table to get the internal opcode index and validate the type qualifier .f32
  2. Allocates an Ori instruction node from the memory pool
  3. Writes the opcode into the instruction field at offset +72
  4. Processes each operand through sub_6273E0 to build the packed operand array at offset +84
  5. Links the instruction into the current basic block's doubly-linked list
  6. If the instruction is a branch/jump/return, creates a CFG edge in the successor hash map at Code Object +648

Special PTX registers (%ntid, %laneid, %smid, %ctaid, %clock64, etc.) are mapped to internal identifiers during parser initialization at sub_451730. The mapping table is built from the ROT13-encoded opcode table populated by ctor_003 at 0x4095D0.

Operand Processing -- sub_6273E0

The 44 KB operand processing function handles all PTX operand forms. It reads v12 = *(_BYTE *)a2 (the first byte of the PTX AST node) and switches on v12 & 0x3F. The 11 active case values and the default are:

v12 & 0x3FPTX AST node kindPTX syntax exampleOri opcode emittedProcessing summary
0Binary expression%r1 + %r2131 (HSETP2, used as binary-op) or 162 (TTUCCTL, used as ternary-select)Recursively processes both child operands via sub_62A760, compares widths via sub_44B390, and widens the narrower operand with sub_620780. Sub-switch on child list-head tag: 12 emits Ori 131, 13 emits Ori 162
2Register%r1, %f1, %p038 (type-resolved move)Calls sub_61C9B0 for type resolution via dword_20249C0 lookup. Sub-switch on resolved type (9/10: int/fp immediate store; 11/13/15/20: flag constants; 26: const-bank redirect creating Ori 11 then sub_620C50; 36: 64-bit literal via sub_616670)
3Register pair{%r1, %r2}38 (same as case 2)Shares handler with case 2. When type==3, the secondary sub-switch dispatches on sub_44E010/sub_44E040/sub_44E060/sub_44E070 extractors for int-32, int-64, float, and double values respectively
4Variable referencevar, arr[i]Depends on storage classCalls sub_457420 to resolve variable descriptor; sub_6200A0 returns storage class. Inner switch on class: 2=register load (Ori 43/45), 3=state-space address (special-reg dispatch via sub_627380 for .nv.reservedSmem.*), 4=array element (Ori 44/46), 5=constant (Ori 41), 6=surface/texture (Ori 42), 8=param (Ori 39), 9=extern (Ori 48), 10=global (Ori 24, link-time), 11=local (Ori 25, link-time), 12=shared (Ori 52)
5Vector constructor{%r1, %r2} (vec2)95 (STS, vec-pack)If a12 flag set: processes single child via sub_62A760. Otherwise: recursively processes both children, type-resolves via sub_61C9B0, emits Ori 95 two-operand vector pack instruction via sub_A2F940
6Negation / unary op-%r1, ~%r171 (CALL, unary-op)Processes inner operand via sub_62A760, type-resolves, emits single-operand Ori 71 instruction via sub_A2F7A0 with the operand type in the high word
9Type cast / conversion.f32 %r1 (explicit cast)Delegates recursivelyRecursive call to sub_6273E0 on child node (a2+16). If byte a2+1 has bit 0 set, post-processes with sub_A2FEB0 + sub_6157C0 to apply rounding/saturation modifiers
0xB (11)Address expression[%rd1+16], [arr+i]131 (base+offset) or 144 (indexed array)Sub-switch on inner node type: if inner==4 (variable), calls sub_624DF0 for direct address; if inner==5 (vector), builds indexed address with Ori 144 via sub_A2F940, creates constant index operand from dword_20246A0 lookup, and optionally emits a widening Ori 131 wrapper
0xC (12)Parenthesized expr(%r1)PassthroughUnwraps one level: recursively calls sub_62A760 on the inner child. If a5 (destination context) flag is set and a12 is zero, chains through sub_624680 for destination address qualification
0xE (14)Operand list%r1, %r2, %r3Chained via sub_620AF0If a4 tag is 66 (predicated): checks type-qualifier size (4 or 8 bytes) via sub_4574A0/sub_4574B0 family to set predicate flags, then delegates to sub_629E40. Otherwise: iterates the linked list (*v56 walk), recursively calling sub_6273E0 on each element and chaining results with sub_620AF0(ctx, new, prev, index)
0x10 (16)Predicate register%p0, @%p1Predicate-typed valueCalls sub_61C9B0 for type resolution, then sub_620320(ctx, typeCode, 1, &v283) to create a predicate-width operand node
default(unknown tag)--Returns 0Unrecognized node tag; returns null

String references in callees of sub_6273E0 (not in the function itself, but in its direct callees sub_627380, sub_623AB0, sub_4CE6B0):

  • ".nv.reservedSmem.{begin,end,cap,offset0,offset1}" -- reserved shared memory region symbols resolved by sub_627380 (called from case 4, storage class 3, state-space codes 'e'--'i')
  • "COARSEOFFSET" -- coarse-grained offset label created by sub_623AB0 for large address space indexing
  • "__$endLabel$__%s" -- end-of-scope label synthesized by the Bison parser (sub_4CE6B0) for structured control flow

The function bridges PTX's explicitly-typed operand model (where .u32, .f32, .b64 qualifiers are part of the syntax) to Ori's implicitly-typed model where the operand type is determined by the SASS opcode. Type resolution at sub_61C9B0 maps PTX type qualifiers to a 5-entry size class via dword_20249C0[min(typeClass, 4)], producing a size-category byte (255 for out-of-range) that is packed into the high word of the Ori operand descriptor.

Bridge Phases (0--13)

Phase 0: OriCheckInitialProgram -- Validation

Validates the raw Ori IR produced by the Bison parser for structural correctness: all basic blocks have valid entry/exit points, instruction operand counts match opcode requirements, register references are within bounds, and CFG edges are consistent. This is a pure validation pass that produces no IR transformations. It catches malformed IR early, before any optimization pass can amplify a structural error into a hard-to-diagnose miscompile.

Phase 1: ApplyNvOptRecipes -- Optimization Level Configuration

Applies NvOptRecipe transformations controlled by option 391. When enabled, the PhaseManager's constructor (sub_C62720) allocates a 440-byte NvOptRecipe sub-manager at PhaseManager+56. This sub-manager configures per-phase behavior based on the NvOpt level (0--5), controlling which later phases are active and their aggressiveness:

NvOpt levelBehavior
0Minimal optimization (fast-compile path, many phases isNoOp())
1--2Standard optimization
3--4Aggressive optimization (loop unrolling, speculative hoisting enabled)
5Maximum optimization (may significantly increase compile time)

The string "Invalid nvopt level : %d." in sub_C173E0 confirms the valid range. The recipe data lives at NvOptRecipe+312 with per-phase records at stride 584 bytes. The sub-manager maintains its own sorted array (+376) and hash table (+400..+416) for fast recipe lookup by phase index.

NvOptRecipe Sub-Manager (440 bytes, at PhaseManager+56)
  +0      compilation_unit
  +8      phase_manager back-reference
  +16     ref_counted_list_1
  +312    recipe_data
  +336    allocator
  +344    timing_records (stride = 584 per entry)
  +376    sorted_array (for binary search by phase index)
  +400    hash_bucket_count
  +408    hash_buckets
  +432    shared_list_ptr (ref-counted)

Phase 2: PromoteFP16 -- Half-Precision Type Promotion

Promotes half-precision (FP16) operations where hardware support is insufficient or promotion yields better throughput. The promotion strategy is architecture-dependent:

  • Pre-sm_53: no native FP16 ALUs. All FP16 arithmetic is expanded to FP32 with narrowing conversions at stores.
  • sm_53+: native FP16 support. Only operations that require expensive multi-instruction sequences in FP16 (certain transcendentals, complex comparisons) are promoted.
  • sm_89+ (Ada, Blackwell): wide FP16 tensor paths. Promotion is minimal; most FP16 stays native.

The phase walks the instruction linked list, inspects each instruction's type encoding at offset +72, and rewrites FP16 operations to FP32 equivalents by replacing the opcode and inserting conversion instructions (F2F in SASS terminology) at use/def boundaries.

Phase 3: AnalyzeControlFlow -- CFG Finalization

Builds and finalizes the control flow graph data structures that the optimizer requires:

  • Successor edges: populates the FNV-1a hash table at Code Object +648
  • Backedge map: computes backedges and stores them at Code Object +680
  • RPO array: builds the reverse post-order traversal at Code Object +720
  • Loop identification: marks loop headers and backedge targets for later loop optimization passes (phases 18, 22, 24, 59)

The Bison parser constructs basic blocks and edges incrementally as it processes PTX instructions, but the CFG is not guaranteed to be fully consistent until this phase runs. For example, forward branch targets may reference blocks that were not yet created at parse time. This phase resolves all pending edges and ensures the CFG is complete.

Phases 4 and 7: Architecture Hook Points

Phases 4 (AdvancedPhaseBeforeConvUnSup) and 7 (AdvancedPhaseAfterConvUnSup) are no-op-by-default hook points that bracket ConvertUnsupportedOps. Architecture backends override their vtables to inject target-specific processing:

  • Phase 4 (before): prepare target-specific state, mark instructions that need special handling on this architecture
  • Phase 7 (after): clean up after legalization, fix architecture-specific edge cases introduced by the generic lowering

These hooks are part of the 16 AdvancedPhase injection points distributed throughout the 159-phase pipeline. The architecture vtable factory at sub_1CCEEE0 (17 KB, 244 callees) selects which overrides are active based on the sm_version.

Phase 5: ConvertUnsupportedOps -- Instruction Legalization

The most substantial bridge phase. Lowers PTX operations that have no direct SASS equivalent for the target architecture. This phase runs the MercConverter engine (see next section) and handles:

  • 64-bit integer arithmetic on architectures with 32-bit ALUs: splits add.s64, mul.lo.s64 into hi/lo 32-bit instruction pairs using carry chains
  • Complex addressing modes: decomposes multi-component addresses into separate arithmetic instructions
  • PTX-specific operations: converts PTX instructions that have no 1:1 SASS mapping (e.g., bfe, bfi, prmt variants not supported on all targets)
  • Architecture availability: gates instructions by SM version (an instruction added in sm_80 is lowered to a multi-instruction sequence on sm_70)
  • Texture/surface operations: legalizes texture sampling and surface access patterns (sub_9E8B20, 17 KB)
  • Memory operations: legalizes load/store patterns, address register handling (sub_9D76D0/sub_9D80E0, 17--18 KB each)

After ConvertUnsupportedOps completes, every instruction in the IR has a valid SASS opcode for the target architecture.

The late phase 132 (UpdateAfterConvertUnsupportedOps) runs cleanup for edge cases introduced by this phase that are only detectable after optimization.

Phase 6: SetControlFlowOpLastInBB -- CFG Structural Fixup

Enforces a critical structural invariant: control flow operations must be the last instruction in their basic block. If a branch, jump, return, or exit instruction is followed by other instructions in the same block (which can happen during lowering when a PTX instruction expands to a sequence ending in a branch), this phase splits the block at the control flow point.

The invariant is required by the scheduler (which assumes only the last instruction in a block can transfer control) and the register allocator (which computes live-out sets at block boundaries). The phase rewrites the instruction linked list and allocates new 40-byte basic block entries as needed.

Phase 8: OriCreateMacroInsts -- Macro Fusion

Identifies and fuses instruction sequences into macro instructions for hardware efficiency. The phase scans the instruction linked list for patterns that the GPU hardware can execute as a single macro-op:

  • Compare + branch: fused into a conditional branch macro instruction
  • Multiply + add: fused into FMA where not already (different from PTX fma -- this catches mul followed by add on the same operands)
  • Address computation + memory access: fused sequences for coalesced access patterns

The fused macro instructions carry composite semantics in a single IR node. They are expanded back into individual SASS instructions much later at phase 118 (MercExpandInstructions), after scheduling has determined the optimal placement. This late expansion allows the optimizer to treat the fused sequence as atomic, preventing passes from inserting unrelated instructions between the components.

Phase 9: ReportInitialRepresentation -- Diagnostic Dump

Dumps the Ori IR state for debugging, active when DUMPIR or --ftrace diagnostics are enabled. The stats emitter at sub_A3A7E0 prints a per-function profile:

# 142 instructions, 24 R-regs
# [inst=142] [texInst=0] [tepid=0] [rregs=24]
# [est latency = 87] [LSpillB=0]
# [Occupancy = 0.750000]
# [issue thru=0.888889] [fp thru=0.000000]
# [worstcaseLat=87.000000]
# [avgcaseLat=52.500000]
# [SharedMem Alloc thru=0.000000]
# [instHint=0] [instPairs=0]

This snapshot provides the pre-optimization baseline. Comparing it against ReportBeforeScheduling (phase 96) and ReportFinalMemoryUsage (phase 126) shows the optimizer's impact on instruction count, register pressure, and estimated latency.

Phases 10--13: Early Cleanup

PhaseNamePurpose
10EarlyOriSimpleLiveDeadFirst dead code elimination pass. Removes instructions whose results are unused. Uses the SIMD-accelerated bitvector library (sub_BDBA60..sub_BDE150) for liveness computation.
11ReplaceUniformsWithImmFolds known-constant uniform register loads into immediate operands. Important for kernel launch parameters passed through constant memory.
12OriSanitizeSecond structural validation after all bridge transformations. Catches errors introduced by phases 1--11 before the main optimizer begins.
13GeneralOptimizeEarlyFirst compound optimization pass: copy propagation + constant folding + algebraic simplification in a single fixed-point iteration. Cleans up redundancies introduced by the bridge phases.

The MercConverter Engine

The MercConverter (sub_9F1A90, 35 KB) is the instruction conversion engine at the heart of ConvertUnsupportedOps. Despite its name referencing "Mercury" (NVIDIA's SASS encoding format), it operates purely at the IR level -- converting instruction semantics, not binary encodings.

Call Chain

sub_9F3340 (orchestrator, 7KB)
  |
  +-- sub_9F1A90 (MercConverter main pass, 35KB)
  |     |
  |     +-- sub_9ED2D0 (opcode dispatch, 25KB)
  |     |     |
  |     |     |  Large switch on (*(instr+72)) with byte-1 mask:
  |     |     |    BYTE1(opcode) &= 0xCF  -- strips modifier bits 4-5
  |     |     |
  |     |     +-- 130 explicit cases covering 181 opcode IDs
  |     |     +-- see "Opcode Dispatch Table" below for full map
  |     |     +-- default: emit_opcode(0xFFFF) -- unsupported marker
  |     |
  |     +-- sub_934630 (instruction creation utility, called N times)
  |
  +-- sub_9EF5E0 (post-conversion lowering, 27KB)
        |  string "CONVERTING"
        +-- sub_9EC160, sub_7C11F0, sub_7BFC30 (intrinsic expansion)

Opcode Dispatch Table (sub_9ED2D0)

The dispatch reads *(instr+72), masks byte 1 with &= 0xCF (strips modifier bits 4-5), then switches. v[N] = vtable call at byte offset N*8 from *(a1).

Case value(s)SASS mnemonic(s)HandlerType
1IMADsub_9DA5C0direct
2,3,4,5,7IMAD_WIDE,IADD3,BMSK,SGXT,ISETPv[0]vtable
6LOP3sub_9DA100direct
8IABSsub_9D2440direct
10,11,149,151,152,290,291SHF,FFMA,UFLO,UIMAD,UMOV,MOV.104,UMOV.104sub_9D80E0direct
14,39,40,105,125,299,300,321FMNMX,FLO,FCHK,ATOMS,DSETP,UFSETP,UI2I,LASTv[7]vtable
15,85FSWZADD,TLD4sub_9EC340direct
16FSETsub_9E8B20direct
17FSELsub_9E7FB0direct
18FSETPv[3]vtable
22R2Psub_9D6DB0direct
23PLOP3sub_9E58F0direct
24PRMTsub_9D9F60direct
26VOTEsub_9E54C0direct
27CS2R_32sub_9E4BB0direct
28CS2R_64sub_9D9E70direct
31VABSDIFFv[4]vtable
32,271VABSDIFF4,TCLDSWSsub_9E2440direct
34IDEsub_9E55E0direct
35I2Iv[6]vtable
36I2IPv[21]vtable
38,59,106,180,182,192,194,215,221,242POPC,R2B,QSPC,DMMA,HFMA2_MMA,REDUX,SM86_FIRST,DMMA.90,GMMA,UTMALDGsub_9DA6B0direct
41,284IPA,IMNMX.104sub_9D1DA0direct
42,53,55,66MUFU,BREV,BMOV_R,DEPBARsub_9D54B0direct
43F2Fv[9]vtable
47I2F (cond)sub_9E74E0conditional
50FRND_Xv[12]vtable
51AL2Psub_9E2F60direct
52,54,72,97AL2P_IDX,BMOV_B,RET,STGsub_9D09C0direct (v8=1)
57,101S2R,STsub_9D6170direct
58B2Remit(162)inline
60,62,78,79LEPC,BAR_IDX,RTT,BSYNCsub_9E5EE0direct
61,63,80BAR,SETCTAID,MATCHsub_9E6600direct
65GETLMEMBASEv[22]vtable
67BRAsub_9D9C30direct
70JMXsub_9E3490direct
73BSSYv[15]vtable
74BREAKv[16]vtable
75BPTsub_9E0C10direct
77EXITsub_9E4DF0direct
81NANOSLEEPv[24]vtable
83TEXsub_9D6AB0direct
88,89TXQ,LDCsub_9D5990direct
90ALDsub_9D2820direct
91ASTsub_9E7600direct
92OUTsub_9E7890direct
93,95OUT_FINAL,STSsub_9E1D40direct
94LDSsub_9E1DF0direct
96LDGsub_9D41C0direct
98LDLsub_9D3230direct
100LDsub_9D70E0direct
102ATOMsub_9D9750direct
103,104ATOMG,REDsub_9E31D0direct
108CCTLsub_9D76D0direct
110,111,112,114CCTLT,MEMBAR,SULD,SUATOMv[25]vtable
118ISBEWRv[10]vtable
119SHFLv[28]vtable
120,121,126--128,280,281WARPSYNC,YIELD,HADD2,HADD2_F32,HFMA2,SM100_LAST,SM104_FIRSTv[27]vtable
122,123,310--312DFMA,DADD,UF2FP.104,MXQMMA_SF,OMMAv[26]vtable
124DMULsub_9E18B0direct
130,169HSET2,S2URv[29]vtable
135INTRINSICsub_9D6560direct
139--141,143UBMSK,UCLEA,UISETP,ULEAsub_9D4C10direct
145ULOP3sub_9D3020direct
148USGXTemit(45)inline
155,268UPOPC,UTCSHIFT_2CTAsub_9E5260direct
156USHFsub_9D94B0direct
157SCATTERv[84]vtable
158,167F2FP,LDTRAMsub_9E4A00direct
161BMMAsub_9D21D0direct
162TTUCCTLsub_9D9660direct
166LDSMsub_9E2100direct
170BRXUsub_9E2DF0direct
173,267GATHER,UTCSHIFT_1CTAsub_9EB5C0direct
174GENMETADATAsub_9D9300direct
176,177BMMA_88128,BMMA_168128v[34]vtable
183,288HMNMX2,ISETP.104v[36]vtable
184IMMA_88sub_9D2E70direct
185IMMA_SP_88sub_9E32F0direct
186IMMA_16816v[35]vtable
188,190IMMA_SP_16832,LDGDEPBARsub_9E2970direct
195F2IPsub_9D2AB0direct
196UF2FPsub_9D9080direct
198SUQUERYsub_9D66F0direct
201,202,204,285QMMA_16816,QMMA_16832,QMMA_SP_12864,IMNMX.104v2sub_9EAC30direct
203QMMA_SP_16832sub_9D8E90direct
205SM89_LASTsub_9E1260direct
209CGABAR_GETsub_9E5740direct
210,213,214CGABAR_SET,CREATEPOLICY,CVTAsub_9D8B30direct
211CGABAR_WAITv[39]vtable
220FMNMX.90v[40]vtable
223,238LEPC.90,ULEPCv[41]vtable
228SETMAXREGv[42]vtable
240UTMACCTLsub_9D6280direct
241UTMACMDFLUSHsub_9E2CC0direct
243UTMAPFv[43]vtable
245UTMALSTv[67]vtable
246VHMNMXv[68]vtable
247VIADDsub_9D0F70direct
248VIADDMNMXsub_9D0DF0direct
249VIMNMXv[72]vtable
250VIMNMX3v[73]vtable
251WARPGROUPv[74]vtable
252SM90_LASTv[75]vtable
253SM100_FIRSTv[76]vtable
257FMNMX3v[69]vtable
262UTCBAR_2CTAsub_9E7440direct
264UTCCP_2CTAsub_9D73F0direct
265,266UTCMMA_1CTA,UTCMMA_2CTAv[93]vtable
269VIRTCOUNTemit(0xFFFF)inline
270TCATOMSWSv[77]vtable
276MEMSETsub_9D5EC0direct
277ACQSHMINIT (type==5 ? v[65] : v[11])conditionalvtable
279FENCE_Tv[81]vtable
282IADDv[82]vtable
283UVIADDv[83]vtable
286,287UIMNMX,UVIMNMXv[87]vtable
292SEL.104sub_9D0E90direct
297UFMULv[19]vtable
298UFSETv[2]vtable
301,319UI2IP,QMMA_SF_SPv[32]vtable
302UF2Fv[5]vtable
303UFRNDv[17]vtable
304--306UF2I,UF2IP,UI2Fv[8]vtable
307UI2FPv[13]vtable
308UIABSv[14]vtable
309CS2URv[18]vtable
313OMMA_SPv[31]vtable
314,324QMMA_16816.104,...v[1]vtable
315QMMA_16832.104v[86]vtable
316QMMA_SP_16832.104v[38]vtable
317,318QMMA_SP_12864.104,QMMA_SFv[44]vtable
322(sm_104)v[66]vtable
323(sm_104)v[85]vtable
325,326(sm_104)v[88]vtable
327,328(sm_104)v[89]vtable
329--331(sm_104)v[90],v[30],v[33]vtable
332--348(sm_104, 17 opcodes)v[46..62]vtable 1:1
349--351(sm_104)v[78..80]vtable 1:1
352(sm_104)v[20]vtable
defaultall unmatchedemit(0xFFFF)unsupported

Legend. v[N] = *(*(a1)+N*8)(a1,a2). "emit(X)" = inline replacement opcode with no handler. Cases 15, 52, 54, 72, 97 set v8=1, skipping the default post-dispatch predication call to sub_9CD420. Case 47 (I2F) checks *(*(instr+40)+174) & 1; only calls sub_9E74E0 if set, else falls to default. Case 277 (ACQSHMINIT) inspects operand type: (operand & 7) == 5 selects v[65], otherwise v[11]. Cases 58/148/269 emit replacement opcodes inline (162/45/0xFFFF).

Per-Category Handlers

HandlerSizeCategoryOpcodes routed here
sub_9D80E017 KBData movement legalization10,11,149,151,152,290,291 (SHF, FFMA, UFLO, UIMAD, UMOV, MOV/UMOV.104)
sub_9DA6B0smallMisc ALU + MMA passthrough38,59,106,180,182,192,194,215,221,242 (POPC through UTMALDG)
sub_9D54B0smallBit/barrier manipulation42,53,55,66 (MUFU, BREV, BMOV_R, DEPBAR)
sub_9D4C10smallUniform integer ops139--141,143 (UBMSK, UCLEA, UISETP, ULEA)
sub_9E660025 KBInstruction expansion61,63,80 (BAR, SETCTAID, MATCH -- multi-instruction)
sub_9E5EE0medControl flow lowering60,62,78,79 (LEPC, BAR_INDEXED, RTT, BSYNC)
sub_9D09C0smallPredicated lowering (v8=1)52,54,72,97 (AL2P_INDEXED, BMOV_B, RET, STG)
sub_9EAC30medQuarter-precision MMA201,202,204,285 (QMMA family)
sub_9EC34023 KBMulti-operand legalization15,85 (FSWZADD, TLD4)
sub_9E8B2017 KBTexture/surface lowering16 (FSET)
sub_9D76D018 KBCache control legalization108 (CCTL)

Intrinsic Descriptor Loading

sub_9EE390 (20 KB) loads architecture-specific instruction descriptions from a file ("IntrinsicDescrFile=%s"). This allows the MercConverter to query which intrinsic operations are natively supported on the target SM and which require multi-instruction expansion. The descriptor file is architecture-versioned and loaded once during the first compilation of a kernel targeting that architecture.

The PTX-to-SASS Opcode Transition

The fundamental semantic transformation during lowering: PTX uses high-level, explicitly-typed opcodes; Ori uses SASS-level opcodes where the type is encoded in the mnemonic. All SASS opcode strings in the binary are ROT13-encoded.

Lowering Rules Reference (95 common PTX instructions)

The table below lists the primary SASS opcode(s) each PTX instruction lowers to during the bridge phases. "1:1" means a single SASS instruction; "1:N" means a multi-instruction expansion whose size depends on type width, rounding mode, or target SM. The lowering phase column indicates where the conversion happens: P = parser inline (Bison reduction action writes the SASS opcode directly), 5 = Phase 5 ConvertUnsupportedOps / MercConverter, 45/78 = later legalization passes. Entries marked with an SM gate are only lowered on architectures that lack native hardware support.

#PTX instructionSASS opcode(s)RatioPhaseNotes
1add.s32 / add.u32IADD3 Rd, Ra, Rb, RZ1:1PThird source defaults to RZ (hardware zero register)
2add.s64 / add.u64IADD3 Rd, Ra, Rb, RZ (sm_70+)1:1PNative 64-bit ALU on Volta+; on older SM, splits to hi/lo pair
3add.f32FADD Rd, Ra, Rb1:1PRounding mode encoded in FADD modifier bits
4add.f64DADD Rd, Ra, Rb1:1PDouble-precision add
5sub.s32 / sub.u32IADD3 Rd, -Ra, Rb, RZ1:1PSubtraction via negated first source in IADD3
6sub.f32FADD Rd, Ra, -Rb1:1PSubtraction via negated second source
7sub.f64DADD Rd, Ra, -Rb1:1PDouble-precision subtraction
8mul.lo.s32 / mul.lo.u32IMAD Rd, Ra, Rb, RZ1:1PMultiply-add with zero addend
9mul.hi.s32 / mul.hi.u32IMAD.HI Rd, Ra, Rb, RZ1:1PHigh-half multiply
10mul.wide.s32IMAD_WIDE Rd, Ra, Rb, RZ1:1P32x32->64 widening multiply
11mul.f32FMUL Rd, Ra, Rb1:1PFP32 multiply
12mul.f64DMUL Rd, Ra, Rb1:1PFP64 multiply
13mad.lo.s32 / mad.lo.u32IMAD Rd, Ra, Rb, Rc1:1PInteger multiply-add
14mad.wide.s32IMAD_WIDE Rd, Ra, Rb, Rc1:1PWidening multiply-add
15fma.rn.f32FFMA Rd, Ra, Rb, Rc1:1PFused multiply-add FP32
16fma.rn.f64DFMA Rd, Ra, Rb, Rc1:1PFused multiply-add FP64
17neg.s32IADD3 Rd, -Ra, RZ, RZ1:15Integer negate via IADD3 with negated source
18abs.s32IABS Rd, Ra1:1PInteger absolute value
19min.s32 / min.u32IMNMX Rd, Ra, Rb1:1PInteger min; sign mode in modifier
20max.s32 / max.u32IMNMX Rd, Ra, Rb1:1PSame opcode as min, direction in modifier bit
21min.f32FMNMX Rd, Ra, Rb, PT1:1PPredicate operand selects min vs max
22max.f32FMNMX Rd, Ra, Rb, !PT1:1PNegated true-predicate selects max
23abs.f32modifier on source operand1:1PAbsolute-value modifier bit, no separate instruction
24neg.f32modifier on source operand1:1PNegate modifier bit, no separate instruction
25div.approx.f32MUFU.RCP + FMUL1:25Approximate: reciprocal then multiply
26div.full.f32MUFU.RCP + FFMA x2 + FMUL1:4+45/78Full-range with one Newton-Raphson refinement
27div.rn.f32N-R sequence (RCP + FFMA chain)1:~1578IEEE rounding; may call __cuda_sm20_div_rn_f32
28div.rn.f64N-R sequence (DFMA chain)1:~3078Inline template from 0x1700000 region
29div.s32 / div.u32IMAD-based sequence1:~3578Calls __cuda_sm20_div_[su]32; magic-number multiply
30div.s64 / div.u64Multi-instruction sequence1:~6078Calls __cuda_sm20_div_[su]64; no HW on any SM
31rem.s32 / rem.u32div + IMAD back-multiply + IADD31:~3878Remainder = a - (a/b)*b
32rem.s64 / rem.u64Multi-instruction sequence1:~6578Calls __cuda_sm20_rem_[su]64
33rcp.approx.f32MUFU.RCP Rd, Ra1:1PSFU pipe, ~4 cycle latency
34rcp.rn.f32MUFU.RCP + FFMA refinement1:~878Newton-Raphson to IEEE precision
35rcp.approx.f64MUFU.RCP64H + widen1:2+5Approximate double reciprocal
36rsqrt.approx.f32MUFU.RSQ Rd, Ra1:1PSFU reciprocal square root
37sqrt.approx.f32MUFU.RSQ + FMUL (+ fixup)1:3+5rsqrt then multiply by input
38sqrt.rn.f32N-R sequence1:~1578May call __cuda_sm20_sqrt_rn_f32
39sqrt.rn.f64N-R sequence1:~2578Inline DFMA template
40sin.approx.f32MUFU.SIN Rd, Ra1:1PSFU pipe
41cos.approx.f32MUFU.COS Rd, Ra1:1PSFU pipe
42lg2.approx.f32MUFU.LG2 Rd, Ra1:1PSFU pipe
43ex2.approx.f32MUFU.EX2 Rd, Ra1:1PSFU pipe
44tanh.approx.f32MUFU.TANH Rd, Ra1:1PSFU pipe, sm_75+ only
45setp.lt.s32 (and variants)ISETP.LT Pd, PT, Ra, Rb1:1PComparison op in ISETP modifier
46setp.lt.f32 (and variants)FSETP.LT Pd, PT, Ra, Rb1:1PFloat comparison; NaN-aware via modifier
47setp.lt.f64 (and variants)DSETP.LT Pd, PT, Ra, Rb1:1PDouble-precision comparison
48selp.b32SEL Rd, Ra, Rb, Pp1:1PPredicate-driven select
49and.b32LOP3 Rd, Ra, Rb, RZ, 0xC01:153-input LUT; AND = truth table 0xC0
50or.b32LOP3 Rd, Ra, Rb, RZ, 0xFC1:15OR = truth table 0xFC
51xor.b32LOP3 Rd, Ra, Rb, RZ, 0x3C1:15XOR = truth table 0x3C
52not.b32LOP3 Rd, Ra, RZ, RZ, 0x331:15NOT = truth table 0x33 (invert first input)
53and.predPLOP3 Pd, PT, Pa, Pb, PT, 0xC01:15Predicate-file version of LOP3
54or.predPLOP3 Pd, PT, Pa, Pb, PT, 0xFC1:15Predicate OR
55shl.b32SHF.L Rd, RZ, Ra, Rb1:15Funnel shift left; high input is zero
56shr.u32SHF.R.U32 Rd, Ra, Rb, RZ1:15Logical shift right
57shr.s32SHF.R.S32 Rd, Ra, Rb, RZ1:15Arithmetic shift right
58mov.b32MOV Rd, Ra1:1PRegister move
59mov.b64MOV pair (lo+hi)1:2PTwo 32-bit moves for 64-bit value
60cvt.f32.s32I2F.F32.S32 Rd, Ra1:1PInteger-to-float conversion
61cvt.s32.f32F2I.S32.F32 Rd, Ra1:1PFloat-to-integer conversion
62cvt.f64.f32F2F.F64.F32 Rd, Ra1:1PFloat widening
63cvt.f32.f64F2F.F32.F64 Rd, Ra1:1PFloat narrowing
64cvt.f16.f32F2F.F16.F32 Rd, Ra1:1PFloat to half
65cvt.f32.f16F2F.F32.F16 Rd, Ra1:1PHalf to float
66cvt.rni.s32.f32F2I.S32.F32.RNI Rd, Ra1:1PRound-to-nearest-int conversion
67ld.global.b32LDG Rd, [Ra]1:1PGlobal load; cache mode in modifier
68ld.shared.b32LDS Rd, [Ra]1:1PShared memory load
69ld.local.b32LDL Rd, [Ra]1:1PLocal memory load (spill region)
70ld.const.b32LDC Rd, c[bank][offset]1:1PConstant memory load
71ld.param.b32LDC Rd, c[0][offset]1:1PParameter load via constant bank 0
72st.global.b32STG [Ra], Rb1:1PGlobal memory store
73st.shared.b32STS [Ra], Rb1:1PShared memory store
74st.local.b32STL [Ra], Rb1:1PLocal memory store
75atom.global.add.s32ATOMG.ADD Rd, [Ra], Rb1:1PGlobal atomic add
76atom.shared.add.s32ATOMS.ADD Rd, [Ra], Rb1:1PShared atomic add
77atom.global.cas.b32ATOMG.CAS Rd, [Ra], Rb, Rc1:1PGlobal atomic compare-and-swap
78red.global.add.s32RED.ADD [Ra], Rb1:1PReduction (no return value)
79braBRA target1:1PUnconditional branch
80@%p0 bra@P0 BRA target1:1PPredicated branch; predicate in P file
81callCALL target1:1PFunction call (ABI save/restore added later)
82retRET1:1PReturn from function
83exitEXIT1:1PTerminate thread
84bar.syncBAR.SYNC1:1PCTA-level barrier
85membar.ctaMEMBAR.CTA1:1PMemory fence (CTA scope)
86membar.glMEMBAR.GL1:1PMemory fence (GPU scope)
87shfl.sync.bfly.b32SHFL.BFLY Rd|Pp, Ra, Rb, Rc1:1PWarp shuffle butterfly
88vote.sync.ballot.b32VOTE.ALL Rd, Pp1:1PWarp vote ballot
89redux.sync.add.s32REDUX.ADD Rd, Ra1:1PWarp reduction (sm_80+)
90popc.b32POPC Rd, Ra1:1PPopulation count
91clz.b32FLO Rd, Ra (inverted)1:15Count leading zeros via find-leading-one
92brev.b32BREV Rd, Ra1:1PBit reversal
93bfe.u32BMSK / multi-instr1:1+5Bit field extract; may use LEA+SHF on some SM
94bfi.b32LOP3 + SHF sequence1:2+5Bit field insert; no single SASS equivalent
95prmt.b32PRMT Rd, Ra, Rb, Rc1:1PByte permute
96fma.rn.f16HFMA2 Rd, Ra, Rb, Rc (sm_53+)1:1PNative half FMA; promoted to FP32 pre-sm_53
97add.f16x2HADD2 Rd, Ra, Rb (sm_53+)1:12Packed FP16x2; Phase 2 promotes if no HW
98cvta.to.globalCVTA Rd, Ra1:1PAddress space conversion (generic to global)
99lop3.b32LOP3 Rd, Ra, Rb, Rc, immLut1:1PDirect LUT-encoded 3-input logic
100shf.l.b32SHF.L Rd, Ra, Rb, Rc1:1PFunnel shift left
101dp4a.u32.u32IDP Rd, Ra, Rb, Rc (sm_61+)1:1P4-element dot product accumulate
102nanosleepNANOSLEEP Rd1:1PThread sleep (sm_70+)

Phase legend: P = parser (Bison reduction action, measured by DAGgen-time). 2 = Phase 2 PromoteFP16. 5 = Phase 5 ConvertUnsupportedOps (MercConverter). 45 = Phase 45 MidExpansion. 78 = Phase 78 LateExpansionUnsupportedOps. Entries marked 45/78 are kept as single Ori instructions through optimization and expanded late to preserve optimization opportunities (LICM, CSE, strength reduction can operate on the unexpanded form).

ROT13 encoding in the binary:

SNQQ  = FADD       VZNQ  = IMAD       SSZN  = FFMA
VNQQ3 = IADD3      QZHY  = DMUL       YQT   = LDG
FGT   = STG        OEN   = BRA        RKVG  = EXIT
ERG   = RET        ONE   = BAR        FGF   = STS

Key semantic differences at the transition:

  1. Type moves into the opcode: PTX add.f32 becomes FADD (the "F" encodes float); PTX add.s32 becomes IADD3 (the "I" encodes integer). The type qualifier disappears from the instruction syntax.

  2. Register namespace unification: PTX's typed virtual registers (%r for int, %f for float, %rd for 64-bit, %p for predicate) merge into Ori's four register files (R, UR, P, UP) with type tracked in the register descriptor at offset +64.

  3. Operand count changes: SASS IADD3 takes 3 source operands where PTX add takes 2 -- the third source defaults to RZ (the hardware zero register). This is handled by the expansion in sub_9E6600.

  4. Multi-instruction expansion: Complex PTX operations expand to multiple SASS instructions. A PTX div.f32 may become a Newton-Raphson sequence of RCP + FMUL + correction iterations.

  5. Predication mapping: PTX @%p0 instruction maps to an Ori predicate operand in the P register file, attached to the instruction node's predicate slot.

Mapping Tables

Table 1 -- PTX type qualifier to SASS opcode prefix. The type qualifier is consumed during MercConverter dispatch and encoded into the SASS mnemonic prefix. Peephole field 0x7E (slot 126) carries the data type qualifier internally (547 = .f32, 548 = .f64); the ISel field 22 encodes integer sign (99 = unsigned, 101 = signed). The U prefix denotes the uniform-register variant, not a type.

PTX type qualifierSASS prefixArithmeticCompareConversionExample
.f16 / .f16x2HHADD2, HFMA2, HMUL2HSETP2, HSET2F2F (via width)add.f16 -> HADD2
.bf16 / .bf16x2HHADD2_F32HSETP2F2Fadd.bf16 -> HADD2
.f32FFADD, FFMA, FMULFSETP, FSETF2I, F2Fadd.f32 -> FADD
.f64DDADD, DFMA, DMULDSETPF2I, F2Fmul.f64 -> DMUL
.s8--.s64IIADD3, IMAD, IMAD_WIDEISETPI2I, I2Fadd.s32 -> IADD3
.u8--.u64IIADD3, IMADISETPI2I, I2Fmul.lo.u32 -> IMAD
.b8--.b128(none)LOP3, SHF, PRMTISETPI2Iand.b32 -> LOP3
.predP (in operand)PLOP3--P2R, R2Pand.pred -> PLOP3

Signed vs. unsigned .s/.u distinction does not change the SASS mnemonic -- both map to I-prefixed instructions. The sign is encoded in a modifier bit (ISel field 22: value 99 for .u, 101 for .s), which the SASS printer emits as .U32 vs no suffix on ISETP.

Table 2 -- PTX state space to SASS memory instruction. The state space qualifier on ld/st selects the SASS opcode suffix. Peephole field 0x119 (slot 281) carries the address space qualifier with enum values 1435--1440. Atomics follow the same suffix pattern (ATOM/ATOMG/ATOMS).

PTX state spaceSASS loadSASS storeSASS atomicField 281 value
.globalLDGSTGATOMG1436
.sharedLDSSTSATOMS1437
.localLDLSTL--1438
.constLDC----1439
.paramLDC (bank 0)----1440
(generic)LDSTATOM1435

Additional memory instructions: LDSM (load shared matrix, sm_75+), LDGSTS (async global-to-shared, sm_80+), LDGDEPBAR (load with dependency barrier), LDTRAM (load TMEM, sm_100+).

Table 3 -- PTX comparison/rounding modifiers to SASS encoding. Modifiers that survive as SASS instruction suffixes are encoded through the modifier-encode functions in the 0x10B region. Field 345 (slot 0x159) selects rounding; field 150 (slot 0x096) selects comparison mode. The SASS printer emits these via vtable[1760] (rounding) and vtable[1392]/vtable[3528] (comparison).

PTX modifierField IDEnum valueSASS suffixEncoding bitsEncoder
.rn (round nearest)3451900.RNfield 300 = 1513sub_10B6220 (3-bit)
.rz (round zero)3451901.RZfield 300 = 1515sub_10B6220
.rm (round minus-inf)3451902.RMfield 300 = 1515sub_10B6220
.rp (round plus-inf)3451903.RPfield 300 = 1516sub_10B6220
.ftz (flush to zero)3011521.FTZ1-bit flagsub_10B6180 (1-bit)
.sat (saturate)(stage)--.SAT1-bit flagsub_10B6180
.eq .ne .lt .le .gt .ge150650, 651.EQ .NE .LT .LE .GT .GE4-bit, (mod>>4)&0xFsub_10B4650 (4-bit)
.equ .neu .ltu .leu .gtu .geu150650, 651.EQU .NEU ...4-bit + unordered bitsub_10B4650
.num .nan150650, 651.NUM .NAN4-bitsub_10B4650

Rounding modes .rz and .rm share encoding value 1515 because the hardware distinguishes them by a secondary bit in field 301 (1520 vs 1521). The PTX comparison operators .lo .ls .hi .hs are unsigned aliases for .lt .le .gt .ge and produce identical SASS encoding.

Error Detection During Lowering

The bridge phases include two error detection mechanisms:

Internal compiler error assertion (sub_9EB990, 1.4 KB): three references to "Internal compiler error.". Called when a bridge phase encounters an impossible IR state (e.g., an opcode value outside the known range in the MercConverter dispatch switch). Triggers longjmp-based fatal abort via sub_42F590 back to the driver's error recovery point in sub_446240.

Uninitialized register detector (sub_A0B5E0, 7 KB): "Found %d potentially uninitialized register(s) in function %s". Walks the instruction list per block, checks register descriptor flags at offset +48 (bit 5 = "defined"). Reports registers that appear as sources without any prior definition. This detector fires after the bridge phases to catch conversion errors that leave registers undefined.

Key Data Structures

Instruction Node

Instruction (variable size, linked list node)
  +0     prev_ptr           // doubly-linked list: previous instruction
  +8     next_ptr           // doubly-linked list: next instruction
  +16    child_ptr          // child/expanded instruction chain
  +32    control_word_ptr   // set later during scheduling (initially NULL)
  +72    opcode             // byte 0: primary opcode
                            // byte 1 bits 4-5: modifier (masked with 0xCF)
  +80    operand_count      // number of operands
  +84    operand_array      // packed operand descriptors

Operand Encoding

Each operand is a packed 32-bit value:
  Bits 28-30: operand kind ((value >> 28) & 7)
    1 = register operand
    5 = predicate register
    (other values for immediate, constant bank, label, etc.)

  Lower bits: operand-kind-specific payload (register ID, immediate value, etc.)

Register Descriptor

Register descriptor (accessed via *(ctx+88) + 8*regId)
  +12    register number (int)
  +48    flags (bit 5 = "defined", other bits for liveness state)
  +64    type (3=address, 6=GPR, 7=predicate)

Timing Boundary

The lowering spans two --compiler-stats timer phases:

TimerCovers
DAGgen-timeBison parser reduction actions -> Ori instruction nodes, operand processing (sub_6273E0), basic block / CFG construction
OCG-timePhases 0--13 (bridge), then phases 14--158 (optimization + codegen)

The boundary between "lowering" and "optimization" is therefore between phase 13 (GeneralOptimizeEarly, the last bridge phase) and phase 14 (DoSwitchOptFirst, the first pure optimization). After phase 13, the IR is in its final SASS-opcode form with validated structure, ready for the main optimization pipeline.

Cross-References

  • PTX Parser -- Flex scanner + Bison LALR(1) parser (the source of raw Ori IR)
  • Ori IR -- IR design: Code Object, basic blocks, instruction format, register files
  • Optimization Pipeline -- 159-phase pipeline (phases 0--13 are the bridge)
  • Phase Manager -- PhaseManager object, phase factory, dispatch loop
  • Optimization Levels -- NvOpt levels 0--5 and their effect on recipes
  • SASS Opcodes -- target SASS instruction set after lowering

Function Map

AddressSizeCallersIdentityConfidence
0x45173014 KB1Parser init, special register setupHIGH
0x46E00093 KB1Opcode table builder (1,141 per-opcode calls)HIGH
0x4CE6B048 KB1Bison LALR(1) parser (512 productions)HIGH
0x6273E044 KBNOperand processing (6-bit type switch)MEDIUM
0x9D43807 KB~10Instruction builder / inserter into linked listHIGH
0x9D76D018 KB1Memory instruction legalization (load/store)HIGH
0x9D80E017 KB1Memory instruction legalization (variant)HIGH
0x9DA1009 KB1Arithmetic operation handler (case 6)HIGH
0x9DE89017 KB1Control flow legalization (branch/call)MEDIUM
0x9DDEE014 KB1Address computation legalizationMEDIUM
0x9E660025 KB1Instruction expansion (64-bit split, etc.)HIGH
0x9E8B2017 KB1Texture/surface loweringMEDIUM
0x9EB9901.4 KB3Internal compiler error assertionHIGH
0x9EC34023 KB1Multi-operand instruction legalizationMEDIUM
0x9ED2D025 KB1Opcode dispatch (master switch, & 0xCF mask)HIGH
0x9EE39020 KB1Intrinsic descriptor file loaderMEDIUM
0x9EF5E027 KB1Post-MercConverter lowering ("CONVERTING")HIGH
0x9F1A9035 KB1MercConverter main instruction conversion passHIGH
0x9F33407 KB1MercConverter orchestrator ("After MercConverter")HIGH
0xA0B5E07 KBNUninitialized register detectorHIGH
0xA3A7E06 KBNScheduling statistics printer (phase 9 output)VERY HIGH