10    Object Annotation Data


Version Note

object annotation data is supported in Tru64 UNIX V5.1B and greater.


Object annotation data is stored in entries in the optimization symbols table with tag types in the range PPODE_ANNOT_RESERVED_FIRST to PPODE_ANNOT_RESERVED_LAST. The data contained in this collection of PPODE's is used to characterize register usage, call linkage, and other aspects of a procedure's text pertaining to calling standard conventions. This data identifies the level of compliance with coding conventions that enable post-link optimizations performed by the spike utility.

10.1    New or Changed Object Annotation Data Features

Tru64 UNIX V5.1B includes support for object annotation data as described by this chapter.

10.2    Structures, Fields, and Values for Object Annotation Data

All structure types and enumeration values described in this section are defined in the header files sym.h and symconst.h.

10.2.1    Annotation Summary Header

type struct {
        coff_uint       version : 8;
        coff_uint       safe_pc_usage : 1;
        coff_uint       safe_gp_usage : 1;
        coff_uint       safe_references : 1;
        coff_uint       safe_targets : 1;
        coff_uint       safe_frame : 1;
        coff_uint       safe_calls : 1;
        coff_uint       safe_linkage : 1;
        coff_uint       safe_floating_use : 1;
        coff_uint       arch : 8;
        coff_uint       tune : 8;
        coff_uint       os_version : 8;
        coff_uint       jump_table_annot : 1;
        coff_uint       reserved : 23;
} ANNOT_SUMMARY_VAL, *pANNOT_SUMMARY_VAL;

SIZE - 8 bytes, ALIGNMENT - 8

Annotation Summary Header Fields

version

Annotation summary version. This field contains the constant ANNOT_VERSION, currently defined as 1.

safe_pc_usage

PC values are only generated from standard linkage mechanisms, relocations, branch targets, or explicit reading of the PC via a branch to the next instruction in a GP reload sequence. Exceptions to this rule are annotated in exact sequences. This flag must be cleared if the exceptions are not annotated.

safe_gp_usage

GP is only accessed via instructions with relocations or explicit save/restore. This flag must be cleared if the procedure contains exceptions to this rule.

safe_references

References are not volatile. Explicit volatile accesses must be annotated as volatile or exact. This flag must be cleared if the exceptions are not annotated.

safe_targets

All relocated targets are not volatile, handler targets, uplevel referenced, etc., unless explicitly annotated. This flag must be cleared if the exceptions are not annotated. (Note, if a non-relocated target is somehow volatile, safe_pc_usage must be cleared.)

safe_frame

The procedure's stack frame is entirely private to the code for this procedure. There are no static links, $sp-derived accesses from callees, etc. If there are exceptions this flag must be cleared.

safe_calls

Calls use standard linkage (live in:$r16 through $r21 and $f16 through $f21; live out: $r0, $r1, $f0, and $f1; standard kill mask). Calls do not have abnormal flow, different $sp values on return, etc. Exceptions are annotated as restricted calls. If exceptions are not annotated this flag must be cleared. (There may or may not be additional annotations describing more detailed linkage information.)

safe_linkage

The procedure's entry and exit use standard linkage (live in:$r16 through $r21 and $f16 through $f21; live out: $r0, $r1, $f0, and $f1). The procedure has no specified or implemented callers with restricted linkages, and no results are passed on the stack. If there are exceptions this flag must be cleared.

safe_floating_use

The procedure may have floating point introduced where it doesn't already exist. If the code was compiled with the -nofloat option this flag must be cleared.

arch

The base architecture for the procedure (see Table 10-1). The -arch option is used to select the base architecture for a compilation (see cc(1)). Architecture choices are described in the Alpha Architecture Reference Manual.

tune

The base tuning for the procedure (see Table 10-1). The -tune option is used to select the base tuning for a compilation (see cc(1)).

os_version

The effective revision of Tru64 UNIX for which the procedure was compiled (see Table 10-2).

jump_table_annot

Indicates that all jump tables referenced by the procedure are annotated.

reserved

Must be zero.

Table 10-1:  Architecture and Tuning Values

