Skip to content
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

Loop Unrolling for the first exp.unrolling-factor Iterations #563

Merged
merged 26 commits into from
Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
acb0b7e
loop unrolling option implemented
mikcp Jan 21, 2022
44def90
Merge branch 'master' into unrolling
mikcp Jan 21, 2022
84d94f2
Comment explaining reason behind replicated stmts
mikcp Jan 25, 2022
7456571
add_label_to_remainder_loop does not remove previous labels of st_loo…
mikcp Jan 25, 2022
29bc829
is_remainder_loop recurses all labels of the stmt
mikcp Jan 25, 2022
26b97ab
redundant check removed
mikcp Jan 25, 2022
e37c29d
by calling the unrolling visitor after preparedCFG, breaks and contin…
mikcp Jan 25, 2022
8a7fc15
basic tests added
mikcp Jan 26, 2022
bdbb726
test to add continue support failed
mikcp Jan 28, 2022
6643236
support for continue instructions added
mikcp Jan 31, 2022
db5da87
Revert "by calling the unrolling visitor after preparedCFG, breaks an…
mikcp Jan 31, 2022
b6f3fd7
Merge branch 'old-version-unrolling' into unrolling
mikcp Jan 31, 2022
99b382e
extra tests deleted
mikcp Jan 31, 2022
5e03d86
Merge branch 'master' into unrolling
michael-schwarz Feb 16, 2022
62a161d
Merge branch 'master' into unrolling
michael-schwarz Mar 12, 2022
72fab58
Add failing example
michael-schwarz Mar 12, 2022
bf5a3fa
Some clenaup
michael-schwarz Mar 12, 2022
10f7e8c
fix example
michael-schwarz Mar 12, 2022
930fae8
Alternative loop unrolling
michael-schwarz Mar 12, 2022
ac9ed15
fix comments
michael-schwarz Mar 12, 2022
4975cf1
fix comments
michael-schwarz Mar 12, 2022
44b162f
add failing test
michael-schwarz Mar 14, 2022
29b1714
One last(?) rewrite
michael-schwarz Mar 14, 2022
cdc512c
typo
michael-schwarz Mar 14, 2022
3acce11
Make Hashtable for patching gotos less fragile
michael-schwarz Mar 15, 2022
3f6e3b8
add test with unrolled array
michael-schwarz Mar 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion goblint.opam
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ dev-repo: "git+https://github.com/goblint/analyzer.git"
# on `dune build` goblint.opam will be generated from goblint.opam.template and dune-project
# also remember to generate/adjust goblint.opam.locked!
pin-depends: [
[ "goblint-cil.1.8.2" "git+https://github.com/goblint/cil.git#b77c663690519be8a672f871a036df3d89b677d5" ]
[ "goblint-cil.1.8.2" "git+https://github.com/goblint/cil.git#52161cdedf012e9328e516d83e38f7fcdc0534dc" ]
# TODO: add back after release, only pinned for optimization (https://github.com/ocaml-ppx/ppx_deriving/pull/252)
[ "ppx_deriving.5.2.1" "git+https://github.com/ocaml-ppx/ppx_deriving.git#0a89b619f94cbbfc3b0fb3255ab4fe5bc77d32d6" ]
# quoter workaround reverted for release, so no pin needed
Expand Down
2 changes: 1 addition & 1 deletion goblint.opam.locked
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ version: "dev"
pin-depends: [
[
"goblint-cil.1.8.2"
"git+https://github.com/goblint/cil.git#b77c663690519be8a672f871a036df3d89b677d5"
"git+https://github.com/goblint/cil.git#52161cdedf012e9328e516d83e38f7fcdc0534dc"
]
[
"apron.v0.9.13"
Expand Down
2 changes: 1 addition & 1 deletion goblint.opam.template
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# on `dune build` goblint.opam will be generated from goblint.opam.template and dune-project
# also remember to generate/adjust goblint.opam.locked!
pin-depends: [
[ "goblint-cil.1.8.2" "git+https://github.com/goblint/cil.git#b77c663690519be8a672f871a036df3d89b677d5" ]
[ "goblint-cil.1.8.2" "git+https://github.com/goblint/cil.git#52161cdedf012e9328e516d83e38f7fcdc0534dc" ]
# TODO: add back after release, only pinned for optimization (https://github.com/ocaml-ppx/ppx_deriving/pull/252)
[ "ppx_deriving.5.2.1" "git+https://github.com/ocaml-ppx/ppx_deriving.git#0a89b619f94cbbfc3b0fb3255ab4fe5bc77d32d6" ]
# quoter workaround reverted for release, so no pin needed
Expand Down
77 changes: 71 additions & 6 deletions src/util/cilfacade.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,62 @@ let end_basic_blocks f =
let thisVisitor = new allBBVisitor in
visitCilFileSameGlobals thisVisitor f

class loopUnrollingVisitor = object
inherit nopCilVisitor
method! vstmt s =
(* All the duplicated stmts need to be re-created or the sid will fail, so we create a copy of st, which is *)
(* physically unequal to it. *)
(* A new sid is computed later (as seen in http://goblint.in.tum.de/assets/goblint-cil/api/Cil.html#TYPEstmt), *)
(* as long as we perform this copies. *)
let newsid st = { st with sid = st.sid } in
sim642 marked this conversation as resolved.
Show resolved Hide resolved
let rec newsid_stmt st =
let mkb stml = mkBlock (List.map newsid_stmt stml) in
match st.skind with
| Instr _ -> newsid st
| If(e,b1,b2,l1,l2) -> mkStmt(If(e,(mkb b1.bstmts),(mkb b2.bstmts),l1,l2))
| Loop(bl,l1,l2,s1,s2) ->
let create_stmt = mkStmt(Loop((mkb bl.bstmts),l1,l2,s1,s2)) in
create_stmt.labels <- st.labels;
create_stmt
| Block(bl) -> mkStmt(Block(mkb bl.bstmts))
| Switch(e,bl,stl,l1,l2) -> mkStmt(Switch(e,(mkb bl.bstmts),(List.map newsid_stmt stl),l1,l2))
| _ -> newsid st in
let mkBlock' b = mkBlock (List.map newsid_stmt b) in
let mk_stmt_from_stmt_list bl = mkStmt(Block(mkBlock' bl)) in
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
match s.skind with
| Loop(b, loc, _, _, _) ->
let get_unrolling_factor = GobConfig.get_int "exp.unrolling-factor" in
(* All unrollings will leave the original loop at the end. The label makes sure it's not unrolled twice.*)
let add_label_to_remainder_loop st_loop loc_loop =
st_loop.labels <- (Label(Cil.freshLabel "remainder_loop", loc_loop, false))::st_loop.labels;
st_loop in
let rec is_remainder_loop loop_stmt_labels =
match loop_stmt_labels with
| [] -> false
| Label(lab,_,_)::tl ->
if BatString.starts_with lab "remainder_loop" then true else is_remainder_loop tl
| _ -> false in
(* Unrolling *)
let rec unroll sl factor =
match factor with
|0-> sl
|_ ->
let x = b.bstmts @ sl in
unroll x (factor-1) in
let check_type_loop =
let is_loop_unrollable s =
if is_remainder_loop s.labels then false
else true in
let unroll_helper st = mk_stmt_from_stmt_list (unroll [(add_label_to_remainder_loop st loc)] get_unrolling_factor) in
if is_loop_unrollable s then ChangeDoChildrenPost ((unroll_helper s), fun x -> x)
else DoChildren in
check_type_loop
| _ -> DoChildren
end

let loop_unrolling f =
let thisVisitor = new loopUnrollingVisitor in
visitCilFileSameGlobals thisVisitor f

let visitors = ref []
let register_preprocess name visitor_fun =
Expand Down Expand Up @@ -107,12 +163,21 @@ let createCFG (fileAST: file) =
* See https://github.com/goblint/cil/issues/31#issuecomment-824939793. *)

iterGlobals fileAST (fun glob ->
match glob with
| GFun(fd,_) ->
prepareCFG fd;
computeCFGInfo fd true
| _ -> ()
);
match glob with
| GFun(fd,_) ->
prepareCFG fd;
| _ -> ()
);
(* The unrolling needs to take place between prepareCFG and computeCFGInfo, since prepareCFG handles the breaks *)
(* and continues, which allow us to replicate the loop's body outside of the loop. computeCFG info creates the CFG, *)
(* so it needs to happen before that. *)
if (get_int "exp.unrolling-factor")>0 then loop_unrolling fileAST;
iterGlobals fileAST (fun glob ->
match glob with
| GFun(fd,_) ->
computeCFGInfo fd true
| _ -> ()
);
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
do_preprocess fileAST

let getAST fileName =
Expand Down
7 changes: 7 additions & 0 deletions src/util/options.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,13 @@
"Path to C preprocessor (cpp) to use. If empty, then automatically searched.",
"type": "string",
"default": ""
},
"unrolling-factor": {
"title": "exp.unrolling-factor",
"description":
"Sets the unrolling factor for the loopUnrollingVisitor.",
"type": "integer",
"default": 0
}
},
"additionalProperties": false
Expand Down