HeadlinesBriefing HeadlinesBriefing 12 languages

Rat's Register Allocator

Hacker News ·

🇬🇧 English

October 7th, 2026 — rat, a small compiler backend with a semi-working C99 frontend, uses an x86-64 code generator that maps virtual registers (vregs) to physical registers or stack slots. The old linear-scan allocator grew to 1392 lines, prompting a rewrite of a priority bin-packing allocator in just 584 lines. This new allocator visits live ranges by importance and places each in the first fitting register, similar to LLVM's greedy allocator but simpler.

A value is live from its write to its last read; two values share a register only when never simultaneously live. When too many values are live, some spill to memory. The calling convention requires preserving callee-saved registers (rbx rbp r12-r15) while caller-saved registers may be clobbered.

As shown, the function h keeps y live across a call without explicit allocator logic for callee-saved placement. The allocator runs five steps: live ranges, fixed registers, coalescing, picking registers, and spilling. Each bundle keeps its register or stack slot for its full lifetime, never evicting or splitting ranges.

View original article →


🇸🇦 العربية

مُحسن مُرتبّب التسجيلات في Rat يقلّص الأسطر ويُنتج رمزًا أفضل

7 أكتوبر 2026 — rat هو وظيفة خلفية مُصغّر للمُترجم تحتوي على واجهة C99 شبه مُعملة، وتستخدم مُنتج كود x86-64 الذي يُخرِج التسجيلات الافتراضية (vregs) إلى تسجيلات فيزيائية أو فتحات في المخزون. نموذج التسجيلات الخطّي القديم نمو إلى 1392 سطراً، مما دفع إلى كتابة مُرتبّب التس registrations ب优先级 في 584 سطراً فقط. يُ_visit هذا المُرتبّب النطاقات الحية حسب الأهمية ويضع كل واحد في أول تسجيل مناسب، يشبه مُرتبّب Greedy في LLVM لكنه أبسط. القيمة حية من كتابتها إلى آخر قراءتها؛ مُشتركان في تسجيل واحد فقط عند عدم تزامنهما. عند تزامن قيم كثيرة، تُ spill بعضها إلى ال memory. يُطلب الحفاظ على تسجيلات المُستدعي (rbx rbp r12-r15) بينما قد تُغطَّى تسجيلات المُستدعي. كما يُظهر، الدالة h تُحافظ على y عبر مكالمة بدون منطق مُ expressly ل placing callee-saved. يُشغّل المُرتبّب خمسة خطوات: النطاقات الحية، التسجيلات الثابتة، Coalescing،اختيار التسجيلات، وال spill. يُحتفظ كل bundle ب sac recording أو فتحة المخزون طوال حياته، لا يُ expel أو يُ片段 النطاقات.

كيف يختلف مُرتبّب التس registrations ب优先级 في Rat عن التس registrations الخطّي؟

يُ_visit مُرتبّب التس registrations ب优先 النطاقات حسب الأهمية ويضع كل واحد في أول تسجيل مناسب، يُنتج رمزًا أفضل في عدد أسطر أقل (584 مقابل 1392) مقارنة بالخطّي، كما يُحافظ تلقائيًا على تسregistrations المُستدعي عبر المكالمات بدون معالجة صريحة.

العربية version →


🇧🇩 বাংলা

Rat-এর উন্নত রেজিস্টার অ্যালোকেটর লাইন কমায় এবং ভালো কোড তৈরি করে

