From 43a0debd527b75eb564cad6bd47f5d5bb301dfad Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 19 Nov 2020 11:04:52 +0100 Subject: [PATCH] Enhance debug info for fixed-point types The Ada language supports fixed-point types as first-class citizens so they need to be described as-is in the debug info. We devised the langhook get_fixed_point_type_info for this purpose a few years ago, but it comes with a limitation for the representation of the scale factor that we would need to lift in order to be able to represent more fixed-point types. gcc/ChangeLog: * dwarf2out.h (struct fixed_point_type_info) : Turn numerator and denominator into a tree. * dwarf2out.c (base_type_die): In the case of a fixed-point type with arbitrary scale factor, call add_scalar_info on numerator and denominator to emit the appropriate attributes. gcc/ada/ChangeLog: * exp_dbug.adb (Is_Handled_Scale_Factor): Delete. (Get_Encoded_Name): Do not call it. * gcc-interface/decl.c (gnat_to_gnu_entity) : Tidy up and always use a meaningful description for arbitrary scale factors. * gcc-interface/misc.c (gnat_get_fixed_point_type_info): Remove obsolete block and adjust the description of the scale factor. --- gcc/ada/exp_dbug.adb | 32 ++------------------------- gcc/ada/gcc-interface/decl.c | 43 +++++++++--------------------------- gcc/ada/gcc-interface/misc.c | 14 ++---------- gcc/dwarf2out.c | 13 ++++++----- gcc/dwarf2out.h | 17 +++++--------- 5 files changed, 27 insertions(+), 92 deletions(-) diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb index c2e774140ff..dc6cd265af4 100644 --- a/gcc/ada/exp_dbug.adb +++ b/gcc/ada/exp_dbug.adb @@ -133,11 +133,6 @@ package body Exp_Dbug is -- Determine whether the bounds of E match the size of the type. This is -- used to determine whether encoding is required for a discrete type. - function Is_Handled_Scale_Factor (U : Ureal) return Boolean; - -- The argument U is the Small_Value of a fixed-point type. This function - -- determines whether the back-end can handle this scale factor. When it - -- cannot, we have to output a GNAT encoding for the corresponding type. - procedure Output_Homonym_Numbers_Suffix; -- If homonym numbers are stored, then output them into Name_Buffer @@ -594,27 +589,6 @@ package body Exp_Dbug is return Make_Null_Statement (Loc); end Debug_Renaming_Declaration; - ----------------------------- - -- Is_Handled_Scale_Factor -- - ----------------------------- - - function Is_Handled_Scale_Factor (U : Ureal) return Boolean is - begin - -- Keep in sync with gigi (see E_*_Fixed_Point_Type handling in - -- decl.c:gnat_to_gnu_entity). - - if UI_Eq (Numerator (U), Uint_1) then - if Rbase (U) = 2 or else Rbase (U) = 10 then - return True; - end if; - end if; - - return - (UI_Is_In_Int_Range (Norm_Num (U)) - and then - UI_Is_In_Int_Range (Norm_Den (U))); - end Is_Handled_Scale_Factor; - ---------------------- -- Get_Encoded_Name -- ---------------------- @@ -671,12 +645,10 @@ package body Exp_Dbug is Has_Suffix := True; - -- Fixed-point case: generate GNAT encodings when asked to or when we - -- know the back-end will not be able to handle the scale factor. + -- Fixed-point case: generate GNAT encodings when asked to if Is_Fixed_Point_Type (E) - and then (GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal - or else not Is_Handled_Scale_Factor (Small_Value (E))) + and then GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal then Get_External_Name (E, True, "XF_"); Add_Real_To_Buffer (Delta_Value (E)); diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index fa17ad9453f..a0f17b1aafc 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1743,24 +1743,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) gnu_type = make_signed_type (esize); - /* Try to decode the scale factor and to save it for the fixed-point - types debug hook. */ - - /* There are various ways to describe the scale factor, however there - are cases where back-end internals cannot hold it. In such cases, - we output invalid scale factor for such cases (i.e. the 0/0 - rational constant) but we expect GNAT to output GNAT encodings, - then. Thus, keep this in sync with - Exp_Dbug.Is_Handled_Scale_Factor. */ - /* When encoded as 1/2**N or 1/10**N, describe the scale factor as a binary or decimal scale: it is easier to read for humans. */ if (UI_Eq (Numerator (gnat_small_value), Uint_1) && (Rbase (gnat_small_value) == 2 || Rbase (gnat_small_value) == 10)) { - /* Given RM restrictions on 'Small values, we assume here that - the denominator fits in an int. */ tree base = build_int_cst (integer_type_node, Rbase (gnat_small_value)); tree exponent @@ -1773,29 +1761,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) base, exponent)); } - /* Default to arbitrary scale factors descriptions. */ - else + /* Use the arbitrary scale factor description. Note that we support + a Small_Value whose magnitude is larger than 64-bit even on 32-bit + platforms, so we unconditionally use a (dummy) 128-bit type. */ { - const Uint num = Norm_Num (gnat_small_value); - const Uint den = Norm_Den (gnat_small_value); + const Uint gnat_num = Norm_Num (gnat_small_value); + const Uint gnat_den = Norm_Den (gnat_small_value); + tree gnu_small_type = make_unsigned_type (128); + tree gnu_num = UI_To_gnu (gnat_num, gnu_small_type); + tree gnu_den = UI_To_gnu (gnat_den, gnu_small_type); - if (UI_Is_In_Int_Range (num) && UI_Is_In_Int_Range (den)) - { - tree gnu_num - = build_int_cst (integer_type_node, - UI_To_Int (Norm_Num (gnat_small_value))); - tree gnu_den - = build_int_cst (integer_type_node, - UI_To_Int (Norm_Den (gnat_small_value))); - scale_factor = build2 (RDIV_EXPR, integer_type_node, - gnu_num, gnu_den); - } - else - /* If compiler internals cannot represent arbitrary scale - factors, output an invalid scale factor so that debugger - don't try to handle them but so that we still have a type - in the output. Note that GNAT */ - scale_factor = integer_zero_node; + scale_factor + = build2 (RDIV_EXPR, gnu_small_type, gnu_num, gnu_den); } TYPE_FIXED_POINT_P (gnu_type) = 1; diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 87724af814e..d0867e00c85 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -628,16 +628,6 @@ gnat_get_fixed_point_type_info (const_tree type, /* We expect here only a finite set of pattern. See fixed-point types handling in gnat_to_gnu_entity. */ - /* Put invalid values when compiler internals cannot represent the scale - factor. */ - if (scale_factor == integer_zero_node) - { - info->scale_factor_kind = fixed_point_scale_factor_arbitrary; - info->scale_factor.arbitrary.numerator = 0; - info->scale_factor.arbitrary.denominator = 0; - return true; - } - if (TREE_CODE (scale_factor) == RDIV_EXPR) { tree num = TREE_OPERAND (scale_factor, 0); @@ -677,8 +667,8 @@ gnat_get_fixed_point_type_info (const_tree type, && TREE_CODE (den) == INTEGER_CST); info->scale_factor_kind = fixed_point_scale_factor_arbitrary; - info->scale_factor.arbitrary.numerator = tree_to_uhwi (num); - info->scale_factor.arbitrary.denominator = tree_to_shwi (den); + info->scale_factor.arbitrary.numerator = num; + info->scale_factor.arbitrary.denominator = den; return true; } diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 54eb445665c..ea2a22a3042 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -12973,18 +12973,19 @@ base_type_die (tree type, bool reverse) break; case fixed_point_scale_factor_arbitrary: - /* Arbitrary scale factors cannot be described in standard DWARF, - yet. */ + /* Arbitrary scale factors cannot be described in standard DWARF. */ if (!dwarf_strict) { /* Describe the scale factor as a rational constant. */ const dw_die_ref scale_factor = new_die (DW_TAG_constant, comp_unit_die (), type); - add_AT_unsigned (scale_factor, DW_AT_GNU_numerator, - fpt_info.scale_factor.arbitrary.numerator); - add_AT_int (scale_factor, DW_AT_GNU_denominator, - fpt_info.scale_factor.arbitrary.denominator); + add_scalar_info (scale_factor, DW_AT_GNU_numerator, + fpt_info.scale_factor.arbitrary.numerator, + dw_scalar_form_constant, NULL); + add_scalar_info (scale_factor, DW_AT_GNU_denominator, + fpt_info.scale_factor.arbitrary.denominator, + dw_scalar_form_constant, NULL); add_AT_die_ref (base_type_result, DW_AT_small, scale_factor); } diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index 9571f8b4b10..0b06cff477b 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -362,23 +362,18 @@ enum fixed_point_scale_factor struct fixed_point_type_info { - /* A scale factor is the value one has to multiply with physical data in - order to get the fixed point logical data. The DWARF standard enables one - to encode it in three ways. */ + /* The scale factor is the value one has to multiply the actual data with + to get the fixed point value. We support three ways to encode it. */ enum fixed_point_scale_factor scale_factor_kind; union { - /* For binary scale factor, the scale factor is: 2 ** binary. */ + /* For a binary scale factor, the scale factor is 2 ** binary. */ int binary; - /* For decimal scale factor, the scale factor is: 10 ** binary. */ + /* For a decimal scale factor, the scale factor is 10 ** decimal. */ int decimal; - /* For arbitrary scale factor, the scale factor is: + /* For an arbitrary scale factor, the scale factor is the ratio numerator / denominator. */ - struct - { - unsigned HOST_WIDE_INT numerator; - HOST_WIDE_INT denominator; - } arbitrary; + struct { tree numerator; tree denominator; } arbitrary; } scale_factor; }; -- 2.30.2