Effect.xcc
Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechin@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.
EffectFlag— Enumerates the Effect flags.
- Side Effect(s)
- not in the Operation arguments or results.
- Indirect Effect(s)
- special cases for latency computations.
typedef enum { EffectFlag_Read = 0x0, // Effect is a read to the target resource. EffectFlag_Write = 0x1, // Effect is a write to the target resource. EffectFlag_Kill = 0x2, // Effect is a write that kills the previous value. EffectFlag_Clobber = 0x4, // Effect is a clobber: creates an undefined value. EffectFlag_Indirect = 0x8, // Effect is indirect: from Label or Control. EffectFlag_Carried = 0x10, // Effect is loop-carried read or partial def. EffectFlag_Supplied = 0x20, // Effect is in the supplied dependence set. EffectFlag_InTrace = 0x40, // Effect is indirect in the same BlockTrace. } enum_EffectFlag; typedef uint8_t EffectFlags;
Effect— Action of an Operation on a processor resource.
An effect materializes a read or a write on a state-holding processor resource (register, control, memory, etc.) represented as a Temporary.
An Effect is a side effect when its XXXINDEX is negative. Else the XXXINDEX is either the ARGINDEX or the RESINDEX, depending on the position in Operation.
struct Effect_ { //@args Operation operation, Temporary temporary, EffectFlags flags, int index //@access NEXT (Effect)(IDListItem_NEXT(this)) Operation OPERATION; // The Operation that creates this Effect. Temporary TEMPORARY; // The Temporary this Effect applies to. int16_t XXXINDEX; // Index in the Operation_xxxEFFECTS. //@access isSide (Effect_XXXINDEX(this) < 0) EffectFlags FLAGS; // This Effect flags. //@access isRead ((Effect_FLAGS(this) & EffectFlag_Write) == 0) //@access isWrite ((Effect_FLAGS(this) & EffectFlag_Write) != 0) //@access isKill ((Effect_FLAGS(this) & EffectFlag_Kill) != 0) //@access isClobber ((Effect_FLAGS(this) & EffectFlag_Clobber) != 0) //@access isIndirect ((Effect_FLAGS(this) & EffectFlag_Indirect) != 0) //@access isCarried ((Effect_FLAGS(this) & EffectFlag_Carried) != 0) //@access isSupplied ((Effect_FLAGS(this) & EffectFlag_Supplied) != 0) //@access isInTrace ((Effect_FLAGS(this) & EffectFlag_InTrace) != 0) int8_t RELAXABLE; // The amount of inductive relaxation applicable. struct Lifetime_ *LIFETIME; // The Lifetime this Effect belongs to. struct Effect_ *PRED; // Dependence predecessor of this Effect. struct Effect_ *SUCC; // Dependence successor of this Effect. };
Effect_pretty— Pretty-print this Effet.
bool Effect_pretty(Effect this, FILE *file);
Effect_operation— This Effect Operation.
static inline Operation Effect_operation(Effect this) { return Effect_OPERATION(this); }
Effect_temporary— This Effect Temporary.
static inline Temporary Effect_temporary(Effect this) { return Effect_TEMPORARY(this); }
Effect_setFlags— Set this Effect flags.
static inline void Effect_setFlags(Effect this, unsigned flags) { *Effect__FLAGS(this) |= flags; }
Effect_clearFlags— Reset this Effect flags.
static inline void Effect_clearFlags(Effect this, unsigned flags) { *Effect__FLAGS(this) &= ~flags; }
Effect_getRegisterRAWLatency— Get the Register RAW latency between two effects.
int Effect_getRegisterRAWLatency(Effect this, Effect that, Processor processor, int extra);
Effect_getRegisterExtraWARLatency— The Register extra WAR latency between two effects.
Add an extra cycle to the WAR latency for operations that are positioned late in an issue group like control-flow operations. This prevents the scheduler to produce semantic invalid issue groups like:
[0] CMP $b1 = ... [0] BR $b1, target
Here, Operation BR actually gets the old $b1 but it appears to get the new $b1.
static inline int Effect_getRegisterExtraWARLatency(Effect this) { Operation this_operation = Effect_OPERATION(this); Operator this_operator = Operation_operator(this_operation); return Operator_isControl(this_operator); }
Effect_getRegisterWARLatency— Get the Register WAR latency between two effects.
int Effect_getRegisterWARLatency(Effect this, Effect that, Processor processor);
Effect_getRegisterWAWLatency— Get the Register WAW latency between two effects.
int Effect_getRegisterWAWLatency(Effect this, Effect that, Processor processor);
Effect_getRegionFlowLatency— Get the Control FLow latency between two effects.
static inline int Effect_getRegionFlowLatency(Effect this, Effect that, Processor processor) { // Control operations are positioned last in an issue group, so latency must be > 0. return 1; }
Effect_getControlAntiLatency— Get the Control Anti latency between two effects.
static inline int Effect_getControlAntiLatency(Effect this, Effect that, Processor processor) { // TODO return 0; }
Effect_getControlOutputLatency— Get the Control Output latency between two effects.
static inline int Effect_getControlOutputLatency(Effect this, Effect that, Processor processor) { Operation this_operation = Effect_OPERATION(this); Operation that_operation = Effect_OPERATION(that); if (Operator_isFall(Operation_operator(this_operation))) return 0; if (Operator_isFall(Operation_operator(that_operation))) return 0; // TODO return 1; }
Effect_getMemoryFlowLatency— Get the Memory FLow latency between two effects.
int Effect_getMemoryFlowLatency(Effect this, Effect that, Processor processor);
Effect_getMemoryAntiLatency— Get the Memory Anti latency between two effects.
int Effect_getMemoryAntiLatency(Effect this, Effect that, Processor processor);
Effect_getMemoryOutputLatency— Get the Memory Output latency between two effects.
int Effect_getMemoryOutputLatency(Effect this, Effect that, Processor processor);
EffectSeq— Sequence of effects on a particular Temporary.
struct EffectSeq_ { //@args Memory memory, int32_t estimate IStack_ ISTACK_; // Stack of Effect(s). //@access ISTACK EffectSeq__ISTACK_(this) //@access COUNT (IStack_usedSize(EffectSeq_ISTACK(this))/sizeof(Effect)) //@access MEMORY IStack_memory(EffectSeq_ISTACK(this)) };
EffectSeq_istack— For use by EffectSeq_FOREACH_Effect.
static inline IStack EffectSeq_istack(EffectSeq this) { return EffectSeq_ISTACK(this); }
EffectSeq_FOREACH_Effect— Iterate over this EffectSeq Effect(s).
#define EffectSeq_FOREACH_Effect(this, effect) { \ IStack EffectSeq_ISTACK = EffectSeq_istack(this); \ IStack_FOREACH(EffectSeq_ISTACK, Effect, EffectSeq__EFFECT) { \ Effect effect = *EffectSeq__EFFECT; #define EffectSeq_ENDEACH_Effect \ } IStack_ENDEACH; \ }
EffectTable— Tabulate the Effect(s) by Operation.
The purpose of an EffectTable is to tabulate the Effect(s) of a sequence of Operation(s), for use in local optimizations. When an Operation is entered into an EffectTable, its side Effect(s) are computed if requested.
struct EffectTable_ { //@args Memory memory, Procedure procedure, int32_t estimate IStack_ OPERATIONS_; // This EffectTable Operation(s). //@access OPERATIONS EffectTable__OPERATIONS_(this) //@access MEMORY IStack_memory(EffectTable_OPERATIONS(this)) //@access COUNT (IStack_usedSize(EffectTable_OPERATIONS(this))/sizeof(Operation)) HTable_ EFFECTSEQS_; // Hash from Temporary to EffectSeq. //@access EFFECTSEQS EffectTable__EFFECTSEQS_(this) IDList_ SIDEEFFECTS_; //< This EffectTable list of side-Effect(s). //@access SIDEEFFECTS EffectTable__SIDEEFFECTS_(this) Procedure PROCEDURE; struct Temporary_ *DEDICATED_; };
EffectTable_operations— For use by EffectTable_FOREACH_Operation.
static inline IStack EffectTable_operations(EffectTable this) { return EffectTable_OPERATIONS(this); }
EffectTable_FOREACH_Operation— Iterate over this EffectTable Operation(s).
#define EffectTable_FOREACH_Operation(this, operation) { \ IStack EffectTable_OPERATIONS = EffectTable_operations(this); \ IStack_FOREACH(EffectTable_OPERATIONS, Operation, EffectTable__ITER) { \ Operation operation = *EffectTable__ITER; #define EffectTable_ENDEACH_Operation \ } IStack_ENDEACH; \ }
EffectTable_FORBACK_Operation— Iterate over this EffectTable Operation(s).
#define EffectTable_FORBACK_Operation(this, operation) { \ IStack EffectTable_OPERATIONS = EffectTable_operations(this); \ IStack_FORBACK(EffectTable_OPERATIONS, Operation, EffectTable__ITER) { \ Operation operation = *EffectTable__ITER; #define EffectTable_ENDBACK_Operation \ } IStack_ENDBACK; \ }
EffectTable_effectSeqs— For use by EffectTable_FOREACH_EffectSeq.
static inline HTable EffectTable_effectSeqs(EffectTable this) { return EffectTable_EFFECTSEQS(this); }
EffectTable_FOREACH_EffectSeq— Iterate over this EffectTable EffectSeq(s).
#define EffectTable_FOREACH_EffectSeq(this, effectSeq) { \ HTable EffectTable_EFFECTSEQS = EffectTable_effectSeqs(this); \ HTable_FOREACH(EffectTable_EFFECTSEQS, HTable_KEY, EffectSeq_, effectSeq) { \ Temporary EffectTable_TEMPORARY = (Temporary)HTable_KEY; #define EffectTable_ENDEACH_EffectSeq \ } HTable_ENDEACH; \ }
EffectTable_lookupEffectSeq— Return the EffectSeq associated to temporary.
EffectSeq EffectTable_lookupEffectSeq(EffectTable this, Temporary temporary);
EffectTable_enterRegisterSetSideEffects— Enter the side Effects of an Operation from a RegisterSet.
void EffectTable_enterRegisterSetSideEffects(EffectTable this, Operation operation, const_RegisterSet registerSet, EffectFlags flags);
EffectTable_enterTemporarySetSideEffects— Enter the side Effects of an Operation from a TemporarySet.
void EffectTable_enterTemporarySetSideEffects(EffectTable this, Operation operation, TemporarySet temporarySet, EffectFlags flags);
EffectTable_enterOperation— Enter an Operation into this EffectTable.
sideEffects
- If true, compute the operation side Effect(s).
void EffectTable_enterOperation(EffectTable this, Operation operation, bool sideEffects);