2026 অক্টোবর 7 — rat একটি ছোট কম্পাইলার ব্যাকএন্ড যার আধা কাজকাজ C99 ফ্রন্টএন্ড, x86-64 কোড জেনারেটর ব্যবহার করে যা ভিচুয়াল রেজিস্টার (vregs) কে ফিজিক্যাল রেজিস্টার বা স্ট্যাক স্লটে ম্যাপ করে। পুরানো লিনিয়ার-স্ক্যান অ্যালোকেটর 1392 লাইনে বেড়ে যাওয়ায়, প্রাথমিকতা বিন-প্যাকিং অ্যালোকেটরকে মাত্র 584 লাইনে লেখার প্রেরিত করে। এই নতুন অ্যালোকেটর গুরুত্বের অনুসারে লাইভ রেঞ্চ প্রদর্শন করে এবং প্রতিটিকে প্রথম উপযুক্ত রেজিস্টারে রাখে, LLVM-এর গ্রীডি অ্যালোকেটরের মতো কিন্তু সরল। একটি মান তার লেখা থেকে শেষ পাঠ অবধি লাইভ থাকে; দুইটি মান একটি রেজিস্টার ভাগ করে কেবল যদি কখনো একসাথে লাইভ না হয়। অনেক মান লাইভ হলে কিছু মেমোরিতে স্পিল হয়। কলিং কনেনশন অনুযায়ী কল-সেভ্ড রেজিস্টার (rbx rbp r12-r15) সংরক্ষিত রাখতে হয় যখন কলার-সেভ্ড রেজিস্টার পরিবর্তন করা যায়। যেমন দেখানো হয়েছে, h ফাংশন কলের মধ্যে y লাইভ রাখে কল-সেভ্ড রেজিস্টার রাখার জন্য স্পষ্ট অ্যালোকেটর লজিক ছাড়াই। অ্যালোকেটর পাঁচটি স্টেপ চালায়: লাইভ রেঞ্চ, ফিক্সড রেজিস্টার, কোয়ালেসিং, রেজিস্টার পিক করা, এবং স্পিল। প্রতিটি বান্ডল তার রেজিস্টার বা স্ট্যাক স্লট সম্পূর্ণ জীবনকাল ধরে রাখে, কখনো ইভিক্ট বা ভাগ করে না।

Rat-এর প্রাথমিকতা বিন-প্যাকিং অ্যালোকেটর লিনিয়ার-স্ক্যান থেকে কেমন আলাদা?

প্রাথমিকতা বিন-প্যাকিং অ্যালোকেটর গুরুত্বের অনুসারে লাইভ রেঞ্চ প্রদর্শন করে এবং প্রতিটিকে প্রথম উপযুক্ত রেজিস্টারে রাখে, লিনিয়ার-স্ক্যানের তুলনায় কম লাইনে (584 বনাম 1392) ভালো কোড তৈরি করে এবং স্পষ্ট হ্যান্ডলিং ছাড়াই কল-সেভ্ড রেজিস্টার স্বতঃস্ফূর্তভাবে সংরক্ষণ করে।

বাংলা version →


🇩🇪 Deutsch

Rats verbesserter Registerallokator reduziert Zeilen und erzeugt besseren Code

7. Oktober 2026 — rat ist ein kleiner Compiler-Backend mit einem halbfunktionierenden C99-Frontend, verwendet einen x86-64-Codegenerator, der virtuelle Register (vregs) auf physische Register oder Stack-Slots abbildet. Der alte Linear-Scan-Allokator wuchs auf 1392 Zeilen, was eine Neuschreibung des Prioritäts-Bin-Packing-Allokators in nur 584 Zeilen nach sich zog.

Dieser neue Allokator besucht Lebensbereiche nach Wichtigkeit und platziert jeden im ersten passenden Register, ähnlich wie LLVMs greedy-Allokator, aber einfacher. Ein Wert ist von seiner Schreiboperation bis zur letzten Leseoperation lebendig; zwei Werte teilen ein Register nur, wenn sie niemals gleichzeitig lebendig sind. Wenn zu viele Werte lebendig sind, werden einige auf den Speicher ausgelagert.

Die Aufrufkonvention erfordert die Erhaltung von callee-saved-Registern (rbx rbp r12-r15), während caller-saved-Register überschrieben werden können. Wie gezeigt, bleibt die Funktion h y über einen Aufruf hinweg lebendig, ohne explizite Allokator-Logik für callee-saved-Platzierung. Der Allokator führt fünf Schritte aus: Lebensbereiche, feste Register, Coalescing, Registerauswahl und Spill.

