diff options
author | Tristan Gingold <tgingold@free.fr> | 2016-12-20 04:52:34 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2016-12-20 04:52:34 +0100 |
commit | abaeccd90ef5b83812fa2e71d4ce2aff8434df4e (patch) | |
tree | 6b6d9c6f551a22d6826bb85ff1131ba1cbc5cd5f | |
parent | d8ae737938689cdac8f96e0b86815b0c95aef692 (diff) | |
download | ghdl-abaeccd90ef5b83812fa2e71d4ce2aff8434df4e.tar.gz ghdl-abaeccd90ef5b83812fa2e71d4ce2aff8434df4e.tar.bz2 ghdl-abaeccd90ef5b83812fa2e71d4ce2aff8434df4e.zip |
Remove Get/Set_Value_Staticness, add Get/Set_Aggregate_Expand_Flag
-rw-r--r-- | src/vhdl/iirs.adb | 29 | ||||
-rw-r--r-- | src/vhdl/iirs.ads | 20 | ||||
-rw-r--r-- | src/vhdl/iirs_utils.adb | 19 | ||||
-rw-r--r-- | src/vhdl/iirs_utils.ads | 7 | ||||
-rw-r--r-- | src/vhdl/nodes_meta.adb | 22 | ||||
-rw-r--r-- | src/vhdl/nodes_meta.ads | 4 | ||||
-rw-r--r-- | src/vhdl/sem_expr.adb | 72 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap7.adb | 48 |
8 files changed, 128 insertions, 93 deletions
diff --git a/src/vhdl/iirs.adb b/src/vhdl/iirs.adb index 133e0b717..fe2b20624 100644 --- a/src/vhdl/iirs.adb +++ b/src/vhdl/iirs.adb @@ -4933,22 +4933,21 @@ package body Iirs is Set_Flag4 (Target, Val); end Set_Aggr_Named_Flag; - function Get_Value_Staticness (Target : Iir) return Iir_Staticness is + function Get_Aggregate_Expand_Flag (Aggr : Iir) return Boolean is begin - pragma Assert (Target /= Null_Iir); - pragma Assert (Has_Value_Staticness (Get_Kind (Target)), - "no field Value_Staticness"); - return Iir_Staticness'Val (Get_State2 (Target)); - end Get_Value_Staticness; + pragma Assert (Aggr /= Null_Iir); + pragma Assert (Has_Aggregate_Expand_Flag (Get_Kind (Aggr)), + "no field Aggregate_Expand_Flag"); + return Get_Flag1 (Aggr); + end Get_Aggregate_Expand_Flag; - procedure Set_Value_Staticness (Target : Iir; Staticness : Iir_Staticness) - is + procedure Set_Aggregate_Expand_Flag (Aggr : Iir; Flag : Boolean) is begin - pragma Assert (Target /= Null_Iir); - pragma Assert (Has_Value_Staticness (Get_Kind (Target)), - "no field Value_Staticness"); - Set_State2 (Target, Iir_Staticness'Pos (Staticness)); - end Set_Value_Staticness; + pragma Assert (Aggr /= Null_Iir); + pragma Assert (Has_Aggregate_Expand_Flag (Get_Kind (Aggr)), + "no field Aggregate_Expand_Flag"); + Set_Flag1 (Aggr, Flag); + end Set_Aggregate_Expand_Flag; function Get_Association_Choices_Chain (Target : Iir) return Iir is begin @@ -4988,7 +4987,7 @@ package body Iirs is pragma Assert (Target /= Null_Iir); pragma Assert (Has_Choice_Staticness (Get_Kind (Target)), "no field Choice_Staticness"); - return Iir_Staticness'Val (Get_State2 (Target)); + return Iir_Staticness'Val (Get_State1 (Target)); end Get_Choice_Staticness; procedure Set_Choice_Staticness (Target : Iir; Staticness : Iir_Staticness) @@ -4997,7 +4996,7 @@ package body Iirs is pragma Assert (Target /= Null_Iir); pragma Assert (Has_Choice_Staticness (Get_Kind (Target)), "no field Choice_Staticness"); - Set_State2 (Target, Iir_Staticness'Pos (Staticness)); + Set_State1 (Target, Iir_Staticness'Pos (Staticness)); end Set_Choice_Staticness; function Get_Procedure_Call (Stmt : Iir) return Iir is diff --git a/src/vhdl/iirs.ads b/src/vhdl/iirs.ads index 7c7159756..487fc17af 100644 --- a/src/vhdl/iirs.ads +++ b/src/vhdl/iirs.ads @@ -469,7 +469,7 @@ package Iirs is -- -- Only for Iir_Kind_Association_Element_By_Individual: -- Must be Locally unless there is an error on one choice. - -- Get/Set_Choice_Staticness (State2) + -- Get/Set_Choice_Staticness (State1) -- Iir_Kind_Waveform_Element (Short) -- @@ -548,7 +548,7 @@ package Iirs is -- -- Only for Iir_Kind_Choice_By_Range: -- Only for Iir_Kind_Choice_By_Expression: - -- Get/Set_Choice_Staticness (State2) + -- Get/Set_Choice_Staticness (State1) -- Iir_Kind_Entity_Aspect_Entity (Short) -- @@ -3427,7 +3427,9 @@ package Iirs is -- -- Get/Set_Expr_Staticness (State1) -- - -- Get/Set_Value_Staticness (State2) + -- If true, the aggregate can be statically built. This is an optimization + -- and the conditions are defined in sem_expr. + -- Get/Set_Aggregate_Expand_Flag (Flag1) -- Iir_Kind_Aggregate_Info (Short) -- @@ -7019,12 +7021,10 @@ package Iirs is function Get_Aggr_Named_Flag (Target : Iir_Aggregate_Info) return Boolean; procedure Set_Aggr_Named_Flag (Target : Iir_Aggregate_Info; Val : Boolean); - -- Staticness of the expressions in an aggregate. - -- We can't use expr_staticness for this purpose, since the staticness - -- of an aggregate is at most globally. - -- Field: State2 (pos) - function Get_Value_Staticness (Target : Iir) return Iir_Staticness; - procedure Set_Value_Staticness (Target : Iir; Staticness : Iir_Staticness); + -- True if the aggregate can be statically built. + -- Field: Flag1 + function Get_Aggregate_Expand_Flag (Aggr : Iir) return Boolean; + procedure Set_Aggregate_Expand_Flag (Aggr : Iir; Flag : Boolean); -- Chain of choices. -- Field: Field4 Chain @@ -7037,7 +7037,7 @@ package Iirs is procedure Set_Case_Statement_Alternative_Chain (Target : Iir; Chain : Iir); -- Staticness of the choice. - -- Field: State2 (pos) + -- Field: State1 (pos) function Get_Choice_Staticness (Target : Iir) return Iir_Staticness; procedure Set_Choice_Staticness (Target : Iir; Staticness : Iir_Staticness); diff --git a/src/vhdl/iirs_utils.adb b/src/vhdl/iirs_utils.adb index 69bbf55e6..4664f8dfa 100644 --- a/src/vhdl/iirs_utils.adb +++ b/src/vhdl/iirs_utils.adb @@ -736,6 +736,25 @@ package body Iirs_Utils is Set_Range_Constraint (Def, Range_Expr); end Create_Range_Constraint_For_Enumeration_Type; + function Is_Static_Construct (Expr : Iir) return Boolean is + begin + case Get_Kind (Expr) is + when Iir_Kind_Aggregate => + return Get_Aggregate_Expand_Flag (Expr); + when Iir_Kinds_Literal => + return True; + when Iir_Kind_Simple_Aggregate + | Iir_Kind_Enumeration_Literal + | Iir_Kind_Character_Literal => + return True; + when Iir_Kind_Overflow_Literal => + -- Needs to generate an error. + return False; + when others => + return False; + end case; + end Is_Static_Construct; + procedure Free_Name (Node : Iir) is N : Iir; diff --git a/src/vhdl/iirs_utils.ads b/src/vhdl/iirs_utils.ads index 3a1ddfc2c..dace93c3c 100644 --- a/src/vhdl/iirs_utils.ads +++ b/src/vhdl/iirs_utils.ads @@ -103,6 +103,13 @@ package Iirs_Utils is -- Duplicate enumeration literal LIT. function Copy_Enumeration_Literal (Lit : Iir) return Iir; + -- True if EXPR can be built statically. This is the case of literals + -- (except overflow), and the case of some aggregates. + -- This is different from locally static expression, particularly for + -- agregate: the analyzer may choose to dynamically create a locally + -- static aggregate if it is sparse. + function Is_Static_Construct (Expr : Iir) return Boolean; + -- Make TARGETS depends on UNIT. -- UNIT must be either a design unit or a entity_aspect_entity. procedure Add_Dependence (Target: Iir_Design_Unit; Unit: Iir); diff --git a/src/vhdl/nodes_meta.adb b/src/vhdl/nodes_meta.adb index 9792d989f..d873669c8 100644 --- a/src/vhdl/nodes_meta.adb +++ b/src/vhdl/nodes_meta.adb @@ -288,7 +288,7 @@ package body Nodes_Meta is Field_Aggr_High_Limit => Type_Iir, Field_Aggr_Others_Flag => Type_Boolean, Field_Aggr_Named_Flag => Type_Boolean, - Field_Value_Staticness => Type_Iir_Staticness, + Field_Aggregate_Expand_Flag => Type_Boolean, Field_Association_Choices_Chain => Type_Iir, Field_Case_Statement_Alternative_Chain => Type_Iir, Field_Choice_Staticness => Type_Iir_Staticness, @@ -889,8 +889,8 @@ package body Nodes_Meta is return "aggr_others_flag"; when Field_Aggr_Named_Flag => return "aggr_named_flag"; - when Field_Value_Staticness => - return "value_staticness"; + when Field_Aggregate_Expand_Flag => + return "aggregate_expand_flag"; when Field_Association_Choices_Chain => return "association_choices_chain"; when Field_Case_Statement_Alternative_Chain => @@ -2077,7 +2077,7 @@ package body Nodes_Meta is return Attr_None; when Field_Aggr_Named_Flag => return Attr_None; - when Field_Value_Staticness => + when Field_Aggregate_Expand_Flag => return Attr_None; when Field_Association_Choices_Chain => return Attr_Chain; @@ -3539,8 +3539,8 @@ package body Nodes_Meta is Field_Method_Object, Field_Base_Name, -- Iir_Kind_Aggregate + Field_Aggregate_Expand_Flag, Field_Expr_Staticness, - Field_Value_Staticness, Field_Association_Choices_Chain, Field_Literal_Subtype, Field_Literal_Origin, @@ -4682,6 +4682,8 @@ package body Nodes_Meta is return Get_Aggr_Others_Flag (N); when Field_Aggr_Named_Flag => return Get_Aggr_Named_Flag (N); + when Field_Aggregate_Expand_Flag => + return Get_Aggregate_Expand_Flag (N); when Field_Has_Disconnect_Flag => return Get_Has_Disconnect_Flag (N); when Field_Has_Active_Flag => @@ -4806,6 +4808,8 @@ package body Nodes_Meta is Set_Aggr_Others_Flag (N, V); when Field_Aggr_Named_Flag => Set_Aggr_Named_Flag (N, V); + when Field_Aggregate_Expand_Flag => + Set_Aggregate_Expand_Flag (N, V); when Field_Has_Disconnect_Flag => Set_Has_Disconnect_Flag (N, V); when Field_Has_Active_Flag => @@ -6142,8 +6146,6 @@ package body Nodes_Meta is return Get_Expr_Staticness (N); when Field_Name_Staticness => return Get_Name_Staticness (N); - when Field_Value_Staticness => - return Get_Value_Staticness (N); when Field_Choice_Staticness => return Get_Choice_Staticness (N); when others => @@ -6162,8 +6164,6 @@ package body Nodes_Meta is Set_Expr_Staticness (N, V); when Field_Name_Staticness => Set_Name_Staticness (N, V); - when Field_Value_Staticness => - Set_Value_Staticness (N, V); when Field_Choice_Staticness => Set_Choice_Staticness (N, V); when others => @@ -9858,10 +9858,10 @@ package body Nodes_Meta is return K = Iir_Kind_Aggregate_Info; end Has_Aggr_Named_Flag; - function Has_Value_Staticness (K : Iir_Kind) return Boolean is + function Has_Aggregate_Expand_Flag (K : Iir_Kind) return Boolean is begin return K = Iir_Kind_Aggregate; - end Has_Value_Staticness; + end Has_Aggregate_Expand_Flag; function Has_Association_Choices_Chain (K : Iir_Kind) return Boolean is begin diff --git a/src/vhdl/nodes_meta.ads b/src/vhdl/nodes_meta.ads index 0400f4025..a67db7f2e 100644 --- a/src/vhdl/nodes_meta.ads +++ b/src/vhdl/nodes_meta.ads @@ -328,7 +328,7 @@ package Nodes_Meta is Field_Aggr_High_Limit, Field_Aggr_Others_Flag, Field_Aggr_Named_Flag, - Field_Value_Staticness, + Field_Aggregate_Expand_Flag, Field_Association_Choices_Chain, Field_Case_Statement_Alternative_Chain, Field_Choice_Staticness, @@ -838,7 +838,7 @@ package Nodes_Meta is function Has_Aggr_High_Limit (K : Iir_Kind) return Boolean; function Has_Aggr_Others_Flag (K : Iir_Kind) return Boolean; function Has_Aggr_Named_Flag (K : Iir_Kind) return Boolean; - function Has_Value_Staticness (K : Iir_Kind) return Boolean; + function Has_Aggregate_Expand_Flag (K : Iir_Kind) return Boolean; function Has_Association_Choices_Chain (K : Iir_Kind) return Boolean; function Has_Case_Statement_Alternative_Chain (K : Iir_Kind) return Boolean; diff --git a/src/vhdl/sem_expr.adb b/src/vhdl/sem_expr.adb index 3707e0e10..63cd7de6c 100644 --- a/src/vhdl/sem_expr.adb +++ b/src/vhdl/sem_expr.adb @@ -2902,12 +2902,12 @@ package body Sem_Expr is Expr: Iir; Has_Named : Boolean; Rec_El_Index : Natural; - Value_Staticness : Iir_Staticness; + Expr_Staticness : Iir_Staticness; begin Ok := True; Assoc_Chain := Get_Association_Choices_Chain (Aggr); Matches := (others => Null_Iir); - Value_Staticness := Locally; + Expr_Staticness := Locally; El_Type := Null_Iir; Has_Named := False; @@ -2976,8 +2976,8 @@ package body Sem_Expr is Expr := Sem_Expression (Expr, El_Type); if Expr /= Null_Iir then Set_Associated_Expr (El, Eval_Expr_If_Static (Expr)); - Value_Staticness := Min (Value_Staticness, - Get_Expr_Staticness (Expr)); + Expr_Staticness := Min (Expr_Staticness, + Get_Expr_Staticness (Expr)); else Ok := False; end if; @@ -3001,9 +3001,8 @@ package body Sem_Expr is Ok := False; end if; end loop; - Set_Value_Staticness (Aggr, Value_Staticness); Set_Expr_Staticness (Aggr, Min (Get_Expr_Staticness (Aggr), - Value_Staticness)); + Expr_Staticness)); return Ok; end Sem_Record_Aggregate; @@ -3031,6 +3030,11 @@ package body Sem_Expr is -- If every dimension has bounds, then the aggregate is constrained. Index_Subtype : Iir := Null_Iir; + -- Number of associations in last-level (not for sub-aggregate). This + -- is used only to decide whether or not a static aggregate can be + -- expanded. + Nbr_Assocs : Natural := 0; + -- True if there is an error. Error : Boolean := False; @@ -3068,11 +3072,11 @@ package body Sem_Expr is Index_Constraint : Iir_Range_Expression; -- FIXME: 'range. Dir : Iir_Direction; Choice_Staticness : Iir_Staticness; - Value_Staticness : Iir_Staticness; + Expr_Staticness : Iir_Staticness; Info : Array_Aggr_Info renames Infos (Dim); begin - -- Sem choices. + -- Analyze choices. case Get_Kind (Aggr) is when Iir_Kind_Aggregate => Assoc_Chain := Get_Association_Choices_Chain (Aggr); @@ -3159,6 +3163,7 @@ package body Sem_Expr is Is_Positional := True; Has_Others := False; Choice_Staticness := Locally; + Info.Nbr_Assocs := Info.Nbr_Assocs + Len; when others => Error_Kind ("sem_array_aggregate_type_1", Aggr); @@ -3191,6 +3196,7 @@ package body Sem_Expr is return; end if; Info.Has_Dynamic := True; + Set_Aggregate_Expand_Flag (Aggr, False); end if; -- Compute bounds of the index if there is no index subtype. @@ -3271,6 +3277,8 @@ package body Sem_Expr is end if; else -- Dynamic aggregate. + Set_Aggregate_Expand_Flag (Aggr, False); + declare -- There is only one choice. Choice : constant Iir := Assoc_Chain; @@ -3330,12 +3338,13 @@ package body Sem_Expr is end if; -- Analyze aggregate elements. - Value_Staticness := Locally; + Expr_Staticness := Locally; if Dim = Get_Nbr_Elements (Index_List) then -- A type has been found for AGGR, analyze AGGR as if it was -- an aggregate with a subtype (and not a string). if Get_Kind (Aggr) /= Iir_Kind_Aggregate then + -- Nothing to do for a string. return; end if; @@ -3358,6 +3367,10 @@ package body Sem_Expr is Expr := Eval_Expr_If_Static (Expr); Set_Associated_Expr (El, Expr); + if not Is_Static_Construct (Expr) then + Set_Aggregate_Expand_Flag (Aggr, False); + end if; + if not Eval_Is_In_Bound (Expr, Element_Type) then Info.Has_Bound_Error := True; @@ -3365,12 +3378,9 @@ package body Sem_Expr is "element is out of the bounds"); end if; - -- FIXME: handle name/others in translate. - -- if Get_Kind (Expr) = Iir_Kind_Aggregate then - -- Expr_Staticness := Get_Value_Staticness (Expr); - -- end if; - Value_Staticness := Min (Value_Staticness, - El_Staticness); + Expr_Staticness := Min (Expr_Staticness, El_Staticness); + + Info.Nbr_Assocs := Info.Nbr_Assocs + 1; else Info.Error := True; end if; @@ -3379,6 +3389,7 @@ package body Sem_Expr is end loop; end; else + -- A sub-aggregate: recurse. declare Assoc : Iir; begin @@ -3392,8 +3403,6 @@ package body Sem_Expr is when Iir_Kind_Aggregate => Sem_Array_Aggregate_Type_1 (Assoc, A_Type, Infos, Constrained, Dim + 1); - Value_Staticness := Min (Value_Staticness, - Get_Value_Staticness (Assoc)); when Iir_Kind_String_Literal8 => if Dim + 1 = Get_Nbr_Elements (Index_List) then Sem_Array_Aggregate_Type_1 @@ -3411,9 +3420,8 @@ package body Sem_Expr is end loop; end; end if; - Set_Value_Staticness (Aggr, Value_Staticness); Set_Expr_Staticness (Aggr, Min (Get_Expr_Staticness (Aggr), - Min (Value_Staticness, + Min (Expr_Staticness, Choice_Staticness))); end Sem_Array_Aggregate_Type_1; @@ -3434,6 +3442,9 @@ package body Sem_Expr is Aggr_Constrained : Boolean; Info, Prev_Info : Iir_Aggregate_Info; begin + -- By default, consider the aggregate can be statically built. + Set_Aggregate_Expand_Flag (Aggr, True); + -- Analyze the aggregate. Sem_Array_Aggregate_Type_1 (Aggr, Aggr_Type, Infos, Constrained, 1); @@ -3441,6 +3452,7 @@ package body Sem_Expr is for I in Infos'Range loop -- Return now in case of error. if Infos (I).Error then + Set_Aggregate_Expand_Flag (Aggr, False); return Null_Iir; end if; if Infos (I).Index_Subtype = Null_Iir then @@ -3465,6 +3477,25 @@ package body Sem_Expr is Set_Constraint_State (A_Subtype, Fully_Constrained); Set_Type (Aggr, A_Subtype); Set_Literal_Subtype (Aggr, A_Subtype); + if Get_Type_Staticness (A_Subtype) = Locally + and then Get_Aggregate_Expand_Flag (Aggr) + then + -- Compute ratio of elements vs size of the aggregate to determine + -- if the aggregate can be expanded. + declare + Size : Iir_Int64; + begin + Size := 1; + for I in Infos'Range loop + Size := Size + * Eval_Discrete_Type_Length (Infos (I).Index_Subtype); + end loop; + Set_Aggregate_Expand_Flag + (Aggr, Infos (Nbr_Dim).Nbr_Assocs >= Natural (Size / 10)); + end; + else + Set_Aggregate_Expand_Flag (Aggr, False); + end if; else -- Free unused indexes subtype. for I in Infos'Range loop @@ -3480,6 +3511,9 @@ package body Sem_Expr is end if; end; end loop; + + -- If bounds are not known, the aggregate cannot be statically built. + Set_Aggregate_Expand_Flag (Aggr, False); end if; if Infos (Nbr_Dim).Has_Bound_Error then diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb index e773b3c87..661b95af2 100644 --- a/src/vhdl/translate/trans-chap7.adb +++ b/src/vhdl/translate/trans-chap7.adb @@ -113,40 +113,20 @@ package body Trans.Chap7 is end if; -- Only aggregates are specially handled. - case Get_Kind (Expr) is - when Iir_Kind_Aggregate => - null; - when Iir_Kind_Simple_Aggregate - | Iir_Kind_Null_Literal - | Iir_Kind_Physical_Int_Literal - | Iir_Kind_Physical_Fp_Literal - | Iir_Kind_Integer_Literal - | Iir_Kind_Floating_Point_Literal - | Iir_Kind_String_Literal8 => - return True; - when Iir_Kind_Overflow_Literal => - return False; - when others => - return False; - end case; - - Atype := Get_Type (Decl); - -- Bounds must be known (and static). - if Get_Type_Staticness (Atype) /= Locally then + if not Is_Static_Construct (Expr) + or else Get_Kind (Expr) /= Iir_Kind_Aggregate + then return False; end if; + Atype := Get_Type (Decl); + -- Currently, only array aggregates are handled. if Get_Kind (Get_Base_Type (Atype)) /= Iir_Kind_Array_Type_Definition then return False; end if; - -- Aggregate elements must be locally static. - -- Note: this does not yet handled aggregates of aggregates. - if Get_Value_Staticness (Expr) /= Locally then - return False; - end if; Info := Get_Aggregate_Info (Expr); while Info /= Null_Iir loop if Get_Aggr_Dynamic_Flag (Info) then @@ -4543,11 +4523,14 @@ package body Trans.Chap7 is procedure Translate_Predefined_Array_Equality (Subprg : Iir) is + Arr_Type : constant Iir_Array_Type_Definition := + Get_Type (Get_Interface_Declaration_Chain (Subprg)); + El_Type : constant Iir := Get_Element_Subtype (Arr_Type); + Info : constant Type_Info_Acc := Get_Info (Arr_Type); + Id : constant Name_Id := + Get_Identifier (Get_Type_Declarator (Arr_Type)); + Arr_Ptr_Type : constant O_Tnode := Info.Ortho_Ptr_Type (Mode_Value); F_Info : Subprg_Info_Acc; - Arr_Type : Iir_Array_Type_Definition; - Arr_Ptr_Type : O_Tnode; - Info : Type_Info_Acc; - Id : Name_Id; Var_L, Var_R : O_Dnode; L, R : Mnode; Interface_List : O_Inter_List; @@ -4558,14 +4541,7 @@ package body Trans.Chap7 is Var_Len : O_Dnode; Label : O_Snode; Le, Re : Mnode; - El_Type : Iir; begin - Arr_Type := Get_Type (Get_Interface_Declaration_Chain (Subprg)); - El_Type := Get_Element_Subtype (Arr_Type); - Info := Get_Info (Arr_Type); - Id := Get_Identifier (Get_Type_Declarator (Arr_Type)); - Arr_Ptr_Type := Info.Ortho_Ptr_Type (Mode_Value); - F_Info := Add_Info (Subprg, Kind_Subprg); -- Create function. |