LLVM'nin neden ağaç benzeri bir IR yerine montaj benzeri bir IR'si var? Veya: projeler neden clang AST yerine LLVM IR'yi hedefliyor?


14

LLVM'nin ara temsil (LLVM IR) montajı neden ağaç gibi değil?

Alternatif olarak, dil uygulamaları neden clang AST'sinden ziyade LLVM IR'yi hedefliyor?

Öyle görünüyorsa, aynı anda iki farklı soru sormaya çalışmıyorum. Bana göre, hem istemci hem de kütüphane programcıları LLVM'nin API'sinin, daha fazla ve daha az bir şey olmadığı açık bir şekilde iyi bir yazılım tasarımı olduğu ve benim sorumun "neden?" Olduğu konusunda fikir birliğine varmış gibi görünüyor.

Sormamın nedeni, LLVM'nin IR'nin AST benzeri olması durumunda ön uçlara daha fazla işlevsellik sağlayabileceği gibi görünüyor çünkü clang'ın AST tabanlı araçları herhangi bir ön uç için kullanılabilir. Alternatif olarak, LLVM IR'yi hedefleyen diller, clang AST'sini hedeflediklerinde daha fazla işlevsellik elde edebilirler.

Clang, AST'leri oluşturmak ve onlarla çalışmak için sınıflara ve işlevlere sahiptir ve LLVM projesine güçlü bir şekilde bağlanan tek ön uç projesi, bu yüzden clang'ın AST işlevselliği neden LLVM'nin dışında?

Başımın üstünden, Rust (rustc), D (ldc) ve Haskell (GHC) 'nin hepsinin arka uç olarak LLVM'yi kullanabileceğini biliyorum, ancak Clang AST'yi kullanmıyorlar (bildiğim kadarıyla yanlış olmak). Bu derleyicilerin tüm iç detaylarını bilmiyorum ama en azından Rust ve D kesinlikle clang'ın AST'sine derlenmiş gibi görünüyorlar. Belki Haskell de yapabilirdi, ama bundan daha az eminim.

Bu tarihsel nedenlerden dolayı mı (LLVM başlangıçta bir "düşük seviye sanal makine" ve daha sonra gelen clang)? Bunun nedeni, diğer ön uçların LLVM'ye besledikleri şey üzerinde mümkün olduğunca fazla kontrol sahibi olmasını istedikleri için mi? Clang AST'sının "C benzeri olmayan" diller için uygunsuz olmasının temel nedenleri var mı?

Bu soruyu zihin okumada bir alıştırma olarak düşünmüyorum. Derleyici tasarımını merak eden, ancak zaten akıcı olmayanlarımız için yararlı olmasını istiyorum. LLVM ve clang projeleri halka açık olarak geliştirildiğinden, bu projelerin geliştirilmesine aşina olan birisinin cevaplayabileceğini veya cevabın, cevaplayacak kadar kendinden emin hissettikleri bazı derleyiciler için yeterince açık olduğunu umuyorum.


Açık ama tatmin edici olmayan bazı cevapları önceden çıkarmak için:

