Temporary.xcc

Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechinst.com) Christophe Guillon (Christophe.Guillonst.com) Nikola Puzovic (Nikola.Puzovic@st.com)

Copyright 2002 - 2007 STMicroelectronics. Copyright 1995 - 1998 Commissariat a l'Energie Atomique.

This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.

1. Temporary Types

1.1. Dedicated Temporary(ies)

Dedicated Temporary(ies) are immutable and used to represent Operation arguments or results that must be in specific machine registers. This applies to procedure register arguments and results an also to implicit or pinned register operands. In effect, using a Dedicated Temporary is an override for the register allocator on what Register to assign to a particular Temporary.

Temporary_hasRegFile is true for Dedicated Temporary(ies) Temporary_hasRegister is true for Dedicated Temporary(ies)

See the note below for more details on dedicated temporary usage.

1.2. Virtual Temporary(ies)

Virtual Temporary(ies) that are also known as pseudo-registers. They are used to carry values between Operation(s).

Temporary_hasRegFile is true for Virtual Temporary(ies) Temporary_hasRegister is valid for Virtual Temporary(ies)

1.3. Variable Temporary(ies)

Variable Temporary(ies) are base objects of Variable(s). They can be assigned a Register.

Temporary_hasRegFile is true for Variable Temporary(ies) Temporary_hasRegister is valid for Variable Temporary(ies)

1.4. Absolute Temporary(ies)

Absolute Temporary(ies) are used to represent resolved constants.

Temporary_isInvariant is true for Absolute Temporary(ies)

1.5. Label Temporary(ies)

Label Temporary(ies) are used for the arguments for intra-procedural branches. For inter-procedural branches, such as those that result from optimizing tail calls, including recursive tail call, Symbol Temporary(ies) must be used instead.

Temporary_isInvariant is true for Label Temporary(ies)

1.6. Symbol Temporary(ies)

Symbol Temporary(ies) are used to represent symbolic values made of a base Symbol plus an offset.

Temporary_isInvariant is true for Symbol Temporary(ies)

1.7. Modifier Temporary(ies)

Modifier Temporary(ies) are used to represent instruction modifiers.

Temporary_isInvariant is true for Modifier Temporary(ies)

1.8. RegMask Temporary(ies)

RegMask Temporary(ies) are placeholders for the immdiate values interpreted as register masks. During encoding, the value of the Instruction's register mask is computed from the Operation's additional arguments or results that are not Parameters.

Temporary_isInvariant is true for RegMask Temporary(ies)

1.9. Note on dedicated Temporary(ies)

It is a requirement for correctness to use dedicated temporaries in the following cases:

These requirements must be enforced before register allocation. After register allocation, the same requirements hold but the scope of the dedicated temporaries used for parameter passing can be extended out of the homing basic block.

1.10. Note on sharing Temporary(ies)

The Register Temporary(ies) should be shared between Operation(s). Other Temporary(ies) should be used by only one Operation. This can be relaxed for Temporary(ies) that are immutable like Absolute Temporary(ies), and also in case it is guaranteed all Operation(s) that share a non-Register Temporary do not update it. Updates are for instance changing the Relocation of the offset.

1.11. Note on Temporary Relocation(s)

Invariant Temporary(ies) have an associated Relocation. This Relocation is an enumeration that specifies additional processing or checking to be done on a resolved ImmediateValue before being passed to the Immediate encoding. Thus, processing done by a linker relocation combines the processing of Relocation with the Immediate encoding process.