Jedes Bundle behält sein Register oder Stack-Slot für seine gesamte Lebensdauer, niemals auswechselnd oder aufteilend.

Wie unterscheidet sich Rats Prioritäts-Bin-Packing-Allokator vom Linear-Scan?

Der Prioritäts-Bin-Packing-Allokator besucht Lebensbereiche nach Wichtigkeit und platziert jeden im ersten passenden Register, erzeugt so besseren Code in weniger Zeilen (584 vs 1392) im Vergleich zum Linear-Scan und preserved callee-saved-Register über Aufrufe hinweg automatisch ohne explizite Behandlung.

Deutsch version →


🇪🇸 Español

El nuevo asignador de registers de rat reduce líneas y genera mejor código

7 de octubre de 2026 — rat, un pequeño backend de compilador con un frontend C99 semifuncional, utiliza un generador de código x86-64 que mapea registers virtuales (vregs) a registers físicos o slots de pila. El antiguo asignador de escaneo lineal creció hasta 1392 líneas, lo que motivó una reescritura del asignador de empaquetamiento con prioridad en solo 584 líneas. Este nuevo asignador recorre los rangos vivos por importancia y coloca cada uno en el primer register adecuado, similar al asignador greedy de LLVM pero más simple.

Un valor es vivo desde su escritura hasta su última lectura; dos valores comparten un register solo cuando nunca están vivos simultáneamente. Cuando hay demasiados valores vivos, algunos se derraman a la memoria. La convención de llamadas requiere preservar registers callee-saved (rbx rbp r12-r15) mientras que los registers caller-saved pueden ser clobbered.

Como se muestra, la función mantiene y vivo a través de una llamada sin lógica explícita del asignador para la colocación de registers callee-saved. El asignador ejecuta cinco pasos: rangos vivos, registers fijos, coalescing, selección de registers y derramamiento. Cada bundle mantiene su register o slot de pila por toda su vida, nunca expulsando o dividiendo rangos.

¿Cómo difiere el asignador de empaquetamiento con prioridad de rat del escaneo lineal?

El asignador de empaquetamiento con prioridad recorre los rangos vivos por importancia y coloca cada uno en el primer register adecuado, generando mejor código en menos líneas (584 vs 1392) en comparación con el escaneo lineal, preservando naturalmente los registers callee-saved a través de llamadas sin manejo explícito.

Español version →


🇫🇷 Français

L'alisateur d'enregistrements amélioré de Rat réduit les lignes et produit un meilleur code

7 octobre 2026 — rat est un backend de compilateur petit avec un frontend C99 semi-fonctionnel, utilise un générateur de code x86-64 qui mappe les registres virtuels (vregs) vers des registres physiques ou des slots de pile. L'ancien alisateur de scan linéaire a grandi à 1392 lignes, ce qui a motivé une réécriture de l'alisateur de bin packing par priorité en seulement 584 lignes. Cet alisateur parcourt les plages de vie par importance et place chacun dans le premier registre approprié, similaire à l'alisateur greedy de LLVM mais plus simple.

Une valeur est vivante de son écriture à sa dernière lecture ; deux valeurs partagent un registre seulement lorsqu'elles ne sont jamais vivantes simultanément. Lorsque trop de valeurs sont vivantes, certaines sont spillées vers la mémoire. La convention d'appel exige de préserver les registres callee-saved (rbx rbp r12-r15) tandis que les registres caller-saved peuvent être clobbered.

Comme montré, la fonction h garde y vivant à travers un appel sans logique explicite d'alisateur pour le placement callee-saved. L'alisateur exécute cinq étapes : plages de vie, registres fixes, coalescing, choix de registres, et spill. Chaque bundle garde son registre ou slot de pile pour toute sa durée de vie, jamais d'éviction ou de division de plages.

