O0 dan debugging
Aturan untuk menyimpan penghitungan, ekspresi konstan, ruang penyimpanan, dan informasi respons debug.
Wave Foundation
model konservasi
O0 mempertahankan perhitungan, variabel, dan aliran kontrol dari typed IR asli untuk tujuan debugging. Itu juga menyimpan hasil yang tidak digunakan dan blok yang secara struktural tidak dapat dijangkau. Verifikasi mendiagnosis kesalahan IR dan tidak menghapus blok atau menyederhanakan operasi.
Konversi yang diperlukan untuk menghasilkan bahasa mesin dilakukan dalam sub-sub terpisah IR. Bahkan setelah konversi, korespondensi dengan ID asli harus dipertahankan. typed IR konservasi tidak berarti korespondensi satu-ke-satu dari semua operasi dan instruksi mesin IR.
Konversi tidak dilakukan oleh O0
| konversi | O0 Operasi |
|---|---|
| sebaris | Pertahankan batasan panggilan dan fungsi |
| Konversi Tail-call | Pertahankan struktur panggilan/pengembalian umum |
| menghapus kode mati | Pertahankan komputasi yang tidak digunakan dan blok yang tidak dapat dijangkau |
| Ciutkan konstanta runtime | pertahankan operasi aslinya |
| Gabungkan perhitungan umum | Simpan perhitungan terpisah |
| Penggunaan kembali ruang penyimpanan variabel lokal | Jaga setiap ruang penyimpanan |
| Hilangkan penunjuk bingkai | mempertahankan penunjuk bingkai |
| Penggabungan string secara otomatis | Pertahankan objek string yang terpisah |
Misalnya, operasi runtime yang menambahkan dua konstanta akan tetap menjadi tambahan meskipun hasilnya tidak digunakan. Cabang-cabang dengan kondisi konstan juga mempertahankan struktur aliran kendali aslinya.
konstanta waktu kompilasi
Deklarasi konstanta waktu kompilasi mempertahankan ekspresi inisialisasi typed dan hasil evaluasi. Hal ini berbeda dengan pelipatan konstan pada instruksi runtime biasa.
Deklarasi dengan ekspresi inisialisasi 1 + 2 dibiarkan dengan ekspresi penjumlahan dan hasil 3. Contoh ini mengilustrasikan arti ungkapan dan bukan tata bahasa deklaratif bahasa sumber tertentu. Hasilnya dapat digunakan saat membuat data statis dan tidak menggantikan ekspresi inisialisasi dengan penambahan runtime.
Deklarasi yang tidak digunakan dan tidak dapat dijangkau juga harus diidentifikasi. Meskipun deklarasi dengan nama yang sama mengaburkan satu sama lain, deklarasi tersebut harus dipisahkan berdasarkan nama·deklarasi ID·referensi. Validasi menolak hasil tersimpan yang memiliki referensi tidak valid, siklus ketergantungan, tipe tidak valid, atau tidak cocok dengan ekspresi aslinya.
pernyataan sumber yang tidak dapat dijangkau
Kalimat setelah return·break·continue juga tetap berada dalam blok yang tidak terhubung. Karena pernyataan ini, Anda tidak boleh mengubah terminator sebelumnya atau membuat jalur eksekusi baru. Ini juga mendiagnosis ekspresi yang tidak valid dalam kalimat yang tidak dapat dijangkau.
Aturan pelestarian ini memungkinkan pemeriksaan struktur program asli. Ini tidak berarti bahwa pernyataan setelah terminator akan benar-benar dieksekusi.
Contoh IR yang diawetkan
Di bawah ini adalah keluaran printer saat ini untuk modul yang lolos verifikasi. Menampilkan penghitungan yang tidak digunakan, deklarasi waktu kompilasi, dan blok yang tidak tertaut.
module {
format_version 2
semantics_version 1
target "x86_64-whale-linux"
datalayout { ptr=64, endian=little }
declare @f0 "preserved": whale () -> void, linkage internal
fn @preserved() -> void, id @f0 {
entry:
%v0: i32 = const i32 1
%v1: i32 = const i32 2
%v2: i32 = add i32 %v0, %v1
%v3: i32 = const_decl "count" add(i32 1, i32 2) => const i32 3
ret void
unreachable.cont:
%v4: i32 = const i32 4
%v5: i32 = const i32 5
%v6: i32 = add i32 %v4, %v5
ret void
}
}
%v2 tetap menjadi add meskipun tidak ada gunanya. %v3 adalah const_decl terpisah, yang mempertahankan ekspresi add(i32 1, i32 2) dan hasil evaluasi 3 secara bersamaan. Karena unreachable.cont tidak memiliki tepi masuk, kita dapat memeriksa penambahan %v6 tanpa menambahkan jalur eksekusi setelah ret void.
Verifikasi mempertahankan instruksi dan blok ini. Contoh ini menunjukkan IR konfigurasi/verifikasi/output dan tidak berarti bahwa native eksekusi atau output DWARF disediakan.
Sumber dan Informasi Tumpukan
Antarmuka debug menggunakan informasi fungsi, baris sumber, variabel lokal default, dan informasi bingkai panggilan dari DWARF 5. Bahkan jika dikonversi ke sub-ekspresi, korespondensi antara informasi fungsi/variabel lokal dan pengidentifikasi IR asli harus dipertahankan.
Profil AMD64 mempertahankan penunjuk bingkai dan tidak menggunakan red zone. Informasi bingkai panggilan digunakan untuk pemeriksaan tumpukan dan tidak menyiratkan dukungan untuk pengecualian unwinding. trap menghentikan eksekusi tanpa menjamin destruktor atau unwinding.
Silakan merujuk ke Ikhtisar rantai alat untuk ketersediaan keluaran DWARF dan eksekusi native. Perilaku O1 dan optimasi di atas berada di luar cakupan referensi O0 ini.