Temporary_Factory— IndexedFactory for Temporary(ies).
extern IndexedFactory_ Temporary_Factory[1];
TemporaryType— Enumerates the Temporary types.
typedef enum {
  TemporaryType_Dedicated,              // Dedicated register.
                                        //      REGISTER is the Register.
                                        //      WIDTH is the bit-width if known.
  TemporaryType_Virtual,                // Virtual register.
                                        //      REGISTER is the first of RegFile.
                                        //      WIDTH is the bit-width if known.
  TemporaryType_Variable,               // Variable base.
                                        //      REGISTER is the first of RegFile.
                                        //      WIDTH is the bit-width if known.
  TemporaryType_Absolute,               // Absolute invariant.
                                        //      INVARIANT is the TemporaryInvariant.
  TemporaryType_Symbol,                 // Symbol invariant.
                                        //      INVARIANT is the TemporaryInvariant.
  TemporaryType_Label,                  // Label invariant.
                                        //      INVARIANT is the TemporaryInvariant.
  TemporaryType_Modifier,               // Modifier invariant.
                                        //      INVARIANT is the TemporaryInvariant.
  TemporaryType_RegMask,                // RegMask invariant.
  TemporaryType_Volatile,               // Volatile resource.
  TemporaryType_Control,                // Control resource.
  TemporaryType_Memory,                 // Memory resource.
  TemporaryType__
} enum_TemporaryType;
typedef uint8_t TemporaryType;
#define TemporaryType_isDedicated(type) ((type) == TemporaryType_Dedicated)
#define TemporaryType_isVirtual(type)   ((type) == TemporaryType_Virtual)
#define TemporaryType_isVariable(type)  ((type) == TemporaryType_Variable)
#define TemporaryType_isAbsolute(type)  ((type) == TemporaryType_Absolute)
#define TemporaryType_isSymbol(type)    ((type) == TemporaryType_Symbol)
#define TemporaryType_isLabel(type)     ((type) == TemporaryType_Label)
#define TemporaryType_isModifier(type)  ((type) == TemporaryType_Modifier)
#define TemporaryType_isRegMask(type)   ((type) == TemporaryType_RegMask)
#define TemporaryType_isVolatile(type)  ((type) == TemporaryType_Volatile)
#define TemporaryType_isControl(type)   ((type) == TemporaryType_Control)
#define TemporaryType_isMemory(type)    ((type) == TemporaryType_Memory)
#define TemporaryType_hasRegFile(type)  \
  ((unsigned)(type) <= TemporaryType_Variable)
#define TemporaryType_isInvariant(type) \
  (   (unsigned)((type) - TemporaryType_Absolute) \
   <= (unsigned)(TemporaryType_RegMask - TemporaryType_Absolute))
#define TemporaryType_isRelaxable(type) \
  (   (unsigned)((type) - TemporaryType_Absolute) \
   <= (unsigned)(TemporaryType_Symbol - TemporaryType_Absolute))