Comment l'alisateur de bin packing par priorité de Rat diffère-t-il du scan linéaire ?

L'alisateur de bin packing par priorité parcourt les plages de vie par importance et place chacun dans le premier registre approprié, produisant un meilleur code en moins de lignes (584 vs 1392) par rapport au scan linéaire, préservant naturellement les registres callee-saved à travers les appels sans handling explicite.

Français version →


🇮🇳 हिन्दी

Rat का सुधरा रजिस्टर एलोकेटर पंक्तियाँ कम करता है और बेहतर कोड बनाता है

2026 अक्टूबर 7 — rat एक छोटा कंपाइलर बैकएंड है जिसमें आधा कामकाज C99 फ्रंटएंड है और यह x86-64 कोड जनरेटर उपयोग करता है जो वर्चुअल रजिस्टर (vregs) को शारीरिक रजिस्टर या स्टैक स्लॉट में मैप करता है। पुराना लीनियर-स्कैन एलोकेटर 1392 पंक्तियों तक बढ़ गया, जिसने प्राथमिकता बिन-पैकिंग एलोकेटर को महज 584 पंक्तियों में लिखने को प्रेरित किया। यह नया एलोकेटर महत्व के अनुसार लाइव रेंजों को दौर करता है और हर एक को पहले उपयुक्त रजिस्टर में रखता है, LLVM के ग्रीडी एलोकेटर की तरह लेकिन सरल। एक मान अपनी लिखाई से लेकर अंतिम पठन तक लाइव रहता है; दो मान केवल तब एक रजिस्टर साझा करते हैं जब वे कभी एक साथ लाइव न हों। बहुत से मान लाइव होने पर कुछ मेमोरी में स्पिल हो जाते हैं। कॉलिंग कन्वेंशन में कॉल-सेव्ड रजिस्टर (rbx rbp r12-r15) संरक्षित रखने की आवश्यकता होती है जबकि कॉलर-सेव्ड रजिस्टर बदले जा सकते हैं। जैसा कि दिखाया गया, फंक्शन h कॉल के दौरान y को लाइव रखता है बिना कॉल-सेव्ड रजिस्टर रखने की स्पष्ट लॉजिक के। एलोकेटर पांच चरणों में चलता है: लाइव रेंज, फिक्स्ड रजिस्टर, कोएलेसिंग, रजिस्टर चुनना और स्पिलिंग। हर बंडल अपनी पूरी जिंदगी अपना रजिस्टर या स्टैक स्लॉट रखता है, कभी भी एविक्ट नहीं करता या रेंज नहीं तोड़ता।

Rat का प्राथमिकता बिन-पैकिंग एलोकेटर लीनियर-स्कैन से कैसे अलग है?

प्राथमिकता बिन-पैकिंग एलोकेटर महत्व के अनुसार लाइव रेंजों को दौर करता है और हर एक को पहले उपयुक्त रजिस्टर में रखता है, जिससे लीनियर-स्कैन की तुलना में कम पंक्तियों (584 vs 1392) में बेहतर कोड बनता है और बिना स्पष्ट हैंडलिंग के स्वतः कॉल-सेव्ड रजिस्टर संरक्षित हो जाते हैं।

हिन्दी version →


🇮🇩 Bahasa Indonesia

Alokasi register yang ditingkatkan dari Rat mengurangi baris dan menghasilkan code yang lebih baik

7 Oktober 2026 — rat adalah backend compiler kecil dengan frontend C99 semi-fungsional, menggunakan x86-64 code generator yang memetakan register virtual (vregs) ke register fisik atau slot stack. Alokasi linear scan lama bertumbuh menjadi 1392 baris, mendorong penulisan ulang alokasi bin packing dengan prioritas dalam hanya 584 baris. Alokasi baru ini mengunjungi rentang hidup berdasarkan kepentingan dan menempatkan masing-masing di register pertama yang cocok, mirip dengan alokasi greedy LLVM tapi lebih sederhana.

