This is the mail archive of the dwarf2@corp.sgi.com mailing list for the dwarf2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: 991108.11 Fortran 90 arrays - a couple of questions


> It occurs to me that one change that might be helpful would be to change
> the F90 example in Appendix 6 to use a descriptor with separate element
> stride and scale factor such as you used in your questions. Would that be,
> of itself, a reasonable way to remove all doubt?

Yes, I think that would be a good idea. My original example was not correct.
It should have been:
 
program main

   type t_1
     integer a
     real b
   end type

   type(t_1), target, dimension(3,2) :: s_1
   integer, pointer, dimension(:,:) :: x

   x => s_1%a         ! (1)

end program main

There are two issues regarding the use of DW_AT_stride that this example
might clarify:
 
a) For pointers to arrays where the distance between successive elements of
an 
   array is different from the actual element size as defined by the element

   type DIE.
b) For Multi-dimensional arrays, where the distance between successive
elements 
   along a given dimension is required.

The pointer assignment at (1) is such that the array descriptor for x will
hold the following information:

   base_address
   scale_factor = 8 bytes
   lower_bound_1 = 1, upper_bound_1 = 3, multiplier_1 = 1
   lower_bound_2 = 1, upper_bound_2 = 2, multiplier_2 = 3

whilst the element size of the array type is 4 bytes (integer base type). 

The address of x(i,j) is calculated from:

address of x(i,j) = base_address 
                    + [ multiplier_1*(i - lower_bound_1) 
                    +   multiplier_2*(j - lower_bound_2) ]*scale_factor

In my understanding, the Dwarf entries for the array type for x are:

<1><  242>      DW_TAG_base_type
                DW_AT_byte_size             4
                DW_AT_encoding              DW_ATE_signed
                DW_AT_name                  integer
<1><  261>      DW_TAG_array_type
                DW_AT_sibling               <300>
                DW_AT_associated            DW_OP_push_object_address 
                                            DW_OP_deref DW_OP_lit0 DW_OP_ne
                DW_AT_data_location         DW_OP_push_object_address 
                                            DW_OP_deref
                DW_AT_type                  <242>
<2><  278>      DW_TAG_subrange_type
                DW_AT_lower_bound           DW_OP_push_object_address
DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! lower_bound_1)
                                            DW_OP_plus
                                            DW_OP_deref
                DW_AT_upper_bound           DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! upper_bound_1) 
                                            DW_OP_plus
                                            DW_OP_deref
                DW_AT_stride                DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! multiplier_1)

                                            DW_OP_plus DW_OP_deref

                                            DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          ! offset(desc,
                                                          ! scale_factor)
                                            DW_OP_plus DW_OP_deref DW_OP_mul
<2><  278>      DW_TAG_subrange_type
                DW_AT_lower_bound           DW_OP_push_object_address
DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! lower_bound_2)
                                            DW_OP_plus
                                            DW_OP_deref

                DW_AT_upper_bound           DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! upper_bound_2) 
                                            DW_OP_plus
                                            DW_OP_deref
                DW_AT_stride                DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          !
offset(desc,dims) +
                                                          ! offset(dims_str,

                                                          ! multiplier_2)

                                            DW_OP_plus DW_OP_deref

                                            DW_OP_push_object_address 
	                                      DW_OP_lit<n>  ! where n == 
                                                          ! offset(desc,
                                                          ! scale_factor)
                                            DW_OP_plus DW_OP_deref DW_OP_mul

Where the DW_AT_stride expressions result in the number of bytes between
successive elements along the given dimension, 

stride_1 = multiplier_1*scale_factor, 
stride_2 = multiplier_2*scale_factor.

So that the address of x(i,j) can be calculated as:

address of x(i,j) = base_address 
                    + stride_1*(i - lower_bound_1) 
                    + stride_2*(j - lower_bound_2)

Have I got the right interpretation of DW_AT_stride? 

N.B. I have used the DW_OP_lit<n> DW_OP_plus combination for ease of
comparison with the example in the draft specification. However, I believe
the number of DW_OP_lit<n> values are insufficient to cope with arrays with
several dimensions.

Regards
Martin Knott

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]