BlockTrace.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.

BlockTraceFlag— Enumerates the BlockTrace flags.
typedef enum {
  BlockTraceFlag_LoopBody = 0x1,        // This BlockTrace is a whole loop body.
  BlockTraceFlag_PrePass = 0x10 // This BlockTrace was made in pre-pass context.
} enum_BlockTraceFlag;
typedef uint8_t BlockTraceFlags;
BlockTrace— Region for instruction scheduling.

A BlockTrace results from the partition of a RegionFlow for the purposes of IF-conversion, instruction scheduling, register allocation, or object code layout. The different BlockTrace types are:

Operation maps, that use Operation_index to index arrays, are defined relative to a particular BlockTrace.

struct BlockTrace_ {
  //@args       Memory memory, OptimizeRegionType regionType, BlockTraceFlags traceFlags
  OptimizeRegionType REGIONTYPE;        // This BlockTrace type.
  //@access isInnerLoop ((BlockTrace_REGIONTYPE(this)&OptimizeRegionType_InnerLoop) != 0)
  //@access isAcyclic   ((BlockTrace_REGIONTYPE(this)&OptimizeRegionType_InnerLoop) == 0)
  BlockTraceFlags FLAGS;                // This BlockTrace flags.
  //@access isLoopBody  ((BlockTrace_FLAGS(this) & BlockTraceFlag_LoopBody) != 0)
  //@access isPrePass   ((BlockTrace_FLAGS(this) & BlockTraceFlag_PrePass) != 0)
  struct RegionFlow_ *REGIONFLOW;       // Encloding RegionFlow.
  //@access PROCEDURE   RegionFlow_procedure(BlockTrace_REGIONFLOW(this))
  //@access CODEREGION  RegionFlow_codeRegion(BlockTrace_REGIONFLOW(this))
  //@access OPTIMIZE    CodeRegion_optimize(BlockTrace_CODEREGION(this))
  CFGNode HEADNODE;             // Head CFGNode in this BlockTrace.
  CFGNode TAILNODE;             // Tail CFGNode in this BlockTrace.
  BasicBlock HEADBLOCK;         // Head BasicBlock in this BlockTrace.
  BasicBlock TAILBLOCK;         // Tail BasicBlock in this BlockTrace.
  PtrSet_ CFGNODES_;            // This BlockTrace CFGNodes.
  //@access CFGNODES    BlockTrace__CFGNODES_(this)
  //@access NODECOUNT   PtrSet_count(BlockTrace_CFGNODES(this))
  IssueItem FIRSTITEM;          // FIRST IssueItem of this BlockTrace.
  IssueItem STARTITEM;          // START IssueItem of this BlockTrace.
  IssueItem STOPITEM;           // STOP IssueItem of this BlockTrace.
  IssueItem LASTITEM;           // LAST IssueItem of this BlockTrace.
  IDList_ ISSUEITEMS_;          // This BlockTrace IssueItem list.
  //@access ISSUEITEMS  BlockTrace__ISSUEITEMS_(this)
  //@access ITEMCOUNT   IDList_count(BlockTrace_ISSUEITEMS(this))
  //@access MEMORY      IDList_memory(BlockTrace_ISSUEITEMS(this))
  PtrSet_ DDGNODES_;            // This BlockTrace Dependence nodes.
  //@access DDGNODES    BlockTrace__DDGNODES_(this)
  LoopScope LOOPSCOPE;          // The LoopScope for this BlockTrace.
  EffectTable EFFECTTABLE;      // The EffectTable of this BlockTrace.
  LifetimeTable LIFETIMETABLE;  // The LifetimeTable of this BlockTrace.
  OptimizeRCMSSolving SOLVING;
  uint16_t TIMEOUT;     // Time-out value for integer linear programming.
  int16_t LAMBDA;       // Loop initiation interval after loop scheduling or pipelining.
  int16_t LENGTH;       // Loop iteration length after loop scheduling or pipelining.
  int8_t FACTOR;        // The power of two unroll factor that satisfies kernel unrolling.
  int8_t KUNROLL;       // Kernel unrolling degree (non-zero only when loop is pipelined).
  Configure_ CONFIGURE_;        // Local copy of LOOPSCOPE CONFIGURE.
  //@access CONFIGURE   BlockTrace__CONFIGURE_(this)
  //@access PROCESSOR   Configure_PROCESSOR(BlockTrace_CONFIGURE(this))
  //@access COMPENSATION        Configure_COMPENSATION(BlockTrace_CONFIGURE(this))
  //@mutate COMPENSATION        Configure__COMPENSATION(BlockTrace_CONFIGURE(this))
  //@access SPECULATION Configure_SPECULATION(BlockTrace_CONFIGURE(this))
  //@mutate SPECULATION Configure__SPECULATION(BlockTrace_CONFIGURE(this))
  //@access RELAXATION  Configure_RELAXATION(BlockTrace_CONFIGURE(this))
  //@mutate RELAXATION  Configure__RELAXATION(BlockTrace_CONFIGURE(this))
  //@access RENAMING    Configure_RENAMING(BlockTrace_CONFIGURE(this))
  //@mutate RENAMING    Configure__RENAMING(BlockTrace_CONFIGURE(this))
  //@access BOOSTING    Configure_BOOSTING(BlockTrace_CONFIGURE(this))
  //@mutate BOOSTING    Configure__BOOSTING(BlockTrace_CONFIGURE(this))
  //@access ALIASING    Configure_ALIASING(BlockTrace_CONFIGURE(this))
  //@mutate ALIASING    Configure__ALIASING(BlockTrace_CONFIGURE(this))
  //@access PIPELINING  Configure_PIPELINING(BlockTrace_CONFIGURE(this))
  //@mutate PIPELINING  Configure__PIPELINING(BlockTrace_CONFIGURE(this))
  //@access PRELOADING  Configure_PRELOADING(BlockTrace_CONFIGURE(this))
  //@mutate PRELOADING  Configure__PRELOADING(BlockTrace_CONFIGURE(this))
  //@access L1MISSEXTRA Configure_L1MISSEXTRA(BlockTrace_CONFIGURE(this))
  //@mutate L1MISSEXTRA Configure__L1MISSEXTRA(BlockTrace_CONFIGURE(this))
  //@access OVERLAP     Configure_OVERLAP(BlockTrace_CONFIGURE(this))
  //@access isPipeline  (BlockTrace_PIPELINING(this) > 0)
};
BlockTrace_createSingleton— Create a BlockTrace containing a single basic block
BlockTrace
BlockTrace_createSingleton(Memory memory, RegionFlow regionFlow, CFGNode cfgNode,
                           LoopScope loopScope, OptimizeRegionType regionType,
                           BlockTraceFlags traceFlags);