Satu nilai hidup dari tulisan hingga pembacaan terakhir; dua nilai berbagi register hanya ketika tidak pernah hidup secara bersamaan. Ketika terlalu banyak nilai hidup, some spill ke memori. Konvensi pemanggilan mengharuskan menjaga register callee-saved (rbx rbp r12-r15) sedangkan register caller-saved dapat di-overwrite.

Seperti ditunjukkan, fungsi h menjaga y hidup melalui panggilan tanpa logika alokasi eksplisit untuk penempatan callee-saved. Alokasi menjalankan lima langkah: rentang hidup, register tetap, coalescing, pemilihan register, dan spill. Setiap bundle menjaga register atau slot stack untuk seluruh hidupnya, never evicting atau splitting rentang.

Bagaimana alokasi bin packing dengan prioritas dari Rat berbeda dari linear scan?

Alokasi bin packing dengan prioritas mengunjungi rentang hidup berdasarkan kepentingan dan menempatkan masing-masing di register pertama yang cocok, menghasilkan code yang lebih baik dalam lebih sedikit baris (584 vs 1392) dibandingkan linear scan, sekaligus secara alami menjaga register callee-saved melalui panggilan tanpa penanganan eksplisit.

Bahasa Indonesia version →


🇯🇵 日本語

Ratの改良されたレジスタ割り当ては行数を削減し、より良いコードを生成

2026年10月7日 — ratは、半分動作するC99フロントエンドを持つ小型のコンパイラバックエンドであり、x86-64コード生成器を使用して仮想レジスタ(vregs)を物理レジスタまたはスタックスロットにマッピングします。従来のリニアスキャン割り当ては1392行に達したため、584行で優先度付きビンパッキング割り当ての書き換えが行われました。この新しい割り当ては重要性に従って生存期間を訪問し、各値を最初の適合レジスタに配置します。LLVMの貪欲割り当てに似ていますが、より簡素です。値は書き込みから最後の読みまで生存し、2つの値は絶対に同時生存しない場合にのみレジスタを共有します。生存値が多すぎると、一部がメモリにスパイルされます。呼び出し惯例では、callee-savedレジスタ(rbx rbp r12-r15)を保持する必要があり、caller-savedレジスタは上書きされます。示されているように、関数hは、callee-saved配置の明示的ロジックなしで呼び出し間でyを生存させます。割り当ては5つのステップを実行します:生存期間、固定レジスタ、コalesce、レジスタ選択、スパイリング。各バンドルは lifetime全体にわたってレジスタまたはスタックスロットを保持し、イベントや分割ません。

Ratの優先度付きビンパッキング割り当てはリニアスキャンとどう違いますか?

優先度付きビンパッキング割り当ては重要性に従って生存期間を訪問し、各値を最初の適合レジスタに配置します。これにより、リニアスキャンと比較して少ない行数(584対1392)でより良いコードを生成し、明示的な処理なしに callee-savedレジスタを呼び出し間で自然に保存します。

日本語 version →


🇧🇷 Português

O novo alocador de registradores de Rat reduz linhas e gera melhor código

7 de outubro de 2026 — rat é um backend de compilador pequeno com um frontend C99 semifuncional, usa um gerador de código x86-64 que mapeia registradores virtuais (vregs) para registradores físicos ou slots de pilha. O antigo alocador de varredura linear cresceu para 1392 linhas, motivando uma reescrita do alocador de bin packing por prioridade em apenas 584 linhas. Este novo alocador visita intervalos de vida por importância e coloca cada um no primeiro registrador adequado, semelhante ao alocador greedy do LLVM, mas mais simples.

Um valor é vivo de sua escrita até sua última leitura; dois valores compartilham um registrador apenas quando nunca estão vivos simultaneamente. Quando muitos valores estão vivos, alguns são spillados para a memória. A convenção de chamada exige preservar registradores callee-saved (rbx rbp r12-r15) enquanto registradores caller-saved podem ser sobrescritos.