Constant Value Description
ANNOT_ARCH_GENERIC 1 Generic Alpha system
ANNOT_ARCH_EV4 3 EV4 system
ANNOT_ARCH_EV5 4 EV5 system
ANNOT_ARCH_EV56 5 EV56 system
ANNOT_ARCH_PCA56 6 PCA56 system
ANNOT_ARCH_EV6 7 EV6 system
ANNOT_ARCH_EV67 8 EV67 system
ANNOT_ARCH_EV68 9 EV68 system
ANNOT_ARCH_EV69 10 EV69 system
ANNOT_ARCH_EV7 11 EV7 system

Table 10-2:  Object Annotation OS Revisions

Constant Value Description
ANNOT_OS_V30 2 Tru64 UNIX V3.0 or later
ANNOT_OS_V40 3 Tru64 UNIX V4.0 or later
ANNOT_OS_V50 4 Tru64 UNIX V5.0 or later
ANNOT_OS_V51 5 Tru64 UNIX V5.1 or later
ANNOT_OS_V51A 7 Tru64 UNIX V5.1A or later
ANNOT_OS_V51B 8 Tru64 UNIX V5.1B or later

10.2.2    Annotation Restricted Offset Flags

typedef struct {
        coff_uint       volatile_target : 1;
        coff_uint       handler_target : 1;
        coff_uint       nonlocal_referenced : 1;
        coff_uint       uplevel_referenced : 1;
        coff_uint       exception_fence : 1;
        coff_uint       soft_order : 1;
} ANNOT_RESTRICTED_OFFSET_FLAGS, *pANNOT_RESTRICTED_OFFSET_FLAGS;

SIZE - 1 byte, ALIGNMENT - 1

Annotation Restricted Offset Fields

volatile_target

Target of asynchronous transfer.

handler_target

Target of transfer from a handler, only.

nonlocal_referenced

Target of reference from another procedure.

uplevel_referenced

Target of reference from a contained procedure.

exception_fence

Target is an exception fence.

soft_order

Recommended ordering break (pipelining).

10.2.3    Annotation Restricted Instruction Flags

typedef struct {
        coff_uint       io_volatile : 1;
        coff_uint       must_read : 1;
        coff_uint       must_write : 1;
        coff_uint       preserve_exceptions : 1;
        coff_uint       no_exception : 1;
} ANNOT_RESTRICTED_INSTRUCTION_FLAGS, *pANNOT_RESTRICTED_INSTRUCTION_FLAGS;
 

SIZE - 1 byte, ALIGNMENT - 1

Annotation Restricted Instruction Fields

io_volatile

Memory accesses must be treated as volatile.

must_read

All inputs (both register and memory) must be read if used.

must_write

All outputs (both register and memory) must be written for potential use in exception handling. (Exception states may be collapsed.)

preserve_exceptions

Potential exceptions are relevant.

no_exception

No exceptions are possible for this instruction.

10.2.4    Annotation Restricted Sequence Flags

typedef struct {
        coff_uint       nomove : 1;
        coff_uint       noreorder : 1;
        coff_uint       noschedule : 1;
        coff_uint       reserved : 5;
        coff_uint       arch : 8;
        coff_uint       tune : 8;
} ANNOT_RESTRICTED_SEQUENCE_FLAGS, *pANNOT_RESTRICTED_SEQUENCE_FLAGS;

SIZE - 3 bytes, ALIGNMENT - 1

Annotation Restricted Sequence Fields

nomove

The instructions in this sequence must remain in order.

noreorder

No instructions may be reordered relative to this sequence.

noschedule

Strong recommendation to avoid modifying this hand-tuned instruction sequence.

reserved

Must be zero.

arch

The base architecture for the procedure (see Table 10-1). The -arch option is used to select the base architecture for this instruction sequence (see cc(1)). Architecture choices are described in the Alpha Architecture Reference Manual.

tune

The base tuning for this instruction sequence (see Table 10-1). The -tune option is used to select the base tuning for a compilation (see cc(1)).

10.2.5    Annotation Restricted Call Flags

