Instruction Combining — bir nechta oraliq kod amallarini semantik jihatdan teng, odatda sodda yoki targetga qulayroq bitta amalga birlashtiradigan optimallashtirish. U peephole transformatsiyadan tortib SSA asosidagi algebraik soddalashtirishgacha bo‘lishi mumkin.
Qayta yozish qoidalari
(x + 1) + 2 shartlar mos bo‘lsa x + 3 ga, x * 2 esa shiftga aylanishi mumkin. zext(trunc(x)) mask bilan ifodalanadi. Biroq integer overflow, signed shift, poison/undefined value va floating-point rounding qoidalari har algebraik tenglikni qonuniy qilmaydi.
Use-def shartlari
Combiner patternni IR DAG yoki use-def chain bo‘yicha topadi. Bir instructionning yagona use’i bo‘lsa uni consumer ichiga yutish oson; bir nechta use bo‘lsa o‘chirish mumkin emas. Canonical form yaratish boshqa optimizatsiyalar uchun patternlarni bir xil ko‘rinishga keltiradi.
Target semantikasi
Target-independent combine umumiy semantikani soddalashtiradi, target-specific combine esa addressing mode, fused multiply-add yoki bitfield instructiondan foydalanadi. FMA a*b+c ni bitta rounding bilan hisoblaydi, shu sabab strict floating-point rejimida alohida multiply va add bilan bitwise teng bo‘lmasligi mumkin.
Tugash va xarajat
Rewrite qoidalari cycle yaratmasligi uchun canonical ordering va profitability talab qilinadi. A → B va B → A qoidalari cheksiz takrorlanmasligi kerak. Code size, latency va throughput maqsadlari ba’zan qarama-qarshi; optimizer target cost modeldan foydalanadi.
Formal tekshiruv
Har rule Alive2 singari formal IR verifier yoki exhaustive kichik bit-width test bilan tekshirilishi mumkin. Regression test exact IR pattern va runtime qiymatlarni qamraydi. Undefined inputlarda istalgan natijani reference deb qabul qilish o‘rniga IRning definedness shartlari alohida solishtiriladi.
Instruction Combining bo‘yicha tahlil natijasi faqat yakuniy xulosa bilan emas, uni hosil qilgan IR versiyasi, target xususiyatlari va qo‘llangan taxminlar bilan birga saqlanadi. Compiler passlari ketma-ket o‘zgarganda oldingi natija avtomatik ravishda haqiqiy deb olinmaydi: tegishli dependencylar invalidatsiya qilinib, zarur qism qayta hisoblanadi. Debug rejimida asosiy invariant buzilgan nuqta va undan oldingi transformatsiya qayd etiladi; release rejimida esa tekshiruvlarning arzon qismi qoldiriladi. Shu yondashuv nazariy jihatdan qonuniy qoida implementatsiya xatosi yoki noto‘g‘ri cost model sabab zararli qarorga aylangan holatni ajratishga yordam beradi.
Kengaytirilgan jihatlar
Instruction combine strength reductiondan foydalanishi mumkin, ammo “kam instruction” har doim “tezroq” emas. Target microarchitecture ayrim murakkab instructionni ko‘p micro-opga ajratadi yoki uzun latency beradi. Constant materialization ham tanlov xarajatiga kiradi: katta immediate uchun qo‘shimcha instruction kerak bo‘lishi mumkin. IR combine targetdan oldin haddan tashqari target-specific shakl yaratsa, boshqa arxitekturaga code generation yomonlashadi. Shu sabab canonical IR va late machine peephole vazifalari ajratiladi. Compile-time regressiyani nazorat qilish uchun har pattern urilish soni, worklist qayta tashrifi va IR size o‘zgarishi o‘lchanadi.
Combiner rule source patternni o‘chirayotganda debug value’ni yangi instructionga ko‘chiradi yoki qiymat joylashuvi tugaganini belgilaydi. Sanitizer va trap instructionlar observable bo‘lgani uchun oddiy arifmetik node kabi yutilmaydi. Optimization level code size yoki speed maqsadini tanlaydi; rule profitabilitysi shu siyosatga mos ravishda o‘zgaradi.
Bog‘liq tushunchalar
peephole optimization, constant folding, canonicalization, use-def chain, target instruction, algebraic simplification