Константа савијања

Константа савијања и константа пропагације су повезане оптимизације компајлера које користе многи модерни компајлери. Напредна форма константе пропагације, позната као распршена условна константа пропагације, може много прецизније да изврши ширење константи и у исто време да уклања мртав код.

Константа савијања уреди

Константа савијања је процес препознавања и израчунавања константних израза за време превођења, а не у време извршавања програма. Терми у константним изразима су обично прости литерали, као на пример целобројни литерал 2, али, такође, то могу бити и променљиве чија се вредност зна већ за време превођења. Размотримо следећу наредбу:

  i = 320 * 200 * 32;

Многи напредни преводиоци неће стварно генерисати две инструкције превођења и простор за ову наредбу. Уместо тога, идентификоваће конструкте попут ових и замениће израчунату вредност у време самог превођења.(у овом случају, 2.048.000). Резултујући код ће учитати једну већ израчунату вредност, уместо учитавања и множења неколико вредности.

Савијање константи може чак користити и аритметичке идентитете. Када је x целобројног типа, вредност израза 0 * x је нула, чак иако преводилац не зна вредност променљиве x.

Савијање константи се не примењује само на бројеве. Надовезивање (конкатенација) стринговних(низова карактера) литерала и константних низова карактера може бити савијено у константу. Код попут овог: "abc" + "def" може бити замењен кодом: "abcdef".

Савијање константи може бити урађено и у фронт-енду преводиоца на ИР дрвету, које представља изворни језик вишег нивоа, пре него што је преведен у адресни код дрвета, или у бацк енду, као додатак ширењу константи.

Савијање константи и цросс преводилац уреди

При имплементацији цросс преводиоца, мора се обезбедити да се понашање аритметичких операција на хост архитектури одговара оној на циљној архитектури. У супротном, ако дозволимо савијање константи, можемо, несмотрено, променити понашање самог програма. Ово је од великог значаја за операције са децималним заретом, чија имплеметација може веома да се разликује.

Ширење константи уреди

Ширење константи процес замене познатих вредности неких константи за време превођења. Ове константе укључују оне дефинисане изнад, као и интринсиц функције примењене на константне вредности. Размотримо следећи псеудокод:

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

Ширење(пропагација) променљиве x чека:

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

Наставак ширења зауставља и следећи код (који би даље био оптимизован путем уклањања мртвог кода променљивих x и y.)

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

Ширење константи је у компајлеру предтсављено коришћењем анализирања резултата доступних дефиниција. Ако све доступне дефиниције једне променљиве представљају исту доделу тј. додељују исту вредност константе променљивој, тада променљива има константну вредност и може бити замењена константом. Ширење константи може узроковати и поједносталвјивање условних грана, њиховом трансформацијом у јенду или више наредби без услова, у случају када условни израз може бити израчунат у време превођења, како би се утврдила његова коначна вредност.

Оптимизација на делу уреди

Савијање константи и њихово ширење, најчешће су коришћене заједно, како би се постигло што више редукција и упрошћавања. Итеративно их користимо, преклапајући их, док ни једна измена више не буде могућа. Размотримо следећи псеудокод:

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

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

Примењујемо ширење константи једном, затим савијамо константе, након тога код изгледа овако:

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

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

Понављамо оба корака два пута, следи резултат:

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

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

Како су a и b упроштени у константе и њихове вредности замењене свуда где су се појављивале, преводилац сада примењује уклањање мртвог кода како би их одбацио и тиме додатно упростио код :

  int c;
  c = 12;

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

У коду изнад, уместо True може стајати број 1 или било која Боолеан ознака, зависно од преводиоца. Традиционалним ширењем константи, добијамо само оволику оптимизацију. Не можемо променити структуру програма.

Постоји још једна, слична, оптимизација, звана проређено ширење константи, која бира одговарајућу грану на основу if-condition.[1] . Преводилац сада може да открије да ће се if наредба извршити у труе, c може бити елиминисана, код се смањује још више:

  return 4;

Ако би овај псеудокод чинио тело функције, преводилац, даље, може искористити информацију о томе да ће резултат извршавања бити цео број4 како би уклонио непотребне позиве функције, резултујући даљим побољшањем перформанси.

Види још уреди

Референце уреди

  1. ^ Wегман, Марк Н.; Задецк, Ф. Кеннетх (април 1991), „Цонстант Пропагатион wитх Цондитионал Бранцхес”, АЦМ Трансацтионс он Программинг Лангуагес анд Сyстемс, 13 (2): 181—210, дои:10.1145/103135.103136 

Литература уреди