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:
- BasicBlock A single BasicBlock.
- SuperBlock A linear string of BasicBlocks, without side entries.
- TraceBlock A linear string of BasicBlocks, with side entries.
- HyperBlock A single entry acyclic region for IF-convresion.
- BasicInner A BasicBlock inner loop.
- SuperInner A SuperBlock inner loop.
- TraceInner A TraceBlock inner loop.
- HyperInner A HyperBlock inner loop.
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;