extern const char *
TemporaryType_name_(TemporaryType this);
TemporaryFlag— Enumerates the Temporary flags.
typedef enum {
  TemporaryFlag_Constant = 0x1,         // Temporary is constant.
  TemporaryFlag_Register = 0x2,         // Temporary has a Register.
  TemporaryFlag_Global = 0x4,           // Temporary is global in Liveness.
  TemporaryFlag_Killed = 0x8,           // Liveness flag, must be cleared after use.
  TemporaryFlag_Remater = 0x10,         // Register Temporary is rematerializable.
                                        //      Get Invariant Temporary in REMATERMAP.
  TemporaryFlag_Homeable = 0x20,        // Register Temporary is homeable.
                                        //      Get home Symbol Temporary in HOMEABLEMAP.
  TemporaryFlag_RenameOK = 0x40,        // Virtual Temporary can be SSA renamed.
  TemporaryFlag_Recycled = 0x80,        // Virtual Temporary is recycled by SSADestruct.
} enum_TemporaryFlag;
typedef uint8_t TemporaryFlags;
TemporaryUnion_— Union for the variant part of Temporary.
union TemporaryUnion_ {
  struct Variable_ *WEBROOT;            // TemporaryType_isVirtual.
  struct Variable_ *SPILLED;            // TemporaryType_isVariable.
};
typedef union TemporaryUnion_ TemporaryUnion_, *TemporaryUnion;
Temporary— Argument and result type for Operations.
struct Temporary_ {
  //@args       TemporaryType type, unsigned flags
  Indexed_ __;                          // A Temporary_ ISA Indexed_.
  //@access IDENTITY    Indexed_IDENTITY(Temporary____(this))
  //@access INDEX       Indexed_INDEX(Temporary____(this))
  //@mutate INDEX       Indexed__INDEX(Temporary____(this))
  TemporaryUnion_ UNION_;               // See TemporaryUnion.
  //@access WEBROOT     (Temporary_UNION_(this).WEBROOT)
  //@mutate WEBROOT     (&Temporary_UNION_(this).WEBROOT)
  //@access SPILLED     (Temporary_UNION_(this).SPILLED)
  //@mutate SPILLED     (&Temporary_UNION_(this).SPILLED)
  TemporaryType TYPE;                   // This Temporary type.
  //@access isDedicated TemporaryType_isDedicated(Temporary_type(this))
  //@access isVirtual   TemporaryType_isVirtual(Temporary_type(this))
  //@access isVariable  TemporaryType_isVariable(Temporary_type(this))
  //@access isAbsolute  TemporaryType_isAbsolute(Temporary_type(this))
  //@access isSymbol    TemporaryType_isSymbol(Temporary_type(this))
  //@access isLabel     TemporaryType_isLabel(Temporary_type(this))
  //@access isModifier  TemporaryType_isModifier(Temporary_type(this))
  //@access isRegMask   TemporaryType_isRegMask(Temporary_type(this))
  //@access isVolatile  TemporaryType_isVolatile(Temporary_type(this))
  //@access isControl   TemporaryType_isControl(Temporary_type(this))
  //@access isMemory    TemporaryType_isMemory(Temporary_type(this))
  //@access hasRegFile  TemporaryType_hasRegFile(Temporary_type(this))
  //@access isInvariant TemporaryType_isInvariant(Temporary_type(this))
  //@access isRelaxable TemporaryType_isRelaxable(Temporary_type(this))
  TemporaryFlags FLAGS;         // This Temporary flags.
  //@access isConstant  ((Temporary_flags(this) & TemporaryFlag_Constant) != 0)
  //@access hasRegister ((Temporary_flags(this) & TemporaryFlag_Register) != 0)
  //@access isGlobal    ((Temporary_flags(this) & TemporaryFlag_Global) != 0)
  //@access isKilled    ((Temporary_flags(this) & TemporaryFlag_Killed) != 0)
  //@access isRemater   ((Temporary_flags(this) & TemporaryFlag_Remater) != 0)
  //@access isHomeable  ((Temporary_flags(this) & TemporaryFlag_Homeable) != 0)
  //@access isRenameOK  ((Temporary_flags(this) & TemporaryFlag_RenameOK) != 0)
  //@access isRecycled  ((Temporary_flags(this) & TemporaryFlag_Recycled) != 0)
  //@access isAssigned  (Temporary_isVirtual(this) && Temporary_hasRegister(this))
  Register REGISTER;                    // The Register of this Temporary.
  //@access REGFILE     (Register_regFile(Temporary_REGISTER(this)))
  uint8_t WIDTH;                        // Width in bits of this Temporary.
  //@access isRenameReg (Temporary_hasRegFile(this) && !Temporary_isDedicated(this))
  //@access INVARIANT   (TemporaryInvariant)(this)
  //@access VARIABLE    (Variable)(this)
};
Temporary_identity— This Temporary identity.
static inline uint32_t
Temporary_identity(const_Temporary this)
{
  return Temporary_IDENTITY(this);
}
Temporary_index— This Temporary index.
static inline uint32_t
Temporary_index(const_Temporary this)
{
  return Temporary_INDEX(this);
}
Temporary_type— This Temporary TemporaryType.
static inline TemporaryType
Temporary_type(const_Temporary this)
{
  return Temporary_TYPE(this);
}
Temporary_flags— This Temporary TemporaryFlags.
static inline TemporaryFlags
Temporary_flags(const_Temporary this)
{
  return Temporary_FLAGS(this);
}
Temporary_setFlags— Set this Temporary flags.
static inline void
Temporary_setFlags(Temporary this, TemporaryFlags flags)
{
  *Temporary__FLAGS(this) |= flags;
}
Temporary_clearFlags— Clear this Temporary flags.
static inline void
Temporary_clearFlags(Temporary this, TemporaryFlags flags)
{
  *Temporary__FLAGS(this) &= ~flags;
}
Temporary_register— Returns register associated with Register Temporary.
Return
the Register, or Register__UNDEF for non-Register Temporary(ies).
static inline Register
Temporary_register(const_Temporary this)
{
  Except_CHECK(Temporary_hasRegister(this) || Temporary_REGISTER(this) == Register__UNDEF);
  return Temporary_REGISTER(this);
}
Temporary_regFile— Returns register file associated with Register Temporary.
Return
the Register, or RegFile__UNDEF for non-Register Temporary(ies).
static inline RegFile
Temporary_regFile(const_Temporary this)
{
  Except_CHECK(Temporary_hasRegFile(this) || Temporary_REGFILE(this) == RegFile__UNDEF);
  return Temporary_REGFILE(this);
}
TemporaryInvariantUnion_— Union for the variant part of Temporary.
union TemporaryInvariantUnion_ {
  void *POINTER;                        // Client pointer.
  Symbol SYMBOL;                        // TemporaryType_isSymbol.
  Label LABEL;                          // TemporaryType_isLabel.
  Modifier MODIFIER;                    // TemporaryType_isModifier.
};
typedef union TemporaryInvariantUnion_ TemporaryInvariantUnion_, *TemporaryInvariantUnion;
TemporaryInvariant— Extension of Temporary for Invariant Temporary(ies).
struct TemporaryInvariant_ {
  Temporary_ __;
  TemporaryInvariantUnion_ UNION_;
  //@access POINTER     (TemporaryInvariant_UNION_(this).POINTER)
  //@mutate POINTER     (&TemporaryInvariant_UNION_(this).POINTER)
  //@access SYMBOL      (TemporaryInvariant_UNION_(this).SYMBOL)
  //@mutate SYMBOL      (&TemporaryInvariant_UNION_(this).SYMBOL)
  //@access LABEL       (TemporaryInvariant_UNION_(this).LABEL)
  //@mutate LABEL       (&TemporaryInvariant_UNION_(this).LABEL)
  //@access MODIFIER    (TemporaryInvariant_UNION_(this).MODIFIER)
  //@mutate MODIFIER    (&TemporaryInvariant_UNION_(this).MODIFIER)
  Relocation RELOCATION;
  ImmediateValue VALUE;
  //@access OFFSET      TemporaryInvariant_VALUE(this)
  //@mutate OFFSET      TemporaryInvariant__VALUE(this)
  //@access MEMBER      TemporaryInvariant_VALUE(this)
  //@mutate MEMBER      TemporaryInvariant__VALUE(this)
};
TemporaryInvariant_label— This TemporaryInvariant Label.
static inline Label
TemporaryInvariant_label(const_TemporaryInvariant this)
{
  Except_CHECK(Temporary_isInvariant(TemporaryInvariant____(this)));
  return TemporaryInvariant_LABEL(this);
}
TemporaryInvariant_symbol— This TemporaryInvariant Symbol.
static inline Symbol
TemporaryInvariant_symbol(const_TemporaryInvariant this)
{
  Except_CHECK(Temporary_isInvariant(TemporaryInvariant____(this)));
  return TemporaryInvariant_SYMBOL(this);
}
TemporaryInvariant_value— This TemporaryInvariant value.
static inline ImmediateValue
TemporaryInvariant_value(const_TemporaryInvariant this)
{
  Except_CHECK(Temporary_isInvariant(TemporaryInvariant____(this)));
  return TemporaryInvariant_VALUE(this);
}
TemporaryInvariant_offset— This TemporaryInvariant offset.
static inline ImmediateValue
TemporaryInvariant_offset(const_TemporaryInvariant this)
{
  Except_CHECK(Temporary_isInvariant(TemporaryInvariant____(this)));
  return TemporaryInvariant_OFFSET(this);
}
TemporaryInvariant_relocation— This TemporaryInvariant relocation.
static inline Relocation
TemporaryInvariant_relocation(const_TemporaryInvariant this)
{
  Except_CHECK(Temporary_isInvariant(TemporaryInvariant____(this)));
  return TemporaryInvariant_RELOCATION(this);
}
Temporary_make— Low-level function to make a new Temporary.
static inline Temporary
Temporary_make(IBList idlist, TemporaryType type, TemporaryFlags flags)
{
  Temporary temporary = IBList_push(idlist);
  Temporary_Ctor(temporary, type, flags);
  return temporary;
}
Temporary_setDedicated— Force a Virtual Temporary to be dedicated.

