-
Notifications
You must be signed in to change notification settings - Fork 84
Autotuning of Configuration #772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
543b954
autoselect beginning, new wideningThresholds
leunam99 9718bfe
Merge branch 'master' of https://github.com/leunam99/analyzer
leunam99 dea75d7
Added Analysis Focus
leunam99 9b39f58
Use LibraryFunction for detecting ThreadCreation
leunam99 011cd17
revert personal changes
leunam99 1c41250
Suggested Changes for Pull request
leunam99 71e65ca
Added selective loop unrolling
leunam99 508efb9
Enum detection
leunam99 60e58d4
Added Collection of factors to predict complexity
leunam99 b9112e4
New loop unrolling heuristic: detect dimple loops with fixed iteratio…
leunam99 5576e21
Enable different tuning options
leunam99 bab6914
Array domain can individually be configured
leunam99 9b95b6c
support for choosing options based on estimates
leunam99 5c91440
Indentation fixes, uncomment loopunrolling
leunam99 fbef34b
project arrays to different domains when calling functions
leunam99 ac1097b
activate loopunrolling correctly
leunam99 050225d
array domain can actually project arguments
leunam99 c926829
Changed options
leunam99 d775b43
regression tests, small fixes
leunam99 8b2bd2c
changed widening thresholds because of logic error, different apron e…
leunam99 b1169c1
Merge branch 'arrayUnrollingOverflow'
leunam99 b68eea7
copy attributes in apron analysis
leunam99 6ae9bbe
fixed bug with precision annotations and wrong comment
leunam99 9daab61
Cleaanup
leunam99 9d717d2
Indentation
leunam99 b869202
Merge branch 'master' into autotune
michael-schwarz 1a2190c
Fix indentation in changed files
michael-schwarz d350ccd
54/{03,04}: Add erroneously deleted tests back
michael-schwarz 58ffe2d
Delete mistaken stuff
michael-schwarz c769b28
Rm erroneously commited files
michael-schwarz 4e21fe2
Restructuring
michael-schwarz c3e66fb
Cleanup
michael-schwarz 3b7b825
Fix names
michael-schwarz c6cc2dd
Cleanup wideningThresholds.ml
michael-schwarz 627c982
Typos in options scheme
michael-schwarz c102005
Minimize changes to array domain
michael-schwarz 5ad7a14
Cleanup indentation
michael-schwarz ff6662b
Changed attribute option names
leunam99 fbd888c
Moved loop unrolling to it's own file
leunam99 aeee3d8
Dokumentaton
leunam99 07d1aff
More small fixes
leunam99 423631c
Merge branch 'master' into autotune
michael-schwarz e247378
Merge branch 'master' of github.com:leunam99/analyzer into autotune
michael-schwarz b6b7cde
Remove polymorphic hash table
michael-schwarz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| open GobConfig;; | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| open Cil;; | ||
|
|
||
| (*Create maps that map each function to the ones called in it and the ones calling it*) | ||
| (* TODO rewrite with Syntacticsearch?: https://github.com/goblint/cil/blob/develop/src/ext/syntacticsearch/funcFunction.ml | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Problems: No access to Storage variable to determine if fuction is extern | ||
| No direct way to map uses to function it is called from | ||
| No included filtering of duplicate functions? | ||
| let calledFunctionsQuery = { | ||
| sel = [Name_sel, ID_sel]; (*Can we get the storage directly? *) | ||
| k = Fun_k; | ||
| tar = All_t; | ||
| f = Uses_f; (*Does this select only function calls without Parameters? *) | ||
| str = None_s; (* Only search in the specific function*) | ||
| } | ||
| *) | ||
|
|
||
| module Varinfo = struct | ||
| type t = varinfo | ||
| let compare v1 v2 = Stdlib.compare v1.vid v2.vid | ||
| end;; | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| module FunctionSet = Set.Make(Varinfo);; | ||
| module FunctionCallMap = Map.Make(Varinfo);; | ||
|
|
||
| let addOrCreateMap fd = function | ||
| | Some set -> Some (FunctionSet.add fd set) | ||
| | None -> Some (FunctionSet.singleton fd) ;; | ||
|
|
||
| class collectFunctionCallsVisitor(callSet, calledBy, argLists, fd) = object | ||
| inherit nopCilVisitor | ||
|
|
||
| method! vinst = function | ||
| | Call (_,Lval ((Var info), NoOffset),args,_,_) as call-> | ||
| (*ignore @@ Pretty.fprint stdout 50 (printInstr defaultCilPrinter () call) ;*) | ||
| callSet := FunctionSet.add info !callSet; | ||
| calledBy := FunctionCallMap.update info (addOrCreateMap fd) !calledBy; | ||
| (*We collect the argument list so we can use LibraryFunctions.find to classify functions*) | ||
| argLists := FunctionCallMap.add info args !argLists; | ||
| (*print_endline @@ fd.vname ^ " -> " ^ info.vname; | ||
| Pretty.fprint stdout (Pretty.d_list "\n" (fun () e -> printExp defaultCilPrinter () e) () args) ~width:50; | ||
| print_endline "\n";*) | ||
| DoChildren | ||
| | _ -> DoChildren | ||
| end;; | ||
|
|
||
| class functionVisitor(calling, calledBy, argLists) = object | ||
| inherit nopCilVisitor | ||
|
|
||
| method! vfunc fd = | ||
| let callSet = ref FunctionSet.empty in | ||
| let callVisitor = new collectFunctionCallsVisitor (callSet, calledBy, argLists, fd.svar) in | ||
| ignore @@ Cil.visitCilFunction callVisitor fd; | ||
| calling := FunctionCallMap.add fd.svar !callSet !calling; | ||
| (*print_endline fd.svar.vname; | ||
| ignore (dumpGlobal plainCilPrinter stdout (GFun (fd, !currentLoc)));*) | ||
| SkipChildren | ||
| end;; | ||
|
|
||
| let functionCallMaps = ResettableLazy.from_fun (fun () -> | ||
| let calling = ref FunctionCallMap.empty in | ||
| let calledBy = ref FunctionCallMap.empty in | ||
| let argLists = ref FunctionCallMap.empty in | ||
| let thisVisitor = new functionVisitor(calling,calledBy, argLists) in | ||
| visitCilFileSameGlobals thisVisitor (!Cilfacade.current_file); | ||
| !calling, !calledBy, !argLists);; | ||
|
|
||
| (*TODO Extend to dynamic calls?*) | ||
| let calledFunctions fd = ResettableLazy.force functionCallMaps |> fun (x,_,_) -> x |> FunctionCallMap.find_opt fd |> Option.value ~default:FunctionSet.empty;; | ||
| let callingFunctions fd = ResettableLazy.force functionCallMaps |> fun (_,x,_) -> x |> FunctionCallMap.find_opt fd |> Option.value ~default:FunctionSet.empty;; | ||
| let functionArgs fd = ResettableLazy.force functionCallMaps |> fun (_,_,x) -> x |> FunctionCallMap.find_opt fd;; | ||
|
|
||
| (*Functions for determining if the Congruence analysis should be enabled *) | ||
| let isNotExtern = function | ||
| | Extern -> false | ||
| | _ -> true;; | ||
|
|
||
| let rec setCongruenceRecursive fd depth neigbourFunction = | ||
| if depth >= 0 then ( | ||
| fd.svar.vattr <- addAttributes (fd.svar.vattr) [Attr ("goblint_precision",[AStr "congruence"])]; | ||
| FunctionSet.iter | ||
| (fun vinfo -> | ||
| print_endline (" " ^ vinfo.vname); | ||
| setCongruenceRecursive (Cilfacade.find_varinfo_fundec vinfo) (depth -1) neigbourFunction | ||
| ) | ||
| (FunctionSet.filter | ||
| (fun x -> isNotExtern x.vstorage) | ||
| (neigbourFunction fd.svar) | ||
| ) | ||
| ; | ||
| );; | ||
|
|
||
| (*Because we now ignore the total count and only care if it exists, this should be rewritten to stop after the first mod*) | ||
| (* -> No longer a visitor, but a recursive search?*) | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| class modCountVisitor(count) = object | ||
| inherit nopCilVisitor | ||
|
|
||
| method! vexpr = function | ||
| | BinOp (Mod,_,_,_) -> | ||
| count := 1 + !count; | ||
| DoChildren | ||
| | _ -> DoChildren | ||
| end;; | ||
|
|
||
| class modFunctionAnnotatorVisitor = object | ||
| inherit nopCilVisitor | ||
|
|
||
| method! vfunc fd = | ||
| let count = ref 0 in | ||
| let thisVisitor = new modCountVisitor(count) in | ||
| ignore (visitCilFunction thisVisitor fd); | ||
| if !count > 0 then ( | ||
| print_endline ("function " ^ (CilType.Fundec.show fd) ^" uses mod, enable Congruence recursively for:"); | ||
| print_endline (" \"down\":"); | ||
| setCongruenceRecursive fd 6 calledFunctions; (* depth? don't do it repeatedly for same function?*) | ||
| print_endline (" \"up\":"); | ||
| setCongruenceRecursive fd 3 callingFunctions; | ||
| (*ignore (dumpGlobal plainCilPrinter stdout (GFun (fd, !currentLoc)))*) | ||
| ); | ||
| SkipChildren | ||
| end;; | ||
|
|
||
| let addModAttributes file = | ||
| let thisVisitor = new modFunctionAnnotatorVisitor in | ||
| ignore (visitCilFileSameGlobals thisVisitor file);; | ||
| (*TODO: Overflow analysis has to be enabled/assumed to not occur, else there are problems?*) | ||
|
|
||
| let disableIntervalContextsInRecursiveFunctions () = | ||
| ResettableLazy.force functionCallMaps |> fun (x,_,_) -> x |> FunctionCallMap.iter (fun f set -> | ||
| (*detect direct recursion and recursion with one indirection*) | ||
| if FunctionSet.mem f set || (not @@ FunctionSet.disjoint (calledFunctions f) (callingFunctions f)) then ( | ||
| print_endline ("function " ^ (f.vname) ^" is recursive, disable interval analysis"); | ||
| f.vattr <- addAttributes (f.vattr) [Attr ("goblint_context",[AStr "base.no-interval"])]; | ||
| ) | ||
| );; | ||
|
|
||
| (*If only one Thread is used in the program, we can disable most thread analyses*) | ||
| (*The exceptions are analyses that are depended on by others: base -> mutex -> mutexEvents, access*) | ||
| (*TODO escape is also still enabled, because I do not know if the analysis gets more imprecise if not*) | ||
|
|
||
| let toJsonArray list = "[\"" ^ (String.concat "\",\"" list) ^ "\"]";; | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let notNeccessaryThreadAnalyses = ["deadlock"; "maylocks"; "symb_locks"; "thread"; "threadflag"; "threadid"; "threadJoins"; "threadreturn"];; | ||
|
|
||
| let reduceThreadAnalyses () = | ||
| (*TODO also consider dynamic calls!?*) | ||
| let hasThreadCreate () = | ||
| ResettableLazy.force functionCallMaps | ||
| |> fun (_,x,_) -> x (*every function that is called*) | ||
| |> FunctionCallMap.exists | ||
| (fun var callers -> | ||
| let desc = LibraryFunctions.find var in | ||
| match (functionArgs var) with | ||
| | None -> false; | ||
| | Some args -> | ||
| match desc.special args with | ||
| | ThreadCreate _ -> | ||
| print_endline @@ "thread created in " ^ var.vname ^ ", called by:"; | ||
| FunctionSet.iter ( fun c -> print_endline @@ " " ^ c.vname) callers; | ||
| true; | ||
| | _ -> false; | ||
| ) | ||
| in | ||
|
|
||
| (*TODO is there a way to specify only the thread analyses to keep? *) | ||
| if not @@ hasThreadCreate () then ( | ||
| print_endline @@ "no thread creation -> disabeling thread analyses \"" ^ (String.concat ", " notNeccessaryThreadAnalyses) ^ "\""; | ||
| get_string_list "ana.activated" | ||
| |> List.filter (fun l -> not (List.mem l notNeccessaryThreadAnalyses)) | ||
| |> toJsonArray | ||
| |> set_auto "ana.activated" | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ) | ||
| ;; | ||
|
|
||
| let focusOnSpecification () = | ||
| match Svcomp.Specification.of_option () with | ||
| | UnreachCall s -> () (*TODO?*) | ||
| | NoDataRace -> (*enable all thread analyses*) | ||
| print_endline @@ "Specification: NoDataRace -> enabeling thread analyses \"" ^ (String.concat ", " notNeccessaryThreadAnalyses) ^ "\""; | ||
| get_string_list "ana.activated" | ||
| |> List.filter (fun l -> not (List.mem l notNeccessaryThreadAnalyses)) (*remove duplicates*) | ||
| |> (@) notNeccessaryThreadAnalyses | ||
| |> toJsonArray | ||
| |> set_auto "ana.activated"; | ||
| | NoOverflow -> (*We focus on integer analysis*) | ||
| set_bool "ana.int.def_exc" true; | ||
| set_bool "ana.int.enums" true; | ||
| set_bool "ana.int.interval" true;; | ||
michael-schwarz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| (*TODO: does calling this at a late point cause any problems?*) | ||
| (* do not overwrite explicit settings?*) | ||
| (* how to better display changed/selected settings?*) | ||
| let chooseConfig file = | ||
| set_bool "annotation.int.enabled" true; | ||
| addModAttributes file; | ||
| set_bool "ana.int.interval_threshold_widening" true; (*Do not do this all the time?*) | ||
|
|
||
| disableIntervalContextsInRecursiveFunctions (); | ||
|
|
||
| (*crashes because sometimes bigints are needed | ||
| print_endline @@ "Upper thresholds: " ^ String.concat " " @@ List.map (fun z -> string_of_int (Z.to_int z)) @@ WideningThresholds.upper_thresholds (); | ||
| print_endline @@ "Lower thresholds: " ^ String.concat " " @@ List.map (fun z -> string_of_int (Z.to_int z)) @@ WideningThresholds.lower_thresholds ();*) | ||
| if get_string "ana.specification" <> "" then focusOnSpecification (); | ||
| reduceThreadAnalyses (); | ||
| ;; | ||
|
|
||
| let reset_lazy () = ResettableLazy.reset functionCallMaps;; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.