aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-09-28 07:06:19 +0200
committerTristan Gingold <tgingold@free.fr>2019-09-28 07:06:19 +0200
commitdf9c9a3e8db99bc9647e1c349c22f77e4566ecc9 (patch)
treee219e3e0aba2c6845da8c80d6c53bf011e8a4d35
parentedd1d24a7de51780fbb5648df0195b7bbf3b2f5d (diff)
downloadghdl-df9c9a3e8db99bc9647e1c349c22f77e4566ecc9.tar.gz
ghdl-df9c9a3e8db99bc9647e1c349c22f77e4566ecc9.tar.bz2
ghdl-df9c9a3e8db99bc9647e1c349c22f77e4566ecc9.zip
synth-stmts: simple optimization for loop control logic.
-rw-r--r--src/synth/synth-stmts.adb29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index 6d42193b3..bcc038180 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -1370,6 +1370,20 @@ package body Synth.Stmts is
end if;
end Loop_Control_Init;
+ function Loop_Control_And (C : Seq_Context; L, R : Net) return Net
+ is
+ B1 : constant Net := Get_Inst_Bit1 (C.Inst);
+ begin
+ -- Optimize common cases.
+ if L = B1 then
+ return R;
+ elsif R = B1 then
+ return L;
+ else
+ return Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And, L, R);
+ end if;
+ end Loop_Control_And;
+
procedure Loop_Control_Update (C : Seq_Context)
is
Lc : constant Loop_Context_Acc := C.Cur_Loop;
@@ -1385,20 +1399,17 @@ package body Synth.Stmts is
-- 2. No return (C.W_Ret)
if C.W_Ret /= No_Wire_Id then
- Res := Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And,
- Res, Get_Current_Value (null, C.W_Ret));
+ Res := Loop_Control_And (C, Res, Get_Current_Value (null, C.W_Ret));
end if;
-- 3. No exit.
if Lc.W_Exit /= No_Wire_Id then
- Res := Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And,
- Res, Get_Current_Value (null, Lc.W_Exit));
+ Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Exit));
end if;
-- 4. No quit.
if Lc.W_Quit /= No_Wire_Id then
- Res := Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And,
- Res, Get_Current_Value (null, Lc.W_Quit));
+ Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Quit));
end if;
Phi_Assign (Get_Build (C.Inst), C.W_En, Res, 0);
@@ -1419,14 +1430,12 @@ package body Synth.Stmts is
-- 2. No return (C.W_Ret)
if C.W_Ret /= No_Wire_Id then
- Res := Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And,
- Res, Get_Current_Value (null, C.W_Ret));
+ Res := Loop_Control_And (C, Res, Get_Current_Value (null, C.W_Ret));
end if;
-- 3. No quit (C.W_Quit)
if Lc.W_Quit /= No_Wire_Id then
- Res := Build_Dyadic (Get_Build (C.Inst), Netlists.Gates.Id_And,
- Res, Get_Current_Value (null, Lc.W_Quit));
+ Res := Loop_Control_And (C, Res, Get_Current_Value (null, Lc.W_Quit));
end if;
Phi_Discard_Wires (Lc.W_Quit, Lc.W_Exit);