Note that this function only exists because copy folding may have discarded a dedicated Temporary and replaced it by an Assigned Temporary. On the Open64 such copy folding breaks the invariant that procedure register arguments should be in Dedicated Temporary(ies). Calling Temporary_setDedicated cures the problem.

static inline void
Temporary_setDedicated(Temporary this)
{
  Except_CHECK(Temporary_isAssigned(this));
  *Temporary__TYPE(this) = TemporaryType_Dedicated;
}
Temporary_compare— Compare two Temporary(ies) for total ordering.
int
Temporary_compare(const_Temporary this, const_Temporary that);
Temporary_pretty— Pretty print of this Temporary.
bool
Temporary_pretty(const_Temporary this, FILE *file);
Temporary_isLifetime— True if the lifetime of this Temporary must be considered.
static inline bool
Temporary_isLifetime(Temporary this)
{
  Convention convention = Convention__DEFAULT;  // FIXME!
  return    Temporary_isVirtual(this)
         || (   Temporary_hasRegFile(this)
             && Register_isLifetime(Temporary_REGISTER(this), convention));
}
Temporary_assignRegister— Assign a Register to this Temporary.
void
Temporary_assignRegister(Temporary this, Register registre);
Temporary_unassignRegister— Un-assign this Temporary.
void
Temporary_unassignRegister(Temporary this);
Temporary_setWidth— Set the bit-width of this Register Temporary.
static inline void
Temporary_setWidth(Temporary this, unsigned width)
{
  *Temporary__WIDTH(this) = width;
}
TemporaryStack— Stack of Temporary(ies).
struct TemporaryStack_ {
  //@args       Memory memory, int maxCount
  PtrSeq_ __;           // Underlying PtrSeq.
};
TemporaryStack_FOREACH_Temporary— Iterate over this TemporaryStack Temporary(ies).
#define TemporaryStack_FOREACH_Temporary(this, temporary) { \
  const_PtrSeq TemporaryStack____ = TemporaryStack__const(this); \
  PtrSeq_FOREACH(TemporaryStack____, Temporary, temporary) {
#define TemporaryStack_ENDEACH_Temporary \
  } PtrSeq_ENDEACH \
}
TemporaryStack_FORBACK_Temporary— Iterate over this TemporaryStack Temporary(ies).
#define TemporaryStack_FORBACK_Temporary(this, temporary) { \
  const_PtrSeq TemporaryStack____ = TemporaryStack__const(this); \
  PtrSeq_FORBACK(TemporaryStack____, Temporary, temporary) {
#define TemporaryStack_ENDBACK_Temporary \
  } PtrSeq_ENDBACK \
}
TemporarySet— Set of Temporary(ies).
struct TemporarySet_ {
  //@args       Memory memory, int32_t estimate
  PtrSet_ __;           // The PtrSet_ that implements the set.
  //@access MEMORY      PtrSet_memory(TemporarySet____(this))
};
TemporarySet_FOREACH_Temporary— Iterate over this TemporarySet Temporary(ies).
#define TemporarySet_FOREACH_Temporary(this, temporary) { \
  const_PtrSet TemporarySet____ = TemporarySet__const(this); \
  PtrSet_FOREACH(TemporarySet____, Temporary, temporary) {
#define TemporarySet_ENDEACH_Temporary \
  } PtrSet_ENDEACH \
}
TemporarySet_FORSORT_Temporary— Iterate over this TemporarySet sorted Temporary(ies).
#define TemporarySet_FORSORT_Temporary(this, compare, temporary) { \
  const_PtrSet TemporarySet____ = TemporarySet__const(this); \
  PtrSet_FORSORT(TemporarySet____, compare, Temporary, temporary) {
#define TemporarySet_ENDSORT_Temporary \
  } PtrSet_ENDSORT \
}
TemporarySet_pretty— Pretty-print this TemporarySet.
bool
TemporarySet_pretty(TemporarySet this, FILE *file);
TemporarySet_display— Display this TemporarySet in VCG format.
bool
TemporarySet_display(TemporarySet this, FILE *file);
TemporaryTable— Specialization of IndexedTable for Temporary(ies).
struct TemporaryTable_ {
  //@args       Memory memory, int32_t estimate
  IndexedTable_ __;
  //@access MEMORY      IndexedTable_memory(TemporaryTable____(this))
  //@access COUNT       IndexedTable_count(TemporaryTable____(this))
  //@access BASE        (const Temporary *)IndexedTable_base(TemporaryTable____(this))
};
TemporaryTable_FOREACH_Temporary— Iterate this TemporaryTable Temporary(ies).
#define TemporaryTable_FOREACH_Temporary(this, temporary) { \
  IndexedTable_FOREACH_Indexed(TemporaryTable__const(this), \
                                   Temporary, temporary) { \
    int32_t TemporaryTable_Temporary_INDEX = IndexedTable_INDEX;
#define TemporaryTable_ENDEACH_Temporary \
  } IndexedTable_ENDEACH_Indexed; \
}
TemporarySparse— Sparse set of Temporary(ies) based on INDEX Sparse set.
struct TemporarySparse_ {
  //@args       Memory memory, TemporaryTable table
  IndexedSparse_ __;
  //@access MEMORY      IndexedSparse_memory(TemporarySparse____(this))
  //@access BASE        (const Temporary *)IndexedSparse_base(TemporarySparse____(this))
};
TemporarySparse_FOREACH_Temporary— Iterate this TemporarySparse Temporary(ies).
#define TemporarySparse_FOREACH_Temporary(this, temporary) { \
  IndexedSparse_FOREACH_Indexed(TemporarySparse__const(this), Temporary, temporary) { \
    int32_t TemporarySparse_POSITION = IndexedSparse_POSITION; \
    int32_t TemporarySparse_INDEX = IndexedSparse_INDEX;
#define TemporarySparse_ENDEACH_Temporary \
  } IndexedSparse_ENDEACH_Indexed; \
}
TemporaryMap— Map Temporary to user-defined object.