Como mostrado, a função manteém y vivo através de uma chamada sem lógica explícita do alocador para posicionamento callee-saved. O alocador executa cinco passos: intervalos de vida, registradores fixos, coalescing, escolha de registradores e spill. Cada bundle mantém seu registrador ou slot de pilha por toda a sua vida, nunca expelindo ou dividindo intervalos.

Como o alocador de bin packing por prioridade de Rat difere da varredura linear?

O alocador de bin packing por prioridade visita intervalos de vida por importância e coloca cada um no primeiro registrador adequado, gerando melhor código em menos linhas (584 vs 1392) em comparação com a varredura linear, preservando naturalmente registradores callee-saved através de chamadas sem tratamento explícito.

Português version →


🇷🇺 Русский

Улучшенный аллокатор регистров Rat сокращает строки и генерирует лучший код

7 октября 2026 года — rat — небольшой бэкенд компилятора с полупод_working C99-фронтендом, использует x86-64 генератор кода, который отображает виртуальные регистры (vregs) в физические регистры или слоты стека. Старый линейно-скан аллокатор вырос до 1392 строк, что привело к переписыванию аллокатора bin packing с приоритетом всего в 584 строки. Этот новый аллокатор посещает интервалы жизни по важности и помещает каждый в первый подходящий регистр, подобно жадному аллокатору LLVM, но проще. Значение живет от его записи до последнего чтения; два значения делят регистр только когда они никогда не живут одновременно. Когда слишком много значений живут, некоторые спиллятся в память. Конвенция вызовов требует сохранения callee-saved регистров (rbx rbp r12-r15), в то время как caller-saved регистры могут быть затертыми. Как показано, функция h держит y живым через вызов без явной логики аллокатора для callee-saved размещения. Аллокатор выполняет пять шагов: интервалы жизни, фиксированные регистры, коалесцинг, выбор регистров и спиллинг. Каждый bundle сохраняет свой регистр или слот стека на протяжении всей своей жизни, никогда не вытесняя или деля интервалы.

Как аллокатор bin packing с приоритетом в Rat отличается от линейно-скан?

Аллокатор bin packing с приоритетом посещает интервалы жизни по важности и помещает каждый в первый подходящий регистр, генерируя лучший код в fewer строках (584 против 1392) по сравнению с линейно-скан, естественным образом сохраняя callee-saved регистры через вызовы без явной обработки.

Русский version →


🇨🇳 简体中文

Rat 的改进型寄存器分配器减少了代码行数,生成了更优代码

2026 年 10 月 7 日 —— rat 是一个小型编译器后端,拥有一个半工作的 C99 前端,使用 x86-64 代码生成器将虚拟寄存器(vregs)映射到物理寄存器或栈槽。原有的线性扫描分配器增长到 1392 行,促使团队用仅 584 行代码重写了优先级装箱分配器。该新分配器按重要性访问活跃范围,并将每个值放入第一个合适的寄存器中,类似于 LLVM 的贪心分配器,但更为简化。一个值从其写入到最后一次读取之间保持活跃;两个值仅在永不同时活跃时才共享寄存器。当活跃值过多时,部分值会被溢出到内存。调用约定要求保留被调用者保存的寄存器(rbx rbp r12-r15),而调用者保存的寄存器可能被覆盖。如所示,函数 h 在调用过程中保持 y 活跃,而无需显式处理被调用者保存寄存器的分配逻辑。分配器运行五个步骤:活跃范围、固定寄存器、合并、选择寄存器和溢出。每个 bundle 在其整个生命周期内保持其寄存器或栈槽,绝不驱逐或拆分范围。

rat 的优先级装箱分配器与线性扫描分配器有何不同?

优先级装箱分配器按重要性访问活跃范围,并将每个值放入第一个合适的寄存器中,相比线性扫描分配器,用更少的代码行数(584 对 1392)生成更优代码,同时无需显式处理即可自然保留跨调用的被调用者保存寄存器。

简体中文 version →