typedef struct {
        coff_uint       extra_inputs : 1;
        coff_uint       extra_outputs : 1;
        coff_uint       extra_kill : 1;
        coff_uint       nonstandard_flow : 1;
        coff_uint       stack_return : 1;
} ANNOT_RESTRICTED_CALL_FLAGS, *pANNOT_RESTRICTED_CALL_FLAGS;

SIZE - 1 byte, ALIGNMENT - 1

Annotation Restricted Call Fields

extra_inputs

One or more non-standard register inputs.

extra_outputs

One or more non-standard register outputs.

extra_kill

Non-standard scratch registers are killed.

nonstandard_flow

May return asynchronously (setjmp).

stack_return

The stack pointer on input may not match the stack pointer on return.

10.2.6    Annotation Restricted Entry Flags

typedef struct {
        coff_uint       extra_inputs : 1;
        coff_uint       nonstandard_save_kill : 1;
} ANNOT_RESTRICTED_ENTRY_FLAGS, *pANNOT_RESTRICTED_ENTRY_FLAGS;

SIZE - 1 byte, ALIGNMENT - 1

Annotation Restricted Entry Fields

extra_inputs

One or more non-standard register inputs.

nonstandard_save_kill

Non-standard scratch or preserved registers.

10.2.7    Annotation Restricted Return Flags

typedef struct {
        coff_uint       extra_outputs : 1;
        coff_uint       nonstandard_save_kill : 1;
} ANNOT_RESTRICTED_RETURN_FLAGS, *pANNOT_RESTRICTED_RETURN_FLAGS;

SIZE - 1 byte, ALIGNMENT - 1

Annotation Restricted Return Fields

extra_outputs

One or more non-standard register outputs.

nonstandard_save_kill

Non-standard scratch or preserved registers.

10.2.8    Annotation Linkage Flags

typedef struct {
        coff_uint       previous_masks : 1;
        coff_uint       must_not_inline : 1;
        coff_uint       requires_call : 1;
        coff_uint       abnormal_flow : 1;
} ANNOT_LINKAGE_FLAGS, *pANNOT_LINKAGE_FLAGS;

SIZE - 1 byte, ALIGNMENT - 1

Annotation Linkage Fields

previous_masks

Use masks from previous linkage description.

must_not_inline

Cannot be inlined.

requires_call

