Konstanta savijanja
Konstanta savijanja i konstanta propagacije su povezane optimizacije kompajlera koje koriste mnogi moderni kompajleri. Napredna forma konstante propagacije, poznata kao raspršena uslovna konstanta propagacije, može mnogo preciznije da izvrši širenje konstanti i u isto vreme da uklanja mrtav kod.

Konstanta savijanja 

Konstanta savijanja je proces prepoznavanja i izračunavanja konstantnih izraza za vreme prevođenja, a ne u vreme izvršavanja programa. Termi u konstantnim izrazima su obično prosti literali, kao na primer celobrojni literal 2, ali, takođe, to mogu biti i promenljive čija se vrednost zna već za vreme prevođenja. Razmotrimo sledeću naredbu:

  i = 320 * 200 * 32;

Mnogi napredni prevodioci neće stvarno generisati dve instrukcije prevođenja i prostor za ovu naredbu. Umesto toga, identifikovaće konstrukte poput ovih i zameniće izračunatu vrednost u vreme samog prevođenja.(u ovom slučaju, 2.048.000). Rezultujući kod će učitati jednu već izračunatu vrednost, umesto učitavanja i množenja nekoliko vrednosti.

Savijanje konstanti može čak koristiti i aritmetičke identitete. Kada je x celobrojnog tipa, vrednost izraza 0 * x je nula, čak iako prevodilac ne zna vrednost promenljive x. 

Savijanje konstanti se ne primenjuje samo na brojeve. Nadovezivanje (konkatenacija) stringovnih(nizova karaktera) literala i konstantnih nizova karaktera može biti savijeno u konstantu. Kod poput ovog: "abc" + "def" može biti zamenjen kodom: "abcdef".

Savijanje konstanti može biti urađeno i u front-endu prevodioca na IR drvetu, koje predstavlja izvorni jezik višeg nivoa, pre nego što je preveden u adresni kod drveta, ili u back endu, kao dodatak širenju konstanti.

Savijanje konstanti i cross prevodilac 

Pri implementaciji cross prevodioca, mora se obezbediti da se ponašanje aritmetičkih operacija na host arhitekturi odgovara onoj na ciljnoj arhitekturi. U suprotnom, ako dozvolimo savijanje konstanti, možemo, nesmotreno, promeniti ponašanje samog programa. Ovo je od velikog značaja za operacije sa decimalnim zaretom, čija implemetacija može veoma da se razlikuje.

Širenje konstanti 

Širenje konstanti proces zamene poznatih vrednosti nekih konstanti za vreme prevođenja. Ove konstante uključuju one definisane iznad, kao i intrinsic funkcije primenjene na konstantne vrednosti. Razmotrimo sledeći pseudokod:

  int x = 14;
  int y = 7 - x / 2;
  return y * (28 / x + 2);

Širenje(propagacija) promenljive x čeka:

  int x = 14;
  int y = 7 - 14 / 2;
  return y * (28 / 14 + 2);

Nastavak širenja zaustavlja i sledeći kod (koji bi dalje bio optimizovan putem uklanjanja mrtvog koda promenljivih x i y.)

  int x = 14;
  int y = 0;
  return 0;

Širenje konstanti je u kompajleru predtsavljeno korišćenjem analiziranja rezultata dostupnih definicija. Ako sve dostupne definicije jedne promenljive predstavljaju istu dodelu tj. dodeljuju istu vrednost konstante promenljivoj, tada promenljiva ima konstantnu vrednost i može biti zamenjena konstantom. 
Širenje konstanti može uzrokovati i pojednostalvjivanje uslovnih grana, njihovom transformacijom u jendu ili više naredbi bez uslova, u slučaju kada uslovni izraz može biti izračunat u vreme prevođenja, kako bi se utvrdila njegova konačna vrednost.

Optimizacija na delu 

Savijanje konstanti i njihovo širenje, najčešće su korišćene zajedno, kako bi se postiglo što više redukcija i uprošćavanja. Iterativno ih koristimo, preklapajući ih, dok ni jedna izmena više ne bude moguća. 
Razmotrimo sledeći pseudokod:

  int a = 30;
  int b = 9 - (a / 5);
  int c;

  c = b * 4;
  if (c > 10) {
     c = c - 10;
  }
  return c * (60 / a);

Primenjujemo širenje konstanti jednom, zatim savijamo konstante, nakon toga kod izgleda ovako:

  int a = 30;
  int b = 3;
  int c;

  c = b * 4;
  if (c > 10) {
     c = c - 10;
  }
  return c * 2;

Ponavljamo oba koraka dva puta, sledi rezultat:

  int a = 30;
  int b = 3;
  int c;

  c = 12;
  if (true) {
     c = 2;
  }
  return c * 2;

Kako su a i b uprošteni u konstante i njihove vrednosti zamenjene svuda gde su se pojavljivale, prevodilac sada primenjuje uklanjanje mrtvog koda kako bi ih odbacio i time dodatno uprostio kod :

  int c;
  c = 12;

  if (true) {
     c = 2;
  }
  return c * 2;
U kodu iznad, umesto True može stajati broj 1 ili bilo koja Boolean oznaka, zavisno od prevodioca. Tradicionalnim širenjem konstanti, dobijamo samo ovoliku optimizaciju. Ne možemo promeniti strukturu programa.

Postoji još jedna, slična, optimizacija, zvana proređeno širenje konstanti, koja bira odgovarajuću granu na osnovu if-condition. . Prevodilac sada može da otkrije da će se if naredba izvršiti u true, c može biti eliminisana, kod se smanjuje još više:

  return 4;

Ako bi ovaj pseudokod činio telo funkcije, prevodilac, dalje, može iskoristiti informaciju o tome da će rezultat izvršavanja biti ceo broj4 kako bi uklonio nepotrebne pozive funkcije, rezultujući daljim poboljšanjem performansi.

Vidi još 
 Control flow graph
 Use-define chain and SSA form
 Copy propagation
 Common subexpression elimination
 Partial evaluation

Reference

Literatura 
 

Оптимизација компилатора