Evet, montaj benzeri bir IR'ye sahip olmak, IR'yi yapan kişi için daha fazla kontrol sağlar (belki X lang, clang'dan daha iyi bir kod tabanına ve AST formatına sahiptir), ancak tek cevap bu ise, soru neden "LLVM'nin yalnızca bir montajı var - yüksek seviyeli bir ağaç benzeri IR ve düşük seviyeli bir montaj benzeri IR yerine IR gibi? ".

Evet, bir programlama dilini AST'ye (en azından derlemenin diğer adımlarına kıyasla) ayırmak o kadar da zor değil. Yine de, neden ayrı AST'ler kullanmalıyım? Başka bir şey değilse, aynı AST'yi kullanmak, AST'ler üzerinde çalışan araçları kullanmanıza izin verir (AST yazıcıları gibi basit şeyler bile).

Evet, daha modüler olmanın iyi bir şey olduğuna kesinlikle katılıyorum, ancak tek neden buysa, diğer dil uygulamaları neden clang'ın AST'si yerine LLVM IR'yi hedefleme eğilimindedir?

Bu önyargılar hatalı olabilir veya ayrıntıları göz ardı edebilir, bu nedenle daha fazla ayrıntıya sahipseniz veya varsayımlarım yanlışsa bu cevapları vermekten çekinmeyin.


Daha kesin olarak cevaplanabilir bir soruya cevap vermek isteyen herkes için: montaj benzeri bir IR'nin ağaç benzeri bir IR'ye karşı avantajları ve dezavantajları nelerdir?


1
Ben bir LLVM uzmanı değilim, ama bence yanınızda küçük bir yanlış anlama var. LLVM'nin IR gibi bir özelliği yoktur. Aslında, IR'si bir ağaçtan çok bir grafik gibidir. Ben 'asm benzeri' ile insan tarafından okunabilir IR (* .ll dosyaları) atıfta bulunduğunu varsayıyorum, eğer öyleyse sadece kolaylık sağlamak için yapılır. Ancak, daha kapsamlı bir cevap verebilecek gerçek bir uzman
bekleyelim

1
Önemli bir özellik tarih olabilir: LLVM başlangıçta derleyici arka uçlarını derleyici ön uçlarından ayırmak için tasarlanmıştır. Fikir, derleyici satıcılarının dil optimizasyonlarında rekabet edeceği ve CPU satıcılarının düşük seviye optimizasyonlarında rekabet edeceği idi. Örneğin Microsoft ve Apple, C derleyicisi C'den "en iyi" bit kodunu üreten birbirleriyle rekabet edecek ve Intel ve AMD, LLVM arka ucu bit kodundan "en iyi" makine kodunu üreten birbirlerine karşı rekabet edeceklerdi. Uygulama satıcıları bitcode uygulamalarını gönderecek ve son derleme kullanıcının üzerinde yapılacaktı…
Jörg W Mittag

1
… Makine. LLVM, herkesin Intel'i kullanacağı hiç belli olmayan bir zamanda başladı. Apple hala PowerPC'deydi, Intel hala Itanium'u zorluyordu. AFAIK, Apple hala kodun bit kod olarak gönderildiği ve daha sonra ne tür kartın takılı olduğuna bağlı olarak nVidia veya ATI için derlendiği 3B çerçevelerinin bazılarında LLVM'yi bu şekilde kullanıyor.
Jörg W Mittag

1
Affet beni, ama IR nedir?
Adam Copley

1
@AdamCopley ara temsil
Praxeolitic

Yanıtlar:


13

Burada birbiriyle ilişkili birkaç soru var, bunları olabildiğince ayırmaya çalışacağım.

Diğer diller neden clang AST yerine LLVM IR üzerine kuruludur?

Bunun nedeni, clang'ın bir C / C ++ ön ucu olması ve ürettiği AST'nin C / C ++ ile sıkıca bağlı olmasıdır. Başka bir dil bunu kullanabilir, ancak C / C ++ 'nın bazı alt kümelerine çok benzer bir semantiğe ihtiyaç duyar. İşaret ettiğiniz gibi, bir AST'ye ayrıştırmak oldukça basittir, bu yüzden anlamsal seçimlerinizi kısıtlamanın küçük tasarruflara değer olması muhtemel değildir.

Bununla birlikte, statik analizörler gibi C / C ++ için takımlar yazıyorsanız, AST ile çalışmak, C / C ++ ile çalıştığınız ham metinten çok daha kolay olduğu için AST'yi yeniden kullanmak çok mantıklıdır. .

LLVM IR neden bu formda?

Derleyici optimizasyonları yazmak için LLVM IR uygun bir form olarak seçilmiştir. Bu nedenle, birincil özelliği SSA formunda olmasıdır. Oldukça düşük seviyeli bir IR'dir, bu nedenle çok çeşitli diller için geçerlidir, örneğin, dillere göre çok değiştiğinden bellek yazmaz.

Şimdi, derleyici optimizasyonları yazmak oldukça uzman bir görevdir ve genellikle dil özellik tasarımına diktir. Bununla birlikte, derlenmiş bir dilin hızlı çalışmasını sağlamak oldukça genel bir gerekliliktir. Ayrıca, LLVM IR'den ASM'ye dönüşüm oldukça mekaniktir ve genellikle dil tasarımcıları için ilginç değildir.

Bu nedenle, bir dili LLVM IR'ye düşürmek, bir dil tasarımcısına, dilin kendisine odaklanmasına izin veren pratikte çok yararlı olan bir çok "özgür şey" verir.

Farklı bir IR faydalı olur mu (Tamam, sorulmamış fakat bir tür zımni)?

Kesinlikle! AST'ler program yapısındaki belirli dönüşümler için oldukça iyidir, ancak program akışını dönüştürmek istiyorsanız kullanımı çok zordur. Bir SSA formu genellikle daha iyidir. Bununla birlikte, LLVM IR çok düşük seviyededir, bu nedenle yüksek seviyeli yapının çoğu kaybolur (bilerek daha genel olarak uygulanabilir). AST ve düşük seviye IR arasında bir IR'ye sahip olmak burada yararlı olabilir. Hem Rust hem de Swift bu yaklaşımı benimser ve ikisi arasında yüksek bir IR'ye sahiptir.


Haskell'in LLVM'ye geçmeden önce bir dizi IR'si var.
DylanSp

1
@ DylanSp Gerçekten. Karmaşık diller için fiili en iyi uygulama olmaya başlıyor. Örneğin, Rust başlangıçta bunu yapmadı ve yüksek seviyeli bir IR içerecek şekilde yeniden düzenlendi. Ben de bunu clang için yapmaktan bahsedildiğine inanıyorum ama bunun nereye gittiğinden emin değilim.
Alex
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.