diff options
| author | Tristan Gingold <tgingold@free.fr> | 2016-12-20 06:22:58 +0100 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2016-12-20 06:22:58 +0100 | 
| commit | 7fd06aadb2e9863cb34f3dce468ac3ab0d39eb2c (patch) | |
| tree | 7f06f1231b8f0c559d9289a47f79ec46bad832b6 /src | |
| parent | abaeccd90ef5b83812fa2e71d4ce2aff8434df4e (diff) | |
| download | ghdl-7fd06aadb2e9863cb34f3dce468ac3ab0d39eb2c.tar.gz ghdl-7fd06aadb2e9863cb34f3dce468ac3ab0d39eb2c.tar.bz2 ghdl-7fd06aadb2e9863cb34f3dce468ac3ab0d39eb2c.zip | |
evaluation: tune evaluation of composite values.
Diffstat (limited to 'src')
| -rw-r--r-- | src/vhdl/evaluation.adb | 137 | ||||
| -rw-r--r-- | src/vhdl/iirs_utils.adb | 9 | ||||
| -rw-r--r-- | src/vhdl/iirs_utils.ads | 4 | ||||
| -rw-r--r-- | src/vhdl/sem_expr.adb | 7 | 
4 files changed, 152 insertions, 5 deletions
| diff --git a/src/vhdl/evaluation.adb b/src/vhdl/evaluation.adb index 4c1386a0f..e17246abf 100644 --- a/src/vhdl/evaluation.adb +++ b/src/vhdl/evaluation.adb @@ -2418,9 +2418,8 @@ package body Evaluation is           when Iir_Kind_Attribute_Name =>              --  An attribute name designates an attribute value.              declare -               Attr_Val : constant Iir := Get_Named_Entity (Expr);                 Attr_Expr : constant Iir := -                 Get_Expression (Get_Attribute_Specification (Attr_Val)); +                 Get_Attribute_Name_Expression (Expr);                 Val : Iir;              begin                 Val := Eval_Static_Expr (Attr_Expr); @@ -2701,11 +2700,141 @@ package body Evaluation is        end if;     end Eval_Expr; +   --  Subroutine of Can_Eval_Composite_Value.  Return True iff EXPR is +   --  considered as a small composite. +   function Is_Small_Composite_Value (Expr : Iir) return Boolean +   is +      Expr_Type : constant Iir := Get_Type (Expr); +      Indexes : Iir_List; +      Len : Iir_Int64; +   begin +      --  Consider only arrays.  Records are never composite. +      if Get_Kind (Expr_Type) /= Iir_Kind_Array_Subtype_Definition then +         return False; +      end if; + +      --  Element must be scalar. +      if Get_Kind (Get_Element_Subtype (Expr_Type)) not in +        Iir_Kinds_Scalar_Type_Definition +      then +         return False; +      end if; + +      Indexes := Get_Index_Subtype_List (Expr_Type); + +      --  Multi-dimensional arrays aren't considered as small. +      if Get_Nbr_Elements (Indexes) /= 1 then +         return False; +      end if; + +      Len := Eval_Discrete_Type_Length (Get_Nth_Element (Indexes, 0)); +      return Len <= 128; +   end Is_Small_Composite_Value; + +   function Can_Eval_Composite_Value (Expr : Iir; Top : Boolean := False) +                                     return Boolean; + +   --  Return True if EXPR should be evaluated. +   function Can_Eval_Value (Expr : Iir; Top : Boolean) return Boolean is +   begin +      --  Always evaluate scalar values. +      if Get_Kind (Get_Type (Expr)) in Iir_Kinds_Scalar_Type_Definition then +         return True; +      end if; +      return Can_Eval_Composite_Value (Expr, Top); +   end Can_Eval_Value; + +   --  For composite values. +   --  Evluating a composite value is a trade-off: it can simplify the +   --  generated code if the value is small enough, or it can be a bad idea if +   --  the value is very large.  It is very easy to create large static +   --  composite values (like: bit_vector'(1 to 10**4 => '0')) +   function Can_Eval_Composite_Value (Expr : Iir; Top : Boolean := False) +                                     return Boolean +   is +      --  We are only considering static values. +      pragma Assert (Get_Expr_Staticness (Expr) = Locally); + +      --  We are only considering composite types. +      pragma Assert (Get_Kind (Get_Type (Expr)) +                       not in Iir_Kinds_Scalar_Type_Definition); +   begin +      case Get_Kind (Expr) is +         when Iir_Kind_Type_Conversion +           | Iir_Kind_Qualified_Expression => +            return Can_Eval_Composite_Value (Get_Expression (Expr)); +         when Iir_Kinds_Denoting_Name => +            return Can_Eval_Composite_Value (Get_Named_Entity (Expr), Top); +         when Iir_Kind_Constant_Declaration => +            --  Pass through names only for small values. +            if Top or else not Is_Small_Composite_Value (Expr) then +               return False; +            else +               return Can_Eval_Composite_Value (Get_Default_Value (Expr)); +            end if; +         when Iir_Kind_Attribute_Name => +            if Top or else not Is_Small_Composite_Value (Expr) then +               return False; +            else +               return Can_Eval_Composite_Value +                 (Get_Attribute_Name_Expression (Expr)); +            end if; +         when Iir_Kinds_Dyadic_Operator => +            --  Concatenation can increase the size. +            --  Others (rol, ror...) don't. +            return Can_Eval_Value (Get_Left (Expr), False) +              and then Can_Eval_Value (Get_Right (Expr), False); +         when Iir_Kinds_Monadic_Operator => +            --  For not. +            return Can_Eval_Composite_Value (Get_Operand (Expr)); +         when Iir_Kind_Aggregate => +            return Is_Small_Composite_Value (Expr); +         when Iir_Kinds_Literal +           | Iir_Kind_Enumeration_Literal +           | Iir_Kind_Simple_Aggregate +           | Iir_Kind_Image_Attribute +           | Iir_Kind_Simple_Name_Attribute => +            return True; +         when Iir_Kind_Overflow_Literal => +            return True; +         when Iir_Kind_Function_Call => +            --  Either using post-fixed notation or implicit functions like +            --  to_string. +            --  Cannot be a user function (won't be locally static). +            declare +               Assoc : Iir; +               Assoc_Expr : Iir; +            begin +               Assoc := Get_Parameter_Association_Chain (Expr); +               while Is_Valid (Assoc) loop +                  case Iir_Kinds_Association_Element (Get_Kind (Assoc)) is +                     when Iir_Kind_Association_Element_By_Expression => +                        Assoc_Expr := Get_Actual (Assoc); +                        if not Can_Eval_Value (Assoc_Expr, False) then +                           return False; +                        end if; +                     when Iir_Kind_Association_Element_Open => +                        null; +                     when Iir_Kind_Association_Element_By_Individual => +                        return False; +                  end case; +                  Assoc := Get_Chain (Assoc); +               end loop; +               return True; +            end; + +         when others => +            --  Be safe, don't crash on unhandled expression. +            --  Error_Kind ("can_eval_composite_value", Expr); +            return False; +      end case; +   end Can_Eval_Composite_Value; +     function Eval_Expr_If_Static (Expr : Iir) return Iir is     begin        if Expr /= Null_Iir and then Get_Expr_Staticness (Expr) = Locally then -         --  Evaluate only scalar expressions. -         if Get_Kind (Get_Type (Expr)) in Iir_Kinds_Scalar_Type_Definition then +         --  Evaluate only when there is a positive effect. +         if Can_Eval_Value (Expr, True) then              return Eval_Expr_Keep_Orig (Expr, False);           else              return Expr; diff --git a/src/vhdl/iirs_utils.adb b/src/vhdl/iirs_utils.adb index 4664f8dfa..5d407a3e6 100644 --- a/src/vhdl/iirs_utils.adb +++ b/src/vhdl/iirs_utils.adb @@ -1278,6 +1278,15 @@ package body Iirs_Utils is        end case;     end Is_Entity_Instantiation; +   function Get_Attribute_Name_Expression (Name : Iir) return Iir +   is +      Attr_Val : constant Iir := Get_Named_Entity (Name); +      Attr_Spec : constant Iir := Get_Attribute_Specification (Attr_Val); +      Attr_Expr : constant Iir := Get_Expression (Attr_Spec); +   begin +      return Attr_Expr; +   end Get_Attribute_Name_Expression; +     function Get_String_Type_Bound_Type (Sub_Type : Iir) return Iir is     begin        if Get_Kind (Sub_Type) /= Iir_Kind_Array_Subtype_Definition then diff --git a/src/vhdl/iirs_utils.ads b/src/vhdl/iirs_utils.ads index dace93c3c..39d56a8ff 100644 --- a/src/vhdl/iirs_utils.ads +++ b/src/vhdl/iirs_utils.ads @@ -267,6 +267,10 @@ package Iirs_Utils is       (Inst : Iir_Component_Instantiation_Statement)       return Boolean; +   --  Get the expression of the attribute specification corresponding to the +   --  attribute name NAME.  Meaningful only for static values. +   function Get_Attribute_Name_Expression (Name : Iir) return Iir; +     --  Return the bound type of a string type, ie the type of the (first)     --  dimension of a one-dimensional array type.     function Get_String_Type_Bound_Type (Sub_Type : Iir) return Iir; diff --git a/src/vhdl/sem_expr.adb b/src/vhdl/sem_expr.adb index 63cd7de6c..6b7624358 100644 --- a/src/vhdl/sem_expr.adb +++ b/src/vhdl/sem_expr.adb @@ -3338,7 +3338,12 @@ package body Sem_Expr is        end if;        --  Analyze aggregate elements. -      Expr_Staticness := Locally; +      if Constrained then +         Expr_Staticness := Get_Type_Staticness (Index_Type); +      else +         Expr_Staticness := Locally; +      end if; +        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). | 
