2012-04-28 20 views
12

Czy istnieje C/C++ kompilator dojrzałe, zdolne do optymalizacji malloc/free (lub new/delete) par informacji alloca? Innymi słowy, konwertuj z pamięci opartej na sterty do opartej na stosach (TYLKO dla niektórych ograniczonych przypadków).Will Compiler optymalizacji malloc/free lub nowe/usuwać parę do alloca

Ta optymalizacja może być dozwolona tylko dla pary malloc/free, gdy obie funkcje są w tej samej funkcji (lub nawet w tym samym bloku {}), a wolna jest wywoływana za każdym razem, gdy wywoływana jest funkcja malloc. Rozważmy także, że wskaźnik do pamięci mallokowanej nie jest zapisywany w niektórych zmiennych globalnych.

Tak, będzie GCC/LLVM + szczęk/Intel Compiler przekonwertować taki fragment kodu:

{ 
    char *carray; 
    carray = malloc(100);   // or malloc(N) 
    // some string-like work with carray 
    free(carray); 
} 

do

{ 
    char*carray; 
    carray = alloca(100); // or if(N<const1) carray=alloca(N);else carray=malloc(N) 
    // the same work 
    // nothing      // or if(N>=const1) free(carray) 
} 

Konwersja ta może nie być bardzo przydatna dla każdego programu, ale myślę, może istnieć specjalna opcja kompilatora.

PS (update1) Możemy ograniczyć nasze rozważania tylko do przypadków, gdy kompilator wie, że malloc i wolna jest od libc (stdlib)

+1

Rok temu jeden człowiek na liście llvm [powiedział nie] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/032971.html) i inny człowiek [powiedział tak] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033015.html) i wskazuje na [faktyczny kod] (http: //lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033017.html) – osgx

+3

Myślę, że malloc nie jest nieodłączny. Jest to dość niebezpieczne, ponieważ kompilator nie ma informacji o rozmiarze stosu w czasie wykonywania. – BlueWanderer

+0

Transformacja jest niebezpieczna, jeśli zostanie wywołana jakakolwiek inna funkcja, której kompilator nie może odczytać definicji, i jest przekazywana wynikowi funkcji malloc: funkcja może przechowywać gdzieś wskaźnik, a następnie pomijać wolny przez 'longjmp' (C, zwykle) lub wyjątek (C++). Podejrzewam, mając to na uwadze, że transformacja jest mniej przydatna, niż sobie wyobrażasz. – hvd

Odpowiedz

2

Technicznie, kompilatory mogą zoptymalizować niczego dopóki śledzić Jak-IF zasada.
Optymalizacja alokacji sterty do alokacji stosów byłaby możliwa, ale aby kompilator musiał być wystarczająco inteligentny, aby zbadać użycie i ustalić, że zmiana przypisania do stosu nie wpłynie na obserwowalne zachowanie programu.

Nie jestem świadomy żadnego kompilatora, który to robi.

10

Ogólnie rzecz biorąc, żaden kompilator nie wykonuje tej optymalizacji. To dobrze, ponieważ to może być potencjalnie bardzo szkodliwe: należy pamiętać, że stos jest zwykle bardzo ograniczony. Jeśli kompilator zoptymalizowane malloc + free się z alloca, obserwowalny zachowanie kodu zmieni: dla niektórych wejść, to nie będzie katastrofy z malloc + free, ale to by z alloca (ponieważ przestrzeń stos został wyczerpany). Dlatego ta optymalizacja jest niebezpieczna (i niezgodna z prawem, ponieważ zmienia zachowanie obserwowalne), a kompilatory nawet nie próbują jej wykonywać.

To powiedziawszy, w niektórych bardzo szczególnych okolicznościach kompilator mógł go wykonać, ale nie ma kompilatora, o którym wiem.

Optymalizacja wykonywana przez LLVM i wymienione w the comments to inna rzecz, to tylko optymalizuje się malloc s, które są porównywane tylko na null, a następnie free d.

+0

W rzeczywistości, llvm 3.0 robi podobną optymalizację (pamięć mallokowa -> rejestracja), jeśli malloc i free są używane do przechowywania wartości skalarnych (podwójny w moim teście), ale nie zoptymalizował on przykładu z tablicą o wartości 100. – osgx

+0

@osgx: nadal nie jest to 'malloc' ->' alloca', jednak. – Fanael

+2

Twój argument zakłada, że ​​rozmiar stosu może zostać wyczerpany w sytuacjach, w których sukces odniesie malloc, co niekoniecznie jest prawdą.Te systemy mogą pozwolić na powiększanie stosu w miarę potrzeby lub, rzadziej, nie używają liniowego stosu w ogóle – hvd

7

Istnieje spora partia LLVM o nazwie poolalloc, która wykonuje tę optymalizację. Jest utrzymywany jako część SAFECode i nie znajduje się w głównej dystrybucji LLVM.

Jest to opisane w dokumencie thesis i this PLDI. Kod to here.

Powiązane problemy