Call instruction cannot be replaced (e.g. can't be changed to a tailcall.)

abnormal_flow

Transfer to this linkage might not return.

10.3    Object Annotation Data Usage

Object annotation data contains offsets into a procedure's text and specific details about the procedure's instructions. If an object tool removes, adds, rearranges, or changes procedure text it must remove or update all optimization symbol table entries including the object annotation data.

All object annotation data will be contained in optimization symbol table entries in the range PPODE_ANNOT_RESERVED_FIRST to PPODE_ANNOT_RESERVED_LAST. This range is further divided into a range of restrictive annotations from PPODE_ANNOT_RESTRICTED_FIRST to PPODE_ANNOT_RESTRICTED_LAST and pure optimization annotations from PPODE_ANNOT_OPTIMIZATION_FIRST to PPODE_ANNOT_OPTIMIZATION_LAST.

New annotations and annotation flags may be introduced that are not described here.

If a tool encounters an unknown restrictive annotation it must process the procedure as if it were unannotated. If a tool encounters an unknown restrictive annotation flag, it must treat the annotation as if all its flags were set.

Tools can ignore unknown optimization annotations and unknown optimization annotation flags.

Link-time text modification does not alter annotation data, because the link-time modifications replace instructions without affecting instruction offsets or attributes of the text that require annotations.

10.3.1    Representation of Object Annotation Data

Annotation data for a procedure must begin with a PPODE_ANNOT_SUMMARY, which must occur only once per procedure and before any other annotation PPODE's. All object annotation PPODE's except PPODE_ANNOT_SUMMARY contain variable length data represented in LEB 128 format. See Section 1.4.6 for a description of this data representation.

10.3.1.1    Object Annotation Summary

Each PPODE_ANNOT_SUMMARY entry consists of a single ANNOT_SUMMARY_VAL structure. This structure can be encoded as an immediate value in the PPODE's ppode_val field. See Section 10.2.1 for a description of the ANNOT_SUMMARY_VAL structure.

This structure includes a version field which will be incremented when new flags are added to annotation records and when new annotation types are added.

The arch and tune fields identify the default values for the compilation environment or the values set by the compilation options -arch and -tune. Hand-coded programs can set these values with assembly directives.

The os_version field identifies the release of Tru64 UNIX for which the procedure was compiled. This value can be used to test for the potential inclusion of release-specific compilation features. A compiler's release notes provide details on new features added for specific releases.

The safety flags are used to indicate that the procedure's text complies with a set of rules for "well-behaved" code, or that any exceptions to these rules are annotated with additional annotation PPODE's. For most compiler-generated code, it should be sufficient to record the annotation summary PPODE with all safety flags set and no additional annotations.

10.3.1.2    Restricted Offset Annotation

This annotation identifies targets in the procedure that may have restrictive properties. Live register sets, etc., must be computed by tools. In assembly source, labels occuring in a .set volatile region should have the volatile_target flag set.

The PPODE_ANNOT_RESTRICTED_OFFSET section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the instruction location within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_RESTRICTED_OFFSET_FLAGS structure that flags the restrictions. The structure is described in Section 10.2.2.

10.3.1.3    Restricted Instruction Annotation

This annotation identifies instructions with restrictive properties.

The io_volatile flag identifies a reference that must be preserved according to volatile semantics:

Note that the source and target registers of io_volatile memory references can be adjusted if the instructions aren't also marked with the must_read or must_write flags. io_volatile specifically applies to the memory being accessed. In assembly source, this is generated for all memory references in a .set volatile region. Non-memory reference instructions in a volatile region are not marked as volatile.

The PPODE_ANNOT_RESTRICTED_INSTRUCTION section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the instruction location within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_RESTRICTED_INSTRUCTION_FLAGS structure that flags the restrictions. The structure is described in Section 10.2.3.

10.3.1.4    Restricted Instruction Sequence Annotation

This annotation identifies instruction sequences with restrictive properties. The instructions inside this sequence must not be changed in any way. This annotation is commonly used for hand-tuned assembly source code that uses assembly directives such as .set noreorder, .set nomove, .arch, and .tune.

The PPODE_ANNOT_RESTRICTED_SEQUENCE section consists of an array of one or more records, each composed of three fields:

Field Type Description

SLEB

Offset. This field identifies the location within the procedure for the first instruction in the sequence. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the first instruction after the sequence identified by the previous record. (Instruction offsets are measured in 4-byte units.)

ULEB

Length. This field identifies the sequence length in instructions (4-byte units).

LEB

Flags. This field contains an ANNOT_RESTRICTED_SEQUENCE_FLAGS structure that flags the restrictions and architecture settings. The structure is described in Section 10.2.4.

10.3.1.5    Restricted Call Annotation

This annotation identifies restrictive properties of a call site.

The PPODE_ANNOT_RESTRICTED_CALL section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the location of a call site within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_RESTRICTED_CALL_FLAGS structure that flags the restrictions. The structure is described in Section 10.2.5.

10.3.1.6    Restricted Entry Annotation

This annotation identifies restrictive properties of an entry point.

The PPODE_ANNOT_RESTRICTED_ENTRY section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the location of an entry point within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_RESTRICTED_ENTRY_FLAGS structure that flags the restrictions. The structure is described in Section 10.2.6.

10.3.1.7    Restricted Return Annotation

This annotation identifies restrictive properties of a return instruction.

The PPODE_ANNOT_RESTRICTED_RETURN section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the location of a return instruction within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_RESTRICTED_RETURN_FLAGS structure that flags the restrictions. The structure is described in Section 10.2.7.

10.3.1.8    Jump Table Annotation

This annotation identifies jump tables used by a procedure. A jump table is an array of 32-bit GP-relative offsets to jump labels within a procedure.

The PPODE_ANNOT_GPREL32_JUMP_TABLE section consists of an array of one or more records, each composed of two fields:

Field Type Description

SLEB

Offset. This field identifies the location of an instruction with a relocation to the jump table. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Length. This field contains the size of the jump table in 4-byte units.

10.3.1.9    Call Specified Linkage Annotation

This annotation identifies the language specified linkage for a call at the source language level. In the absence of more specific information, this is what must be assumed by the caller.

The PPODE_ANNOT_CALL_SPECIFIED_LINKAGE section consists of an array of one or more linkage description records, each composed of either two or five fields:

Field Type Description

SLEB

Offset. This field identifies the location of an entry point or call site within the procedure. For the first record in this PPODE it gives the instruction offset relative to the procedure address as specified in the adr field of the PDR. For subsequent records the instruction offset is relative to the instruction identified by the previous record. (Instruction offsets are measured in 4-byte units.)

LEB

Flags. This field contains an ANNOT_LINKAGE_DESCRIPTION structure that describes properties of a linkage. The structure is described in Section 10.2.8.

The previous_masks field in the ANNOT_LINKAGE_DESCRIPTION structure is cleared when the following three mask fields are present in the record. When previous_masks is set, the mask values are the same as those used for the previous record in this same PPODE.

Note that registers not appearing in any mask are unused, not just preserved. Normally, standard linkage registers are preserved, but there can be special linkages where the register assumption of the caller is that the register is volatile. Unused registers can't be allocated in that case.

[LEB]

Read. This field contains the register mask for registers that are read by the linkage.

[LEB]

Written. This field contains the register mask for registers that are written by the linkage.

[LEB]

Preserved. This field contains the register mask for registers that are preserved by the linkage.

10.3.1.10    Entry Specified Linkage Annotation

This annotation describes the language specified linkage for the entry at the source language level. Any unknown callers may assume this about the entry. Note that this is not a description of the constraints the procedure must follow, but rather what callers may assume in general. Anything compiled with the procedure could use a more restricted linkage (see Section 10.3.1.9).

The PPODE_ANNOT_ENTRY_SPECIFIED_LINKAGE section consists of an array of linkage description records as described in Section 10.3.1.9

10.3.1.11    Entry Utilized Linkage Annotation

This annotation describes the linkage actually utilized by the union of all callers. This linkage may be more restrictive than the PPODE_ANNOT_ENTRY_SPECIFIED_LINKAGE. For example, callers that were compiled with the procedure may have been able to use some registers known to be preserved by the current implementation, even though they weren't preserved in the specified linkage.

If callers are modified to take advantage of the difference between the PPODE_ANNOT_ENTRY_UTILIZED_LINKAGE and the PPODE_ANNOT_ENTRY_IMPLEMENTED_LINKAGE (for example, by utilizing more registers across calls to the procedure) the PPODE_ANNOT_ENTRY_UTILIZED_LINKAGE must be updated, if it is still present.

The PPODE_ANNOT_ENTRY_UTILIZED_LINKAGE section consists of an array of linkage description records as described in Section 10.3.1.9

10.3.1.12    Entry Implemented Linkage Annotation

This annotation describes the linkage actually implemented by the code. This may be a more restrictive linkage than the caller utilized linkage. For example, callers may not have taken advantage of some properties of the implementation.

If the current procedure is modified to take advantage of the difference between the PPODE_ANNOT_ENTRY_IMPLEMENTED_LINKAGE and the PPODE_ANNOT_ENTRY_UTILIZED_LINKAGE (for example, by utilizing more registers in the procedure's code) the PPODE_ANNOT_ENTRY_IMPLEMENTED_LINKAGE must be updated, if it is still present.

The PPODE_ANNOT_ENTRY_IMPLEMENTED_LINKAGE section consists of an array of linkage description records as described in Section 10.3.1.9

10.3.1.13    Return Specified Linkage Annotation

This annotation describes the "live-out" results for a procedure. These are the registers written by the procedure that may be read by callers. If no annotation is present, it may be assumed that the union of specified return results for entry points to the procedure are the maximum live-out set. (Compilers are expected to annotate only the single entry point with the specified linkage.)

The PPODE_ANNOT_RETURN_SPECIFIED_LINKAGE section consists of an array of linkage description records as described in Section 10.3.1.9