BlockTrace_regionFlow— This BlockTrace RegionFlow
static inline RegionFlow
BlockTrace_regionFlow(BlockTrace this)
{
  return BlockTrace_REGIONFLOW(this);
}
BlockTrace_headNode— For use by BlockTrace_FOREACH_CFGNode.
static inline CFGNode
BlockTrace_headNode(BlockTrace this)
{
  return BlockTrace_HEADNODE(this);
}
BlockTrace_FOREACH_CFGNode— Iterate over this BlockTrace CFGNodes.
#define BlockTrace_FOREACH_CFGNode(this, node) { \
  CFGNode BlockTrace_HEADNODE = BlockTrace_headNode(this); \
  CFGNode BlockTrace_NODE = BlockTrace_HEADNODE; \
  while (BlockTrace_NODE != NULL) { \
    CFGNode node = BlockTrace_NODE; \
    BlockTrace_NODE = CFGNode_nextNode(BlockTrace_NODE);
#define BlockTrace_ENDEACH_CFGNode \
    if (BlockTrace_NODE == BlockTrace_HEADNODE) break; \
  } \
}
BlockTrace_cfgNodes— The CFGNode set of this BlockTrace.
static inline PtrSet
BlockTrace_cfgNodes(BlockTrace this)
{
  return BlockTrace_CFGNODES(this);
}
BlockTrace_issueItems— For use by BlockTrace_FOREACH_IssueItem.
static inline IDList
BlockTrace_issueItems(BlockTrace this)
{
  return BlockTrace_ISSUEITEMS(this);
}
BlockTrace_FOREACH_IssueItem— Iterate over this BlockTrace IssueItems.
#define BlockTrace_FOREACH_IssueItem(this, issueItem) \
  IDList_FOREACH(BlockTrace_issueItems(this), IssueItem_, issueItem) {
#define BlockTrace_ENDEACH_IssueItem \
  } IDList_ENDEACH;
