четверг, 15 октября 2026 г.

comparison of nvcc vs clang nvptx backend, part 3

Parts 1 & 2

Little disclaimer: I am not llvm expert and never created my own backend - in best case I can write simple optimization pass, lower yet another senseless MLIR dialect or extract some info from IR (and prefer gcc bcs its code more clean & neat and not scattered on thousands of sub-dirs as if written by an orthodox Java devotee), so take everything described below with healthy dose of skepticism

Task of searching for modifications/patches in general is well known, the problem in our case is that binary files is just huge

  • cicc from SDK 13.1 has size 80mb
  • libLLVM.so.21.1 128mb
besides that cicc does not contain DWARF debug info, so using of tools like bindiff seems like a questionable idea. Let's check if can invent some dirty tricks to reduce volume of code for comparison

CL options

Let's start with something easy - as you could know in llvm all CL options represented as static vars of template class cl::opt<Type>, like

static cl::opt<bool>
NVVMReflectEnabled("nvvm-reflect-enable", cl::init(true), cl::Hidden,
                   cl::desc("NVVM reflection, enabled by default"));

We can guess that code to create them must be located in array of constructors - in section .ctors or .init_array (actually second can have any name - only section type INIT_ARRAY matters). What really important here is that constructor of these object must load some constant strings from .rodata section

So I wrote dirty hack to disasm array of constructors and dump all used string to file. Results:

I also wrote simple script for comparison, so just run

perl cstr.pl clang-cstr.txt cicc-cstr.txt

What interesting we can note in its output?

  • print-schedule - Print 'sched: [latency:throughput]' in .s output
  • wmma-memory-space-opt
  • dump-ir-before-memory-space-opt & dump-ir-after-memory-space-opt
  • enable-bfi64 - Enable generation of 64-bit BFI instructions
  • nvptx-add-scalar-move-for-vector-load, nvptx-lower-global-ctor-dtor & nvptx-use-max-local-array-alignment
This method retrieves all the strings used in constructors, and for this reason, it is not very reliable, so check every interesting string in disasm

Passes 

As you could know passes for MachineIR should be registered with old Legacy PassManager. Let's check how macro INITIALIZE_PASS expanding - it generates static function ending with call of Registry.registerPass. More important this function gets as argument passName. It's not too hard to find it even without symbols - so we could just enum all xrefs to it and extract required pass names. I wrote hideous IDC script for IDA Pro to do this

Results:

As you can guess I also wrote yet another script (laziness is virtue) to compare passes, like

perl cpass.pl clang-passes.txt cicc-passes.txt
---- total passes 319
Not found 42 (0.131661)

Seems that cicc contains ~13% of new passes. Interesting new are:

  • nvvm-peephole-optimizer
  • nvvm-printf-lowering
  • nvvm-propagate-alignment
  • nvvm-pretreat
  • nvvm-libdevice-check
  • nvptx-mem2reg
  • nvptx-isomorphic-instr-optimizer
  • nvptx-set-global-array-alignment
  • nvptx-set-local-array-alignment

Комментариев нет:

Отправить комментарий