aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-11-09 07:14:55 +0100
committerTristan Gingold <tgingold@free.fr>2019-11-11 20:25:34 +0100
commitf3c6b53fd39049e8bda611dc98a50e93ceb7be39 (patch)
treecba13966458ce9f5f9f1ae8f3a8127ed67850e5c
parent023644a0eedf4ac919cae2e176ddc995d2e9afb5 (diff)
downloadghdl-f3c6b53fd39049e8bda611dc98a50e93ceb7be39.tar.gz
ghdl-f3c6b53fd39049e8bda611dc98a50e93ceb7be39.tar.bz2
ghdl-f3c6b53fd39049e8bda611dc98a50e93ceb7be39.zip
synth: merge partial assignments before merging phis.
-rw-r--r--src/synth/synth-environment.adb56
-rw-r--r--src/synth/synth-stmts.adb2
2 files changed, 57 insertions, 1 deletions
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index 0612c3b14..5b051d3d7 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -179,6 +179,58 @@ package body Synth.Environment is
Nbr => 0));
end Push_Phi;
+ procedure Merge_Partial_Assignments
+ (Ctxt : Context_Acc; Head : Partial_Assign)
+ is
+ use Netlists.Concats;
+ First : Partial_Assign;
+ Next : Partial_Assign;
+ Concat : Concat_Type;
+ Expected_Next_Off : Uns32;
+ Next_Off : Uns32;
+ Next_Val : Net;
+ begin
+ First := Head;
+ loop
+ exit when First = No_Partial_Assign;
+
+ Next := Get_Partial_Next (First);
+ exit when Next = No_Partial_Assign;
+ Expected_Next_Off := Get_Partial_Offset (First)
+ + Get_Width (Get_Partial_Value (First));
+ Next_Off := Get_Partial_Offset (Next);
+ if Expected_Next_Off = Next_Off then
+ -- Merge First and Next.
+ Next_Val := Get_Partial_Value (Next);
+ Append (Concat, Get_Partial_Value (First));
+ Append (Concat, Next_Val);
+ Expected_Next_Off := Next_Off + Get_Width (Next_Val);
+ -- Merge as long as possible.
+ loop
+ Next := Get_Partial_Next (Next);
+ exit when Next = No_Partial_Assign;
+
+ Next_Off := Get_Partial_Offset (Next);
+ Next_Val := Get_Partial_Value (Next);
+ exit when Next_Off /= Expected_Next_Off;
+ Append (Concat, Next_Val);
+ Expected_Next_Off := Next_Off + Get_Width (Next_Val);
+ end loop;
+
+ -- Replace.
+ declare
+ First_Record : Partial_Assign_Record renames
+ Partial_Assign_Table.Table (First);
+ begin
+ Build (Ctxt, Concat, First_Record.Value);
+ First_Record.Next := Next;
+
+ end;
+ end if;
+ First := Next;
+ end loop;
+ end Merge_Partial_Assignments;
+
-- Get list of assignments for this current block.
procedure Pop_Phi (Phi : out Phi_Type)
is
@@ -1030,6 +1082,10 @@ package body Synth.Environment is
T_Asgns := Get_Assign_Chain (T_Asgns);
F_Asgns := Get_Assign_Chain (F_Asgns);
end if;
+ -- Merge partial assigns as much as possible. This reduce
+ -- propagation of splits.
+ Merge_Partial_Assignments (Ctxt, Fp);
+ Merge_Partial_Assignments (Ctxt, Tp);
Merge_Assigns (Ctxt, W, Sel, Fp, Tp, Stmt);
end loop;
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index 758a7aaad..ea177af30 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -615,7 +615,7 @@ package body Synth.Stmts is
end if;
Pop_Phi (Phi_False);
- Merge_Phis (Build_Context,
+ Merge_Phis (Get_Build (C.Inst),
Get_Net (Cond_Val), Phi_True, Phi_False, Stmt);
end if;
end Synth_If_Statement;