BlockTrace_FORBACK_IssueItem— Iterate over this BlockTrace IssueItems.
#define BlockTrace_FORBACK_IssueItem(this, issueItem) \
  IDList_FORBACK(BlockTrace_issueItems(this), IssueItem_, issueItem) {
#define BlockTrace_ENDBACK_IssueItem \
  } IDList_ENDBACK;
BlockTrace_prettyIssueItems— Pretty-print this BlockTrace IssueItems.
//
bool
BlockTrace_prettyIssueItems(BlockTrace this, FILE *file);
BlockTrace_pretty— Pretty-print this BlockTrace.
//
bool
BlockTrace_pretty(BlockTrace this, FILE *file);
BlockTrace_isEmpty— True if this BlockTrace has no Operations.
bool
BlockTrace_isEmpty(BlockTrace this);
BlockTrace_getEnterFrequency— Get the frequency this BlockTrace is entered.
float
BlockTrace_getEnterFrequency(BlockTrace this);
BlockTrace_getLoopProbalility— Get the probalility this BlockTrace loops.
float
BlockTrace_getLoopProbalility(BlockTrace this);
BlockTrace_getDependenceTable— Return this BlockTrace DependenceTable.
const_DependenceTable
BlockTrace_getDependenceTable(const_BlockTrace this);
BlockTrace_normalizeRegionFlow— Normalize this BlockTrace control-flow.
Return
True if middle CFGNodes were discarded.
bool
BlockTrace_normalizeRegionFlow(BlockTrace this);
BlockTrace_prepareScheduling— Prepare this BlockTrace for scheduling.

The BlockTrace is normalized to ensure the following conditions: * Case of block scheduling and loop scheduling: the FIRST node of the DDGraph is the first LABEL operation, and the LAST node is the last operation, which is a FALL if there was no control operation. * Case of software pipelining: the FIRST node of the DDGraph is the first LABEL operation, and the LAST node is an unconditional branch to the loop header. All other branches must be conditional GOTO operations.

void
BlockTrace_prepareScheduling(BlockTrace this);
BlockTrace_enterOperations— Enter Operations into this BlockTrace region.

Sets the BlockTrace_FIRSTITEM, BlockTrace_STARTITEM, BlockTrace_STOPITEM Operations, and BlockTrace_LASTITEM. Also fill the BlockTrace_DDGNODES.

void
BlockTrace_enterOperations(BlockTrace this);
BlockTrace_relaxConstraints— Relax scheduling constraints with speculation.
void
BlockTrace_relaxConstraints(BlockTrace this);
BlockTrace_buildEffects— Build this BlockTrace_EFFECTTABLE.
void
BlockTrace_buildEffects(BlockTrace this);
BlockTrace_buildLifetimes— Build this BlockTrace_LIFETIMETABLE.
void
BlockTrace_buildLifetimes(BlockTrace this);
BlockTrace_sortIssueItems— Sort this BlockTrace IssueItems using InstructionTask_compare.
static inline void
BlockTrace_sortIssueItems(BlockTrace this)
{
  IDList_sort(BlockTrace_ISSUEITEMS(this), InstructionTask_compare);
}
BlockTrace_findInvariants— Find the loop-invariants.

According to Muchnich in "Compiler Design and Implementation", p. 398, loop-invariant operations are detected as follows: * Mark as loop-invariant the constant operands in the instructions. * Mark the operands that have all definitions that reach them located outside the loop. * Mark as loop-invariant instructions that: have all operands marked as loop-invariant; or operands have only one reaching definition, and that definition is an already marked loop-invariant instruction, and there are no uses of the variable assigned to by that instruction in the loop located before the instruction.

void
BlockTrace_findInvariants(BlockTrace this);
BlockTrace_computeKunroll— Compute this BlockTrace_KUNROLL.

As a side-effect, compute the Lifetime_LIFESPAN.

int
BlockTrace_computeKunroll(BlockTrace this, int lambda);
RegionFlowCover— Cover a RegionFlow with BlockTraces.
struct RegionFlowCover_;
RegionFlowCover_blockTraces— For use by RegionFlowCover_FOREACH_BlockTrace.
IDList
RegionFlowCover_blockTraces(RegionFlowCover this);
RegionFlowCover_FOREACH_BlockTrace— Iterate this RegionFlowCover BlockTraces.
#define RegionFlowCover_FOREACH_BlockTrace(this, blockTrace) \
  IDList_FOREACH(RegionFlowCover_blockTraces(this), BlockTrace_, blockTrace)
#define RegionFlowCover_ENDEACH_BlockTrace \
  IDList_ENDEACH;