aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Fasse <justus.fasse@etu.univ-grenoble-alpes.fr>2021-07-15 09:57:52 +0200
committerJustus Fasse <justus.fasse@etu.univ-grenoble-alpes.fr>2021-07-15 09:57:52 +0200
commit4d56e04147c59abcca0542e7cc69e76647d6002b (patch)
tree4f97b05ee93978485517ce0caf7d3597a52b84ab
parent931e10341d58840b5747ec607cdac72444cde0b2 (diff)
downloadcompcert-kvx-4d56e04147c59abcca0542e7cc69e76647d6002b.tar.gz
compcert-kvx-4d56e04147c59abcca0542e7cc69e76647d6002b.zip
Optimize code layout
When detecting a superblock that spans a loop, lay out the code in such a way that not looping can be handled via fall-through, thus saving an extra instruction on the suspected hot-path.
-rw-r--r--backend/Linearizeaux.ml19
1 files changed, 14 insertions, 5 deletions
diff --git a/backend/Linearizeaux.ml b/backend/Linearizeaux.ml
index 5914f6a3..e89db024 100644
--- a/backend/Linearizeaux.ml
+++ b/backend/Linearizeaux.ml
@@ -113,7 +113,7 @@ let flatten_blocks blks =
let cmp_minpc (mpc1, _) (mpc2, _) =
if mpc1 = mpc2 then 0 else if mpc1 > mpc2 then -1 else 1
in
- List.flatten (List.map snd (List.sort cmp_minpc blks))
+ List.flatten (List.map snd (List.stable_sort cmp_minpc (List.rev blks)))
(* Build the enumeration *)
@@ -139,11 +139,16 @@ let super_blocks f joins =
pc is the function entry point
or a join point
or the successor of a conditional test *)
- let rec start_block pc =
+ let rec start_block ?minpc pc =
+ let minpc =
+ match minpc with
+ | None -> pc
+ | Some minpc -> minpc
+ in
let npc = P.to_int pc in
if not (IntSet.mem npc !visited) then begin
visited := IntSet.add npc !visited;
- in_block [] npc pc
+ in_block [] (P.to_int minpc) pc
end
(* in_block: add pc to block and check successors *)
and in_block blk minpc pc =
@@ -159,10 +164,14 @@ let super_blocks f joins =
match pred with
| None -> (end_block blk minpc; start_block ifso; start_block ifnot)
| Some true -> (next_in_block blk minpc ifso; start_block ifnot)
- | Some false -> (next_in_block blk minpc ifnot; start_block ifso)
+ | Some false ->
+ if List.mem ifnot blk then
+ (next_in_block blk minpc ifnot; start_block ~minpc:ifnot ifso)
+ else
+ (next_in_block blk minpc ifnot; start_block ifso)
end
| Ljumptable(arg, tbl) :: _ ->
- end_block blk minpc; List.iter start_block tbl
+ end_block blk minpc; List.iter (start_block ?minpc:None) tbl
| Lreturn :: _ -> end_block blk minpc
| instr :: b' -> do_instr_list b' in
do_instr_list b