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

compiler metrics #425

Merged
merged 72 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
c821320
remove extraneous Search command
pratapsingh1729 May 3, 2022
34513c0
add isReg to FlatImp semantics, other files still broken
pratapsingh1729 May 4, 2022
da28f4a
start fixing other files to add isReg, low-hanging fruit first
pratapsingh1729 May 4, 2022
143d485
fix FlatToRiscvFunctions.v, could be a little tidier though
pratapsingh1729 May 10, 2022
9720664
progress on RegAlloc.v, not done yet
pratapsingh1729 May 16, 2022
d157885
fixed but slow version of regalloc proof; TODO improve performance
pratapsingh1729 Jun 14, 2022
803a137
perf improvements for RegAlloc.v
pratapsingh1729 Jun 21, 2022
276bb7b
fix LowerPipeline.v
pratapsingh1729 Jul 12, 2022
db9c19b
start work on Spilling.v (#1)
pratapsingh1729 Jul 12, 2022
7779d35
Merge branch 'regalloc-metrics' of https://github.com/pratapsingh1729…
pratapsingh1729 Jul 12, 2022
6670dcd
finish Spilling pass except some admits relating to SInteract
pratapsingh1729 Jul 20, 2022
7d1d671
FlattenExpr pass with admits for metrics goals, because bedrock2 sema…
pratapsingh1729 Jul 20, 2022
67d485f
Merge branch 'master' into regalloc-metrics
pratapsingh1729 Jul 20, 2022
cdbdbc0
Merge branch 'regalloc-metrics' of https://github.com/pratapsingh1729…
pratapsingh1729 Jul 20, 2022
402f67f
cleaning up
pratapsingh1729 Jul 20, 2022
ca1bd2a
update submodules
pratapsingh1729 Jul 20, 2022
f8af06b
fix merge issues
pratapsingh1729 Jul 20, 2022
8329197
make compilerExamples/SoftmulCompile.v compatible with new FlatImp.ex…
pratapsingh1729 Jul 21, 2022
24eb5f5
work on spilling pass, current costs for call and interact don't work
pratapsingh1729 Aug 11, 2022
6bd3c05
cleaned up as much of the mess as i could for now
nathan-sheffield Oct 9, 2023
9a0f6fd
sorry to leave you with this andy
nathan-sheffield Oct 9, 2023
55d0f22
Recover ipow metrics proof
tckmn Jan 25, 2024
6c4b51f
extremely finnicky bugs in straightline
tckmn Apr 4, 2024
387f09c
fix bsearch proof
tckmn Apr 4, 2024
0fff400
simplify ipow metrics proof
tckmn Apr 4, 2024
6760654
Merge remote-tracking branch 'pratap/regalloc-metrics' into compilerm…
tckmn Apr 18, 2024
b16c3a6
fix cost_SOp
tckmn Apr 25, 2024
b433c2f
utility functions
tckmn Jun 7, 2024
bcd6714
Parametrize FlatImp.exec by compiler phase
tckmn Jun 10, 2024
68059d6
Incorporate metrics into compiler pipeline proofs
tckmn Jun 10, 2024
86a0f8a
Fix admits in RegAlloc step
tckmn Jun 10, 2024
568b87d
Move cost_SStackalloc into postcondition
tckmn Jun 10, 2024
56a2834
Fixed UseImmediate proof
tckmn Jun 10, 2024
6558c61
Merge remote-tracking branch 'origin/master' into compilermetrics
tckmn Jun 10, 2024
39ff02b
Incorporate metrics into DCE
tckmn Jun 11, 2024
5abef1c
Use alternative metrics statement style in pipeline
tckmn Jun 11, 2024
6484871
Finish metrics proof of lower pipeline
tckmn Jun 11, 2024
7cb7783
Finish metrics patches in pipeline
tckmn Jun 11, 2024
98f5ca2
Patch ToplevelLoop for metrics changes
tckmn Jun 11, 2024
2e3ada6
Factor out expr/stmt costs into MetricCosts.v
tckmn Jun 15, 2024
88c314d
MetricCosts migration: Spilling
tckmn Jun 15, 2024
33e328b
MetricCosts migration: RegAlloc
tckmn Jun 15, 2024
25004bf
MetricCosts migration: UseImmediate
tckmn Jun 15, 2024
5851d6d
MetricCosts migration: DeadCodeElim
tckmn Jun 15, 2024
a9d7747
MetricCosts migration: Pipeline (finished!)
tckmn Jun 15, 2024
681aead
fix MetricWeakestPrecondition and ...Properties
andres-erbsen Jun 21, 2024
5f48741
Merge pull request #1 from andres-erbsen/compilermetrics-mwpp
tckmn Jun 21, 2024
ab56647
Merge branch 'master' into compilermetrics
samuelgruetter Jun 22, 2024
e5ba50c
account for isReg in regalloc heuristic
pratapsingh1729 Jul 7, 2024
b389899
keep old code in a comment for easier diffing
pratapsingh1729 Jul 8, 2024
44380e0
add some simple tests for the new heuristic
pratapsingh1729 Jul 8, 2024
c4213c4
Revert "add some simple tests for the new heuristic"
pratapsingh1729 Jul 8, 2024
105c5ea
Revert "keep old code in a comment for easier diffing"
pratapsingh1729 Jul 8, 2024
2c29dce
Revert "account for isReg in regalloc heuristic"
pratapsingh1729 Jul 8, 2024
7d74179
fix ipow metrics proof
tckmn Jul 5, 2024
74337b8
additive style
tckmn Jul 10, 2024
63eeb7e
fix ipow again
tckmn Jul 10, 2024
ce31e90
loop/wp properties lemmas needed
tckmn Jul 10, 2024
496c5b7
very messy SPI wip
tckmn Jul 10, 2024
07eee80
clean up bits of PR
tckmn Jul 26, 2024
e4358eb
correct call/spilling costs
tckmn Jul 26, 2024
ae6c57b
naming and tactic improvements
tckmn Jul 26, 2024
56b462f
Merge remote-tracking branch 'origin/master' into compilermetrics
tckmn Jul 26, 2024
bdecbb9
fix qed slowness
tckmn Jul 26, 2024
3aad17e
clean up metrics examples to mergable state
tckmn Jul 31, 2024
9b9f221
remove unfinished loop lemmas
tckmn Aug 9, 2024
1d84825
slightly nicer cost_unfold
tckmn Aug 9, 2024
2970594
Merge remote-tracking branch 'origin/master' into compilermetrics
tckmn Aug 9, 2024
46e8ccc
oops forgot to delete this
tckmn Aug 9, 2024
b8b232e
update comments to reflect current code
tckmn Aug 9, 2024
5360013
Merge remote-tracking branch 'origin/master' into compilermetrics
tckmn Aug 16, 2024
070a202
restore loop lemmas with metrics adapted proofs
tckmn Aug 16, 2024
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
175 changes: 175 additions & 0 deletions bedrock2/src/bedrock2/MetricCosts.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
Require Import BinIntDef.
Require Import Coq.Strings.String.
Require Import bedrock2.MetricLogging.
From coqutil.Tactics Require Import destr.

Local Open Scope MetricH_scope.

Inductive compphase: Type :=
| PreSpill
| PostSpill.

Section FlatImpExec.

Context {varname: Type}.
Variable (phase: compphase).
Variable (isReg: varname -> bool).

Definition cost_interact mc :=
match phase with
| PreSpill => (addMetricInstructions 100 (addMetricJumps 100 (addMetricStores 100 (addMetricLoads 100 mc))))
| PostSpill => (addMetricInstructions 50 (addMetricJumps 50 (addMetricStores 50 (addMetricLoads 50 mc))))
end.

Definition cost_call_internal mc :=
match phase with
| PreSpill => addMetricInstructions 100 (addMetricJumps 100 (addMetricLoads 100 (addMetricStores 100 mc)))
| PostSpill => addMetricInstructions 50 (addMetricJumps 50 (addMetricLoads 50 (addMetricStores 50 mc)))
end.

Definition cost_call_external mc :=
match phase with
| PreSpill => addMetricInstructions 100 (addMetricJumps 100 (addMetricLoads 100 (addMetricStores 100 mc)))
| PostSpill => addMetricInstructions 50 (addMetricJumps 50 (addMetricLoads 50 (addMetricStores 50 mc)))
end.

(* TODO think about a non-fixed bound on the cost of function preamble and postamble *)

Definition cost_load x a mc :=
match (isReg x, isReg a) with
| (false, false) => (addMetricInstructions 3 (addMetricLoads 5 (addMetricStores 1 mc)))
| (false, true) => (addMetricInstructions 2 (addMetricLoads 3 (addMetricStores 1 mc)))
| ( true, false) => (addMetricInstructions 2 (addMetricLoads 4 mc))
| ( true, true) => (addMetricInstructions 1 (addMetricLoads 2 mc))
end.

Definition cost_store a v mc :=
match (isReg a, isReg v) with
| (false, false) => (addMetricInstructions 3 (addMetricLoads 5 (addMetricStores 1 mc)))
| (false, true) => (addMetricInstructions 2 (addMetricLoads 3 (addMetricStores 1 mc)))
| ( true, false) => (addMetricInstructions 2 (addMetricLoads 3 (addMetricStores 1 mc)))
| ( true, true) => (addMetricInstructions 1 (addMetricLoads 1 (addMetricStores 1 mc)))
end.

Definition cost_inlinetable x i mc :=
match (isReg x, isReg i) with
| (false, false) => (addMetricInstructions 5 (addMetricLoads 7 (addMetricStores 1 (addMetricJumps 1 mc))))
| (false, true) => (addMetricInstructions 4 (addMetricLoads 5 (addMetricStores 1 (addMetricJumps 1 mc))))
| ( true, false) => (addMetricInstructions 4 (addMetricLoads 6 (addMetricJumps 1 mc)))
| ( true, true) => (addMetricInstructions 3 (addMetricLoads 4 (addMetricJumps 1 mc)))
end.

Definition cost_stackalloc x mc :=
match isReg x with
| false => (addMetricInstructions 2 (addMetricLoads 2 (addMetricStores 1 mc)))
| true => (addMetricInstructions 1 (addMetricLoads 1 mc))
end.

Definition cost_lit x mc :=
match isReg x with
| false => (addMetricInstructions 9 (addMetricLoads 9 (addMetricStores 1 mc)))
| true => (addMetricInstructions 8 (addMetricLoads 8 mc))
end.

Definition cost_op x y z mc :=
match (isReg x, isReg y, isReg z) with
| (false, false, false) => (addMetricInstructions 5 (addMetricLoads 7 (addMetricStores 1 mc)))
| (false, false, true) | (false, true, false) => (addMetricInstructions 4 (addMetricLoads 5 (addMetricStores 1 mc)))
| (false, true, true) => (addMetricInstructions 3 (addMetricLoads 3 (addMetricStores 1 mc)))
| ( true, false, false) => (addMetricInstructions 4 (addMetricLoads 6 mc))
| ( true, false, true) | ( true, true, false) => (addMetricInstructions 3 (addMetricLoads 4 mc))
| ( true, true, true) => (addMetricInstructions 2 (addMetricLoads 2 mc))
end.

Definition cost_set x y mc :=
match (isReg x, isReg y) with
| (false, false) => (addMetricInstructions 3 (addMetricLoads 4 (addMetricStores 1 mc)))
| (false, true) => (addMetricInstructions 2 (addMetricLoads 2 (addMetricStores 1 mc)))
| ( true, false) => (addMetricInstructions 2 (addMetricLoads 3 mc))
| ( true, true) => (addMetricInstructions 1 (addMetricLoads 1 mc))
end.

Definition cost_if x y mc :=
match (isReg x, match y with | Some y' => isReg y' | None => true end) with
| (false, false) => (addMetricInstructions 4 (addMetricLoads 6 (addMetricJumps 1 mc)))
| (false, true) | ( true, false) => (addMetricInstructions 3 (addMetricLoads 4 (addMetricJumps 1 mc)))
| ( true, true) => (addMetricInstructions 2 (addMetricLoads 2 (addMetricJumps 1 mc)))
end.

Definition cost_loop_true x y mc :=
match (isReg x, match y with | Some y' => isReg y' | None => true end) with
| (false, false) => (addMetricInstructions 4 (addMetricLoads 6 (addMetricJumps 1 mc)))
| (false, true) | ( true, false) => (addMetricInstructions 3 (addMetricLoads 4 (addMetricJumps 1 mc)))
| ( true, true) => (addMetricInstructions 2 (addMetricLoads 2 (addMetricJumps 1 mc)))
end.

Definition cost_loop_false x y mc :=
match (isReg x, match y with | Some y' => isReg y' | None => true end) with
| (false, false) => (addMetricInstructions 3 (addMetricLoads 5 (addMetricJumps 1 mc)))
| (false, true) | ( true, false) => (addMetricInstructions 2 (addMetricLoads 3 (addMetricJumps 1 mc)))
| ( true, true) => (addMetricInstructions 1 (addMetricLoads 1 (addMetricJumps 1 mc)))
end.

End FlatImpExec.

Definition isRegZ (var : Z) : bool :=
Z.leb var 31.

Definition isRegStr (var : String.string) : bool :=
String.prefix "reg_" var.

Ltac cost_unfold :=
unfold cost_interact, cost_call_internal, cost_call_external, cost_load,
cost_store, cost_inlinetable, cost_stackalloc, cost_lit, cost_op, cost_set,
cost_if, cost_loop_true, cost_loop_false, EmptyMetricLog in *.

Ltac cost_destr :=
repeat match goal with
| x : compphase |- _ => destr x
| _ : context[if ?x then _ else _] |- _ => destr x; try discriminate
| |- context[if ?x then _ else _] => destr x; try discriminate
end.

Ltac cost_solve := cost_unfold; cost_destr; try solve_MetricLog.
Ltac cost_solve_piecewise := cost_unfold; cost_destr; try solve_MetricLog_piecewise.

Definition metrics_additive f := forall mc, f mc - mc = f EmptyMetricLog.
#[global] Transparent metrics_additive.

Ltac t := unfold metrics_additive; intros; cost_solve_piecewise.
Lemma cost_additive_interact : forall phase, metrics_additive (cost_interact phase). Proof. t. Qed.
Lemma cost_additive_call_internal : forall phase, metrics_additive (cost_call_internal phase). Proof. t. Qed.
Lemma cost_additive_call_external : forall phase, metrics_additive (cost_call_external phase). Proof. t. Qed.
Lemma cost_additive_load : forall varname isReg x a, metrics_additive (@cost_load varname isReg x a). Proof. t. Qed.
Lemma cost_additive_store : forall varname isReg x a, metrics_additive (@cost_store varname isReg x a). Proof. t. Qed.
Lemma cost_additive_inlinetable : forall varname isReg x a, metrics_additive (@cost_inlinetable varname isReg x a). Proof. t. Qed.
Lemma cost_additive_stackalloc : forall varname isReg x, metrics_additive (@cost_stackalloc varname isReg x). Proof. t. Qed.
Lemma cost_additive_lit : forall varname isReg x, metrics_additive (@cost_lit varname isReg x). Proof. t. Qed.
Lemma cost_additive_op : forall varname isReg x y z, metrics_additive (@cost_op varname isReg x y z). Proof. t. Qed.
Lemma cost_additive_set : forall varname isReg x y, metrics_additive (@cost_set varname isReg x y). Proof. t. Qed.
Lemma cost_additive_if : forall varname isReg x y, metrics_additive (@cost_if varname isReg x y). Proof. t. Qed.
Lemma cost_additive_loop_true : forall varname isReg x y, metrics_additive (@cost_loop_true varname isReg x y). Proof. t. Qed.
Lemma cost_additive_loop_false : forall varname isReg x y, metrics_additive (@cost_loop_false varname isReg x y). Proof. t. Qed.

(* COQBUG:
these cannot have "in *", because this causes a crash if the environment contains a Semantics.ExtSpec.
Anomaly "Unable to handle arbitrary u+k <= v constraints."
Please report at http://coq.inria.fr/bugs/.
to use these in hypotheses, revert them first *)
Ltac cost_additive := repeat (
rewrite cost_additive_interact ||
rewrite cost_additive_call_internal ||
rewrite cost_additive_call_external ||
rewrite cost_additive_load ||
rewrite cost_additive_store ||
rewrite cost_additive_inlinetable ||
rewrite cost_additive_stackalloc ||
rewrite cost_additive_lit ||
rewrite cost_additive_op ||
rewrite cost_additive_set ||
rewrite cost_additive_if ||
rewrite cost_additive_loop_true ||
rewrite cost_additive_loop_false
).

Ltac cost_hammer := cost_additive; try solve [eauto 3 with metric_arith | cost_solve].
89 changes: 83 additions & 6 deletions bedrock2/src/bedrock2/MetricLogging.v
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Section Riscv.
Definition subMetricLoads n log := withLoads (loads log - n) log.
Definition subMetricJumps n log := withJumps (jumps log - n) log.

Definition metricAdd(metric: MetricLog -> Z) finalM initialM : Z :=
samuelgruetter marked this conversation as resolved.
Show resolved Hide resolved
Z.add (metric finalM) (metric initialM).
Definition metricSub(metric: MetricLog -> Z) finalM initialM : Z :=
Z.sub (metric finalM) (metric initialM).

Expand All @@ -40,8 +42,16 @@ Section Riscv.
(op loads initialM finalM)
(op jumps initialM finalM).

Definition metricsAdd := metricsOp metricAdd.
Definition metricsSub := metricsOp metricSub.

Definition metricsMul (n : Z) (m : MetricLog) :=
mkMetricLog
(n * instructions m)
(n * stores m)
(n * loads m)
(n * jumps m).

Definition metricLeq(metric: MetricLog -> Z) m1 m2: Prop :=
(metric m1) <= (metric m2).

Expand All @@ -51,20 +61,17 @@ Section Riscv.
metricLeq loads m1 m2 /\
metricLeq jumps m1 m2.

Definition metricMax(metric: MetricLog -> Z) m1 m2: Z :=
Z.max (metric m1) (metric m2).

Definition metricsMax := metricsOp metricMax.
End Riscv.

Declare Scope MetricH_scope.
Bind Scope MetricH_scope with MetricLog.
Delimit Scope MetricH_scope with metricsH.

Infix "<=" := metricsLeq : MetricH_scope.
Infix "+" := metricsAdd : MetricH_scope.
Infix "-" := metricsSub : MetricH_scope.
Infix "*" := metricsMul : MetricH_scope.

#[export] Hint Unfold
#[global] Hint Unfold
samuelgruetter marked this conversation as resolved.
Show resolved Hide resolved
withInstructions
withLoads
withStores
Expand All @@ -78,8 +85,11 @@ Infix "-" := metricsSub : MetricH_scope.
subMetricStores
subMetricJumps
metricsOp
metricAdd
metricsAdd
metricSub
metricsSub
metricsMul
metricLeq
metricsLeq
: unf_metric_log.
Expand Down Expand Up @@ -107,3 +117,70 @@ Ltac solve_MetricLog :=
repeat unfold_MetricLog;
repeat simpl_MetricLog;
blia.

Ltac solve_MetricLog_piecewise :=
repeat unfold_MetricLog;
repeat simpl_MetricLog;
f_equal; blia.

Module MetricArith.

Open Scope MetricH_scope.

Lemma mul_sub_distr_r : forall n m p, (n - m) * p = n * p - m * p.
Proof. intros. unfold_MetricLog. f_equal; apply Z.mul_sub_distr_r. Qed.

Lemma add_sub_swap : forall n m p, n + m - p = n - p + m.
Proof. intros. unfold_MetricLog. f_equal; apply Z.add_sub_swap. Qed.

Lemma le_add_le_sub_r : forall n m p, n + p <= m <-> n <= m - p.
Proof. solve_MetricLog. Qed.

Lemma le_trans : forall n m p, n <= m -> m <= p -> n <= p.
Proof. solve_MetricLog. Qed.

Lemma le_refl : forall m, m <= m.
Proof. solve_MetricLog. Qed.

Lemma le_sub_mono : forall n m p, n - p <= m - p <-> n <= m.
Proof. solve_MetricLog. Qed.

Lemma add_0_r : forall mc, (mc + EmptyMetricLog)%metricsH = mc.
Proof. destruct mc. unfold EmptyMetricLog. solve_MetricLog_piecewise. Qed.

Lemma sub_0_r : forall mc, (mc - EmptyMetricLog)%metricsH = mc.
Proof. destruct mc. unfold EmptyMetricLog. solve_MetricLog_piecewise. Qed.

End MetricArith.

Create HintDb metric_arith.
#[export] Hint Resolve MetricArith.le_trans MetricArith.le_refl MetricArith.add_0_r MetricArith.sub_0_r : metric_arith.
#[export] Hint Resolve <- MetricArith.le_sub_mono : metric_arith.
#[export] Hint Resolve -> MetricArith.le_sub_mono : metric_arith.

Lemma applyAddInstructions n a b c d : addMetricInstructions n {| instructions := a; stores := b; loads := c; jumps := d |} = {| instructions := a+n; stores := b; loads := c; jumps := d |}. Proof. auto. Qed.
Lemma applyAddStores n a b c d : addMetricStores n {| instructions := a; stores := b; loads := c; jumps := d |} = {| instructions := a; stores := b+n; loads := c; jumps := d |}. Proof. auto. Qed.
Lemma applyAddLoads n a b c d : addMetricLoads n {| instructions := a; stores := b; loads := c; jumps := d |} = {| instructions := a; stores := b; loads := c+n; jumps := d |}. Proof. auto. Qed.
Lemma applyAddJumps n a b c d : addMetricJumps n {| instructions := a; stores := b; loads := c; jumps := d |} = {| instructions := a; stores := b; loads := c; jumps := d+n |}. Proof. auto. Qed.

Ltac applyAddMetricsGoal := (
repeat (
try rewrite applyAddInstructions;
try rewrite applyAddStores;
try rewrite applyAddLoads;
try rewrite applyAddJumps
);
repeat rewrite <- Z.add_assoc;
cbn [Z.add Pos.add Pos.succ]
).

Ltac applyAddMetrics H := (
repeat (
try rewrite applyAddInstructions in H;
try rewrite applyAddStores in H;
try rewrite applyAddLoads in H;
try rewrite applyAddJumps in H
);
repeat rewrite <- Z.add_assoc in H;
cbn [Z.add Pos.add Pos.succ] in H
).
Loading
Loading