• Aucun résultat trouvé

3.2 Contexte scientifique

3.2.3 L’ex´ ecution symbolique

3.2.3.6 Autres optimisations

L’ex´ecution symbolique est souvent critiqu´ee en raison de la complexit´e `a r´e- soudre certaines contraintes ainsi que la complexit´e combinatoire qu’implique l’ex- ploration des chemins. C’est pourquoi beaucoup de travaux portent sur la mise en place d’optimisations permettant de r´eduire ces complexit´es.

Optimisations sur les expressions : Klee [26] et EXE [28] mettent en place

plusieurs optimisations telles que Expression Rewriting qui consiste `a transformer des formes d’expressions connues par leur ´equivalence allant des simples trans- formations (ex. x + 0 = x), `a des simplifications permettant de r´eduire la com- plexit´e de l’expression lors de son traitement par le solveur de contraintes (ex. x∗ 2n = x << n) ou encore des simplifications lin´eaires (ex. 2∗ x − x = x).

Klee [26] met ´egalement en place une optimisation appel´ee Constraint Set Simpli- fication qui consiste `a simplifier le pr´edicat de chemin au fur et `a mesure qu’une contrainte y est rajout´ee. Naturellement les contraintes sur les mˆemes variables ont tendance `a devenir plus sp´ecifiques au cours de l’ex´ecution. Par exemple, quand une contrainte telle que x < 10 est ajout´ee au pr´edicat de chemin, suivie ult´erieurement

d’une contrainte d’´egalit´e telle que x = 5, Klee r´e´ecrit le pr´edicat de chemin en ´eliminant la premi`ere contrainte ajout´ee car celle-ci peut ˆetre simplifi´ee par true. On peut ´egalement y trouver l’optimisation Constraint Independence qui consiste `

a d´eterminer les d´ependances d’une requˆete dans un ensemble de contraintes. Par exemple, prenons l’ensemble de contraintes suivant : {i < j, j < 20, k > 0}. L’op- timisation permet de savoir que pour une requˆete telle que i = 20, seules les deux premi`eres contraintes de cet ensemble sont n´ecessaires. On peut ´egalement y trou- ver l’optimisation Constraint Caching qui consiste `a mettre en cache les requˆetes ainsi que leur r´esultat afin d’´eviter, dans la mesure du possible, les appels au solveur de contraintes. Par exemple, le m´ecanisme de cache dans EXE [28] est d´eport´e sur un serveur distant. Chaque entr´ee dans le serveur est sous la forme hhash, resulti o`u hash repr´esente le hache M D4 de la repr´esentation syntaxique de la requˆete et result la r´eponse du solveur de contraintes (un mod`ele satisfaisant la contrainte, unsat ou unknown). Avant d’appeler le solveur de contraintes pour une requˆete q, EXE v´erifie si la r´eponse est disponible en cache sur le serveur, si c’est le cas, le r´esultat est renvoy´e depuis le m´ecanisme de cache. Dans le cas contraire, une requˆete est effectu´ee au solveur de contraintes et le r´esultat est mis en cache. Un syst`eme de cache au niveau des formules est facile `a faire mais peu utile (rares sont les mˆemes formules rejou´ees plusieurs fois), c’est pourquoi Klee [26] met en place un m´ecanisme de cache qui prend en compte les sous-formules ainsi que les sur-formules, ce qui demande une construction des pr´edicats de chemins et une repr´esentation des formules d´edi´ees.

Il existe ´egalement des optimisations pour les lectures et ´ecritures m´emoire tels que FAS (Fast Array Simplification) [43] appliqu´ee en pr´e-processeur `a une formule SMT. FAS propose une nouvelle repr´esentation des tableaux sous la forme d’une liste de maps afin d’assurer le passage `a l’´echelle lors des lectures et ´ecritures m´emoire.

La th`ese de Robin David [33] donne ´egalement un tr`es bon aper¸cu de ces optimisations.

Optimisations sur les chemins : Les outils d’exploration de chemins ont

montr´e leur efficacit´e `a d´ecouvrir de nouveaux chemins, mais le probl`eme auquel ils sont confront´es est de savoir comment g´erer efficacement le nombre exponentiel de chemins d´ecouverts. Boonstoppel et al. [23] pr´esentent une technique permettant de r´eduire le nombre de chemins `a explorer en supprimant ceux qui doivent avoir des effets de bord identiques `a certains chemins explor´es pr´ec´edemment.

liques issus de diff´erents chemins, il est possible de r´eduire le nombre d’´etats `a explorer dans un programme. `A premi`ere vue, cela augmenterait la complexit´e des contraintes. Cependant, ils proposent deux nouvelles m´ethodes permettant de d´eterminer automatiquement quand et comment fusionner des ´etats symboliques afin d’am´eliorer consid´erablement les performances de l’ex´ecution symbolique. La premi`ere m´ethode query count estimation, qui permet d’estimer l’impact de chaque variable symbolique sur les performances du solveur de contraintes – les ´etats sont fusionn´es que si les performances promettent d’ˆetre avantageuses. Ainsi que la deuxi`eme m´ethode dynamic state merging, permettant la fusion d’´etats symbo- liques en interagissant favorablement avec les strat´egies de couverture de chemins. Godefroid [46] introduit ´egalement les r´esum´es symboliques de fonctions con- nues. Un r´esum´e de fonction est une formule logique exprim´ee avec les pr´e-conditions des entr´ees et les post-conditions des sorties de la fonction. Le r´esum´e est ensuite utilis´e d`es lors que la fonction cibl´ee est appel´ee ce qui ´evite de devoir construire sa repr´esentation symbolique `a chaque appel de cette derni`ere.

Lors de l’exploration de chemins, Bardin et al. [17] pr´esentent une heuristique permettant d’´eliminer autant que possible les chemins non pertinents. L’heuris- tique Look-Ahead, qui consiste `a effectuer une analyse d’accessibilit´e (en termes d’´el´ements accessibles dans le CFG) pour d´ecider si le chemin actuel doit ˆetre ´etendu ou non.

Documents relatifs