2012-04-28 6 views
12

C'è qualche maturare C/C++, in grado di ottimizzare malloc/free (o new/delete) coppie di informazioni alloca? In altre parole, convertire da memoria basata su heap a stack (SOLO per alcuni casi limitati).Will compilatore ottimizzare malloc/liberi o nuova/delete coppia in alloca

Questa ottimizzazione può essere consentita solo per coppia di malloc/free quando entrambe le funzioni sono nella stessa funzione (o anche nello stesso blocco di {}) e viene chiamata ogni volta che viene chiamato malloc. Inoltre, consideriamo che il puntatore alla memoria malloced non viene salvato in alcune variabili globali.

Quindi, sarà GCC/LLVM + clang/Intel Compiler convertire tale blocco di codice:

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

in

{ 
    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) 
} 

Questa conversione potrebbe non essere molto utile per ogni programma, ma penso , potrebbe esserci qualche opzione speciale per il compilatore.

PS (Update1) Siamo in grado di limitare la nostra discussione solo per i casi in cui compilatore sa che malloc e libero è da libc (stdlib)

+1

Anno fa un uomo in lista llvm [ha detto no] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/032971.html) e altro uomo [ha detto di sì] (http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033015.html) e punta a [codice effettivo] (http: //lists.cs.uiuc.edu/pipermail/llvmdev/2010-July/033017.html) – osgx

+3

Penso che malloc non sia un elemento intrinseco. Ed è piuttosto pericoloso farlo, dal momento che il compilatore non ha informazioni sulla dimensione dello stack in fase di esecuzione. – BlueWanderer

+0

La trasformazione non è sicura se viene chiamata qualsiasi altra funzione di cui il compilatore non può vedere la definizione e viene passato il risultato di malloc: la funzione potrebbe memorizzare il puntatore da qualche parte e quindi saltare il file libero da "longjmp' (C, di solito) o un eccezione (C++). Sospetto, tenendo presente ciò, che la trasformazione sia meno frequente di quanto immagini. – hvd

risposta

2

Tecnicamente, i compilatori possono ottimizzare qualsiasi cosa purché essi seguono il come-se regola.
Quindi, è possibile ottimizzare le allocazioni dell'heap per allocare le allocazioni, ma è necessario che il compilatore sia abbastanza intelligente da sondare l'utilizzo e determinare che la modifica dell'assegnazione allo stack non influirà sul comportamento osservabile del programma.

Non sono a conoscenza di alcun compilatore che esegue questa operazione.

10

In generale, nessun compilatore esegue questa ottimizzazione. Va bene, perché questa cosa può essere potenzialmente molto dannosa: tieni presente che lo stack di solito è molto limitato nelle sue dimensioni. Se un compilatore ottimizzato malloc + free in un alloca, il comportamento osservabile del codice cambierebbe: per alcuni input, non sarebbe in crash con malloc + free, ma sarebbe con alloca (perché lo spazio di stack ottenuto esaurito). Pertanto, questa ottimizzazione non è sicura (e illegale secondo lo standard, poiché modifica il comportamento osservabile) e i compilatori non tentano nemmeno di eseguirlo.

Detto questo, in alcune circostanze molto specifiche, un compilatore potrebbe eseguirlo, ma nessun compilatore ne sono a conoscenza.

L'ottimizzazione eseguita da LLVM e menzionato in the comments è una cosa diversa, ottimizza solo malloc s che vengono confrontati solo a null e quindi free d.

+0

In realtà, llvm 3.0 esegue un'ottimizzazione simile (memoria malloced -> registro), se malloc e free vengono utilizzati per la memorizzazione di valori scalari (double nel mio test), ma non ha ottimizzato l'esempio con 100 char array. – osgx

+0

@osgx: non è ancora 'malloc' ->' alloca', tuttavia. – Fanael

+2

Il tuo argomento presuppone che la dimensione dello stack possa essere esaurita in situazioni in cui malloc avrebbe avuto successo. Questo non è necessariamente vero. I sistemi possono consentire alle dimensioni dello stack di espandersi secondo necessità, o più raramente, non usano affatto uno stack lineare – hvd

7

È in corso l'off-shoot di LLVM denominato poolalloc che esegue questa ottimizzazione. Viene gestito come parte di SAFECode e non si trova nella distribuzione LLVM della linea principale.

E 'descritto nel documento Chris Lattner PhD thesis e nella carta PLDI this. Il codice è here.

Problemi correlati