From bdc1c9cf6db576e585d60e531da14a4c8d72333d Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 7 Apr 2023 21:04:43 +0200 Subject: translation: improve type conversion (recurse) --- src/vhdl/translate/trans-chap5.adb | 2 +- src/vhdl/translate/trans-chap7.adb | 198 ++++++++++++++++++++++--------------- src/vhdl/translate/trans-chap7.ads | 2 +- 3 files changed, 120 insertions(+), 82 deletions(-) diff --git a/src/vhdl/translate/trans-chap5.adb b/src/vhdl/translate/trans-chap5.adb index 2c91f36f2..59cdc41c3 100644 --- a/src/vhdl/translate/trans-chap5.adb +++ b/src/vhdl/translate/trans-chap5.adb @@ -649,7 +649,7 @@ package body Trans.Chap5 is Res_Type := Get_Type (Get_Association_Interface (Assoc, Inter)); Bounds := Get_Actual_Bounds (False); Res := Alloc_Bounds (Res_Type, Alloc_System); - Chap7.Translate_Type_Conversion_Bounds + Chap7.Translate_Type_Conversion_Array_Bounds (Res, Bounds, Res_Type, Actual_Type, Assoc); return Res; end Get_Unconstrained_Port_Bounds; diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb index 237643133..3192fe305 100644 --- a/src/vhdl/translate/trans-chap7.adb +++ b/src/vhdl/translate/trans-chap7.adb @@ -4519,74 +4519,8 @@ package body Trans.Chap7 is end case; end Translate_Allocator_By_Subtype; - function Translate_Fat_Array_Type_Conversion - (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) - return O_Enode; - - function Translate_Array_Subtype_Conversion - (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) - return O_Enode - is - Res_Info : constant Type_Info_Acc := Get_Info (Res_Type); - Expr_Info : constant Type_Info_Acc := Get_Info (Expr_Type); - E : Mnode; - begin - E := Stabilize (E2M (Expr, Expr_Info, Mode_Value)); - case Res_Info.Type_Mode is - when Type_Mode_Bounded_Arrays => - Chap3.Check_Composite_Match - (Res_Type, T2M (Res_Type, Mode_Value), - Expr_Type, E, - Loc); - return New_Convert_Ov - (M2Addr (Chap3.Get_Composite_Base (E)), - Res_Info.Ortho_Ptr_Type (Mode_Value)); - when Type_Mode_Unbounded_Array => - declare - Res : Mnode; - begin - Res := Create_Temp (Res_Info); - Copy_Fat_Pointer (Res, E); - Chap3.Check_Composite_Match (Res_Type, Res, Expr_Type, E, Loc); - return M2Addr (Res); - end; - when others => - Error_Kind ("translate_array_subtype_conversion", Res_Type); - end case; - end Translate_Array_Subtype_Conversion; - - function Translate_Type_Conversion - (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) - return O_Enode - is - Res_Info : constant Type_Info_Acc := Get_Info (Res_Type); - Res : O_Enode; - begin - case Get_Kind (Res_Type) is - when Iir_Kinds_Scalar_Type_And_Subtype_Definition => - Res := New_Convert_Ov (Expr, Res_Info.Ortho_Type (Mode_Value)); - if Chap3.Need_Range_Check (Null_Iir, Res_Type) then - Res := Chap3.Insert_Scalar_Check - (Res, Null_Iir, Res_Type, Loc); - end if; - return Res; - when Iir_Kinds_Array_Type_Definition => - if Get_Constraint_State (Res_Type) = Fully_Constrained then - return Translate_Array_Subtype_Conversion - (Expr, Expr_Type, Res_Type, Loc); - else - return Translate_Fat_Array_Type_Conversion - (Expr, Expr_Type, Res_Type, Loc); - end if; - when Iir_Kind_Record_Type_Definition - | Iir_Kind_Record_Subtype_Definition => - return Expr; - when others => - Error_Kind ("translate_type_conversion", Res_Type); - end case; - end Translate_Type_Conversion; - - procedure Translate_Type_Conversion_Bounds + -- Convert the bounds of an array (and only the bounds). + procedure Translate_Type_Conversion_Array_Bounds (Res : Mnode; Src : Mnode; Res_Type : Iir; Src_Type : Iir; Loc : Iir) is Res_Indexes : constant Iir_Flist := Get_Index_Subtype_List (Res_Type); @@ -4597,21 +4531,18 @@ package body Trans.Chap7 is Get_Index_Subtype_List (Res_Base_Type); Src_Base_Indexes : constant Iir_Flist := Get_Index_Subtype_List (Src_Base_Type); - - R_El : Iir; - S_El : Iir; begin -- Convert bounds. for I in Flist_First .. Flist_Last (Src_Indexes) loop - R_El := Get_Index_Type (Res_Indexes, I); - S_El := Get_Index_Type (Src_Indexes, I); declare - Rb_Ptr : Mnode; - Sb_Ptr : Mnode; - Ee : O_Enode; + Res_Idx : constant Iir := Get_Index_Type (Res_Indexes, I); + Src_Idx : constant Iir := Get_Index_Type (Src_Indexes, I); Same_Index_Type : constant Boolean := (Get_Index_Type (Res_Base_Indexes, I) = Get_Index_Type (Src_Base_Indexes, I)); + Rb_Ptr : Mnode; + Sb_Ptr : Mnode; + Ee : O_Enode; begin Open_Temp; Rb_Ptr := Stabilize (Chap3.Bounds_To_Range (Res, Res_Type, I + 1)); @@ -4621,12 +4552,12 @@ package body Trans.Chap7 is -- array in common cases). Ee := M2E (Chap3.Range_To_Left (Sb_Ptr)); if not Same_Index_Type then - Ee := Translate_Type_Conversion (Ee, S_El, R_El, Loc); + Ee := Translate_Type_Conversion (Ee, Src_Idx, Res_Idx, Loc); end if; New_Assign_Stmt (M2Lv (Chap3.Range_To_Left (Rb_Ptr)), Ee); Ee := M2E (Chap3.Range_To_Right (Sb_Ptr)); if not Same_Index_Type then - Ee := Translate_Type_Conversion (Ee, S_El, R_El, Loc); + Ee := Translate_Type_Conversion (Ee, Src_Idx, Res_Idx, Loc); end if; New_Assign_Stmt (M2Lv (Chap3.Range_To_Right (Rb_Ptr)), Ee); -- Copy Dir and Length. @@ -4637,7 +4568,51 @@ package body Trans.Chap7 is Close_Temp; end; end loop; - end Translate_Type_Conversion_Bounds; + + -- TODO: element layout + -- array: same sizes, bounds: recurse; but constrained states can be + -- different. + -- record: no conversion, simply copy ? + declare + Res_El_Type : constant Iir := Get_Element_Subtype (Res_Type); + Src_El_Type : constant Iir := Get_Element_Subtype (Src_Type); + Res_El : Mnode; + Src_El : Mnode; + begin + if Is_Fully_Constrained_Type (Res_El_Type) + and then Is_Fully_Constrained_Type (Src_El_Type) + then + -- No need to convert. + -- TODO: still check matching length (if not same type). + return; + end if; + + -- TODO: if the subtype is fully bounded, get the subtype bounds + -- directly (and not from the object bounds). + Res_El := Stabilize + (Chap3.Array_Bounds_To_Element_Layout (Res, Res_Type)); + Src_El := Stabilize + (Chap3.Array_Bounds_To_Element_Layout (Src, Src_Type)); + + if Res_El_Type = Src_El_Type then + -- TODO: copy layout, no need to check. + raise Internal_Error; + else + -- TODO: copy or convert. + -- 1. Copy layout size + for K in Object_Kind_Type loop + New_Assign_Stmt (Chap3.Layout_To_Size (Res_El, K), + New_Value (Chap3.Layout_To_Size (Res_El, K))); + end loop; + + -- 2. Recurse on bounds + Translate_Type_Conversion_Array_Bounds + (Stabilize (Chap3.Layout_To_Bounds (Res_El)), + Stabilize (Chap3.Layout_To_Bounds (Src_El)), + Res_El_Type, Src_El_Type, Loc); + end if; + end; + end Translate_Type_Conversion_Array_Bounds; function Translate_Fat_Array_Type_Conversion (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) @@ -4667,7 +4642,7 @@ package body Trans.Chap7 is New_Address (New_Obj (Bounds), Res_Info.B.Bounds_Ptr_Type)); -- Convert bounds. - Translate_Type_Conversion_Bounds + Translate_Type_Conversion_Array_Bounds (Dv2M (Bounds, Res_Info, Mode_Value, Res_Info.B.Bounds_Type, Res_Info.B.Bounds_Ptr_Type), Stabilize (Chap3.Get_Composite_Bounds (E)), @@ -4677,6 +4652,69 @@ package body Trans.Chap7 is return M2E (Res); end Translate_Fat_Array_Type_Conversion; + function Translate_Array_Subtype_Conversion + (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) + return O_Enode + is + Res_Info : constant Type_Info_Acc := Get_Info (Res_Type); + Expr_Info : constant Type_Info_Acc := Get_Info (Expr_Type); + E : Mnode; + begin + E := Stabilize (E2M (Expr, Expr_Info, Mode_Value)); + case Res_Info.Type_Mode is + when Type_Mode_Bounded_Arrays => + Chap3.Check_Composite_Match + (Res_Type, T2M (Res_Type, Mode_Value), + Expr_Type, E, + Loc); + return New_Convert_Ov + (M2Addr (Chap3.Get_Composite_Base (E)), + Res_Info.Ortho_Ptr_Type (Mode_Value)); + when Type_Mode_Unbounded_Array => + declare + Res : Mnode; + begin + Res := Create_Temp (Res_Info); + Copy_Fat_Pointer (Res, E); + Chap3.Check_Composite_Match (Res_Type, Res, Expr_Type, E, Loc); + return M2Addr (Res); + end; + when others => + Error_Kind ("translate_array_subtype_conversion", Res_Type); + end case; + end Translate_Array_Subtype_Conversion; + + function Translate_Type_Conversion + (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir) + return O_Enode + is + Res_Info : constant Type_Info_Acc := Get_Info (Res_Type); + Res : O_Enode; + begin + case Get_Kind (Res_Type) is + when Iir_Kinds_Scalar_Type_And_Subtype_Definition => + Res := New_Convert_Ov (Expr, Res_Info.Ortho_Type (Mode_Value)); + if Chap3.Need_Range_Check (Null_Iir, Res_Type) then + Res := Chap3.Insert_Scalar_Check + (Res, Null_Iir, Res_Type, Loc); + end if; + return Res; + when Iir_Kinds_Array_Type_Definition => + if Get_Constraint_State (Res_Type) = Fully_Constrained then + return Translate_Array_Subtype_Conversion + (Expr, Expr_Type, Res_Type, Loc); + else + return Translate_Fat_Array_Type_Conversion + (Expr, Expr_Type, Res_Type, Loc); + end if; + when Iir_Kind_Record_Type_Definition + | Iir_Kind_Record_Subtype_Definition => + return Expr; + when others => + Error_Kind ("translate_type_conversion", Res_Type); + end case; + end Translate_Type_Conversion; + function Sig2val_Prepare_Composite (Targ : Mnode; Targ_Type : Iir; Data : Mnode) return Mnode is diff --git a/src/vhdl/translate/trans-chap7.ads b/src/vhdl/translate/trans-chap7.ads index ac69c8893..f361eb87f 100644 --- a/src/vhdl/translate/trans-chap7.ads +++ b/src/vhdl/translate/trans-chap7.ads @@ -87,7 +87,7 @@ package Trans.Chap7 is (Res : in out Mnode; Expr : Mnode); -- Convert bounds SRC (of type SRC_TYPE) to RES (of type RES_TYPE). - procedure Translate_Type_Conversion_Bounds + procedure Translate_Type_Conversion_Array_Bounds (Res : Mnode; Src : Mnode; Res_Type : Iir; Src_Type : Iir; Loc : Iir); -- Convert range EXPR into ortho tree. -- cgit v1.2.3