Berikut adalah file C sederhana dengan definisi enum dan main
fungsi:
enum days {MON, TUE, WED, THU};
int main() {
enum days d;
d = WED;
return 0;
}
Ini mentranspile ke LLVM IR berikut:
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 2, i32* %2, align 4
ret i32 0
}
%2
jelas d
variabel, yang mendapat 2 ditugaskan untuk itu. Apa yang %1
berhubungan dengan jika nol dikembalikan secara langsung?
c
llvm
llvm-codegen
macleginn
sumber
sumber
clang-9 -S -emit-llvm simple.c
main
( godbolt.org/z/kEtS-s ). Tautan menunjukkan bagaimana perakitan dipetakan ke sumbermain
, variabel ekstra misterius menghilang. Menariknya, itu juga menghilang jika Anda menghilangkanreturn
pernyataan sepenuhnya (yang legal untukmain
dalam C dan setara denganreturn 0;
).main
seperti yangint main(int argc, char **argv)
Anda lihatargc
danargv
disalin ke tumpukan, tetapi variabel nol misterius masih ada di samping mereka.Jawaban:
Ini
%1
mendaftar dihasilkan oleh dentang untuk menangani beberapa pernyataan kembali dalam fungsi . Bayangkan Anda memiliki fungsi untuk menghitung faktorial bilangan bulat. Alih-alih menulisnya seperti iniAnda mungkin akan melakukan ini
Mengapa? Karena Dentang akan memasukkan
result
variabel yang memegang nilai pengembalian untuk Anda. Yay. Itulah tujuan persisnya%1
. Lihatlah ir untuk versi kode Anda yang sedikit dimodifikasi.Kode yang dimodifikasi,
IR,
Sekarang Anda lihat itu
%1
membuat dirinya berguna ya? Seperti yang lain telah tunjukkan, untuk fungsi dengan hanya satu pernyataan pengembalian, variabel ini mungkin akan dilucuti oleh salah satu operan optimal llvm.sumber
Mengapa ini penting - apa masalah sebenarnya?
Saya pikir jawaban yang lebih dalam yang Anda cari mungkin: Arsitektur LLVM didasarkan di sekitar antarmuka yang cukup sederhana dan banyak lintasan. Frontend harus menghasilkan kode yang benar, tetapi tidak harus berupa kode yang baik. Mereka dapat melakukan hal paling sederhana yang berhasil.
Dalam hal ini, Dentang menghasilkan beberapa instruksi yang ternyata tidak dapat digunakan untuk apa pun. Itu umumnya bukan masalah, karena beberapa bagian dari LLVM akan menyingkirkan instruksi yang berlebihan. Dentang percaya itu akan terjadi. Dentang tidak perlu menghindari memancarkan kode mati; implementasinya dapat fokus pada kebenaran, kesederhanaan, testabilitas, dll.
sumber
Karena Dentang dilakukan dengan analisis sintaks tetapi LLVM bahkan belum mulai dengan optimasi.
Ujung depan Dentang telah menghasilkan IR (Representasi Menengah) dan bukan kode mesin. Variabel-variabel tersebut adalah SSA (Tugas Statis Tunggal); mereka belum terikat register dan sebenarnya setelah optimasi, tidak akan pernah terjadi karena mereka berlebihan.
Kode itu adalah representasi sumber yang agak literal. Inilah yang bergantung pada LLVM untuk optimisasi. Pada dasarnya, LLVM mulai dengan itu dan mengoptimalkan dari sana. Memang, untuk versi 10 dan x86_64, llc -O2 pada akhirnya akan menghasilkan:
sumber