Issue 230712.3: Object Components Promoted to Registers

Author: Ron Brender
Champion: Ron Brender
Date submitted: 2023-07-12
Date revised:
Date closed:
Type: Concept
Status: Open
DWARF Version: 6

Part III: Object Components Promoted to Registers

Introduction

One key problem presented in the proposals for allowing location descriptors as stack entries is that current DWARF provides no way to describe an object whose value is allocated in separate parts. The following seeks to directly model the structure of an optimized variable when one or more of its components may sometimes be promoted to registers.

Concept Proposal

Introduce a new DW_TAG_object_part DIE. One or more DW_TAG_object_part DIEs may occur as children of an object having a structure/union/class type. Each object part DIE corresponds to a part of its parent object that may sometimes be allocated separately from its parent (commonly in a register).

Note that an object part DIE is a child of a specific object, not of the type of the object. It is expected that each object instance may potentially have multiple distinct object parts.

An object part DIE necessarily has the following attributes:

The lifetime of the object part is limited by the lifetime of the parent object. If the lifetime is less, then an implicit default location from the corresponding parent member applies.

No other attributes are defined for DW_TAG_object_part.

Discussion

One way to think about this is that an object part supersedes or replaces the data member allocation of the type of the object that contains it. An object may have more than one object part child applying to distinct data members.

Example

Type REC is record
    COMP1 : integer;
    COMP2 : float;
End;

Fig 1: A simple record

1$: DW_TAG_structure_type
    DW_AT_name(“REC)
2$:     DW_TAG_member
    DW_AT_name(“COMP1”)
    DW_AT_type(reference to integer)
    DW_AT_location(constant 0)
3$:     DW_TAG_member
    DW_AT_name(“COMP2”)
    DW_AT_type(reference to integer)
    DW_AT_location(constant 8)

4$: DW_TAG_variable
    DW_AT_name(“VAR”)
    DW_AT_type(ref 1$)
    DW_AT_location(address for VAR)
    DW_TAG_object_part
    DW_AT_part(ref 2$)
    DW_AT_parent(ref 4$)
    DW_AT_location(DW_OP_reg0)    ! COMP1 allocated in R0
                      ! COMP2 allocated in memory

Fig 2: DWARF for A Simple Record

Variations

There are several levels of complexity that can be considered:

Variation 1: Limit object parts to “simple types” (basically non-composite types):

Allow only the following possible types for DW_TAG_object_part DIEs:

Variation 2: Allow record types that can be wholly allocated in registers

In addition to variation 1, allow the DW_TAG_object_part to have a structure/union/class type all of whose components have DW_AT_data_member_regsec attributes. In this case, the location of the object part must begin on a register boundary (have a regsec value with a position component of zero).

Variation 3: Allow record types generally

In addition to variation 2, allow all record types. In this case, the DW_TAG_object_part itself has children consisting of DW_TAG_object_part DIEs corresponding to every component of that type. The DW_AT_location attribute may be omitted, in which case the base location of the structure defaults in the usual way.