This map is based on the Temporary_INDEX fields, which must be properly initialized for instance by entering the Temporary(ies) in a TemporaryTable before the TemporaryMap is constructed.

struct TemporaryMap_ {
  //@args       Memory memory, int32_t maxCount, size_t itemSize
  Memory MEMORY;
  int32_t MAXCOUNT;
  size_t ITEMSIZE;
  void *BASE;
};
TemporaryMap_resize— Resize this TemporaryMap with a new maxCount.
void
TemporaryMap_resize(TemporaryMap this, int32_t maxCount);
TemporaryMap_resize— Resize this TemporaryMap memory.
void
TemporaryMap_release(TemporaryMap this, void (*release)(void * item));
TemporaryMap_base— For use in TemporaryMap_FOREACH.
static inline void *
TemporaryMap_base(TemporaryMap this)
{
  return TemporaryMap_BASE(this);
}
TemporaryMap_past— For use in TemporaryMap_FOREACH.
static inline void *
TemporaryMap_past(TemporaryMap this)
{
  char *base = TemporaryMap_BASE(this);
  int32_t maxCount = TemporaryMap_MAXCOUNT(this);
  size_t itemSize = TemporaryMap_ITEMSIZE(this);
  return base + maxCount*itemSize;
}
TemporaryMap_itemSize— For use in TemporaryMap_FOREACH.
static inline size_t
TemporaryMap_itemSize(TemporaryMap this)
{
  return TemporaryMap_ITEMSIZE(this);
}
TemporaryMap_FOREACH— Iterate over this TemporaryMap objects.
#define TemporaryMap_FOREACH(this, Type, iter) { \
  size_t TemporaryMap_ITEMSIZE = TemporaryMap_itemSize(this); \
  Type *TemporaryMap_BASE = (Type *)TemporaryMap_base(this); \
  Type *TemporaryMap_PAST = (Type *)TemporaryMap_past(this), *(iter); \
  for (iter = TemporaryMap_BASE; iter < TemporaryMap_PAST; ++(iter)) { \
    int32_t TemporaryMap_INDEX = iter - TemporaryMap_BASE;
#define TemporaryMap_ENDEACH \
  } \
}
TemporaryMap_access— Access the object mapped by the temporary.
void *
TemporaryMap_access(TemporaryMap this, Temporary temporary);