OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
DataDependenceGraph Class Reference

#include <DataDependenceGraph.hh>

Inheritance diagram for DataDependenceGraph:
Inheritance graph
Collaboration diagram for DataDependenceGraph:
Collaboration graph

Classes

struct  UndoData
 

Public Types

enum  AntidependenceLevel { NO_ANTIDEPS , INTRA_BB_ANTIDEPS , SINGLE_BB_LOOP_ANTIDEPS , ALL_ANTIDEPS }
 
enum  DumpFileFormat { DUMP_DOT , DUMP_XML }
 
enum  EdgeWeightHeuristics { EWH_HEURISTIC , EWH_REAL , EWH_DEFAULT = EWH_HEURISTIC }
 
- Public Types inherited from BoostGraph< MoveNode, DataDependenceEdge >
typedef std::set< MoveNode *, typename GraphNode::ComparatorNodeSet
 
typedef std::set< DataDependenceEdge *, typename GraphEdge::ComparatorEdgeSet
 
typedef MoveNode Node
 The (base) node type managed by this graph.
 
typedef DataDependenceEdge Edge
 The (base) edge type managed by this graph.
 
- Public Types inherited from GraphBase< GraphNode, GraphEdge >
typedef std::set< GraphNode *, typename GraphNode::ComparatorNodeSet
 
typedef std::set< GraphEdge *, typename GraphEdge::ComparatorEdgeSet
 
typedef GraphNode Node
 Node type of this graph (possibly, a base class).
 
typedef GraphEdge Edge
 Edge type of this graph (possibly, a base class).
 

Public Member Functions

 DataDependenceGraph (std::set< TCEString > allParamRegs, const TCEString &name="", AntidependenceLevel antidependenceLevel=ALL_ANTIDEPS, BasicBlockNode *ownedBBN=NULL, bool containsProcedure=false, bool noLoopEdges=false)
 
virtual ~DataDependenceGraph ()
 
const BasicBlockNodegetBasicBlockNode (const MoveNode &mn) const
 
BasicBlockNodegetBasicBlockNode (MoveNode &mn)
 
void setBasicBlockNode (const MoveNode &mn, BasicBlockNode &bbn)
 
int programOperationCount () const
 
ProgramOperationprogramOperation (int index)
 
const ProgramOperationprogramOperation (int index) const
 
ProgramOperationPtr programOperationPtr (int index)
 
DataDependenceEdgeonlyRegisterEdgeIn (MoveNode &mn) const
 
DataDependenceEdgeonlyRegisterEdgeOut (MoveNode &mn) const
 
void addNode (MoveNode &moveNode)
 
void addNode (MoveNode &moveNode, MoveNode &relatedNode)
 
void addNode (MoveNode &moveNode, BasicBlockNode &bblock)
 
void addProgramOperation (ProgramOperationPtr po)
 
void dropProgramOperation (ProgramOperationPtr po)
 
int edgeLatency (const DataDependenceEdge &edge, int ii, const MoveNode *tail, const MoveNode *head) const
 
int earliestCycle (const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegWaRs=false, bool ignoreRegWaWs=false, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false, bool assumeBypassing=false) const
 
int latestCycle (const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegAntideps=false, bool ignoreUnscheduledSuccessors=true, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false) const
 
bool hasUnscheduledSuccessors (const MoveNode &mn) const
 
bool hasUnscheduledPredecessors (const MoveNode &mn) const
 
int smallestCycle () const
 
int largestCycle () const
 
int scheduledNodeCount () const
 
NodeSet unscheduledMoves () const
 
NodeSet scheduledMoves () const
 
NodeSet movesAtCycle (int cycle) const
 
MoveNodeonlyGuardDefOfMove (MoveNode &moveNode)
 
MoveNodelastGuardDefMove (MoveNode &moveNode)
 
NodeSet guardDefMoves (const MoveNode &moveNode)
 
MoveNodelastScheduledRegisterRead (const TTAMachine::BaseRegisterFile &rf, int registerIndex, int lastCycleToTest=INT_MAX) const
 
NodeSet lastScheduledRegisterReads (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
NodeSet lastScheduledRegisterGuardReads (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
NodeSet lastScheduledRegisterWrites (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
MoveNodefirstScheduledRegisterRead (const TTAMachine::BaseRegisterFile &rf, int registerIndex, int firstCycleToTest=0) const
 
MoveNodefirstScheduledRegisterWrite (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
NodeSet firstScheduledRegisterWrites (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
NodeSet firstScheduledRegisterReads (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
MoveNodelastScheduledRegisterKill (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
MoveNodefirstScheduledRegisterKill (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
int lastRegisterCycle (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
int firstRegisterCycle (const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
 
void sanityCheck () const
 
virtual TCEString dotString () const
 Dot printing related methods.
 
virtual void setCycleGrouping (bool flag)
 
virtual void setProgramOperationNodes (bool flag)
 
void writeToXMLFile (std::string fileName) const
 
bool mergeAndKeepAllowed (MoveNode &sourceNode, MoveNode &userNode)
 
TCEString removeRAWEdges (MoveNode &sourceNode, MoveNode &userNode)
 
bool isLoopBypass (MoveNode &sourceNode, MoveNode &userNode)
 
bool mergeAndKeepUser (MoveNode &resultNode, MoveNode &userNode, bool force=false)
 
bool mergeAndKeepSource (MoveNode &resultNode, MoveNode &userNode, bool force=false)
 
void unMergeUser (MoveNode &resultNode, MoveNode &mergedNode, bool loopBypass=false)
 
void guardConverted (MoveNode &guardSrc, MoveNode &dst)
 
void guardRestored (MoveNode &guardSrc, MoveNode &dst)
 
bool resultUsed (MoveNode &resultNode)
 
bool resultUsed (MoveNode &resultNode, MoveNode *regCopy)
 
void removeNode (MoveNode &node)
 
void deleteNode (MoveNode &node)
 
void setEdgeWeightHeuristics (EdgeWeightHeuristics ewh)
 
int edgeWeight (DataDependenceEdge &e, const MoveNode &hNode) const
 
bool predecessorsReady (MoveNode &node) const
 
bool successorsReady (MoveNode &node) const
 
bool otherSuccessorsScheduled (MoveNode &node, const NodeSet &ignoredNodes) const
 
void setMachine (const TTAMachine::Machine &machine)
 
const TTAMachine::Machinemachine () const
 
bool connectOrDeleteEdge (const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
 
DataDependenceGraphcreateSubgraph (NodeSet &nodes, bool includeLoops=false)
 
DataDependenceGraphcreateSubgraph (TTAProgram::CodeSnippet &cs, bool includeLoops=false)
 
DataDependenceGraphcreateSubgraph (std::list< TTAProgram::CodeSnippet * > &codeSnippets, bool includeLoops=false)
 
DataDependenceGraphtrueDependenceGraph (bool removeMemAntideps=true, bool ignoreMemDeps=false)
 
DataDependenceGraphcriticalPathGraph ()
 
DataDependenceGraphmemoryDependenceGraph ()
 
MoveNodenodeOfMove (const TTAProgram::Move &move)
 
void dropBackEdges ()
 
void fixInterBBAntiEdges (BasicBlockNode &bbn1, BasicBlockNode &bbn2, bool loopEdges)
 
void copyDependencies (const MoveNode &src, MoveNode &dst, bool ignoreSameBBBackedges, bool moveOverLoopEdge=true)
 
void copyIncomingGuardEdges (const MoveNode &src, MoveNode &dst)
 
void copyOutgoingGuardWarEdges (const MoveNode &src, MoveNode &dst)
 
NodeSet guardRawPredecessors (const MoveNode &node) const
 
DataDependenceEdgeonlyIncomingGuard (const MoveNode &mn) const
 
MoveNodeonlyRegisterRawSource (const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
 
NodeSet onlyRegisterRawDestinations (const MoveNode &mn, bool allowGuardEdges=false, bool allowBackEdges=false) const
 
std::map< DataDependenceEdge *, MoveNode *, DataDependenceEdge::ComparatoronlyRegisterRawDestinationsWithEdges (const MoveNode &mn, bool allowBackEdges) const
 
NodeSet regWarSuccessors (const MoveNode &node) const
 
NodeSet regRawSuccessors (const MoveNode &node) const
 
NodeSet regWawSuccessors (const MoveNode &node) const
 
NodeSet regDepSiblings (const MoveNode &mn) const
 
NodeSet regRawPredecessors (const MoveNode &node, int backedges=0) const
 
void createRegisterAntiDependenciesBetweenNodes (NodeSet &nodes)
 
bool exclusingGuards (const MoveNode &mn1, const MoveNode &mn2) const
 
bool sameGuards (const MoveNode &mn1, const MoveNode &mn2) const
 
int rWarEdgesOut (MoveNode &mn)
 
int regRawSuccessorCount (const MoveNode &mn, bool onlyScheduled)
 
bool guardsAllowBypass (const MoveNode &defNode, const MoveNode &useNode, bool loopBypass=false)
 
const MoveNodeonlyRegisterRawAncestor (const MoveNode &node, const std::string &sp) const
 
EdgeSet copyDepsOver (MoveNode &node, bool anti, bool raw)
 
void copyDepsOver (MoveNode &node1, MoveNode &node2, bool anti, bool raw)
 
void combineNodes (MoveNode &node1, MoveNode &node2, MoveNode &destination)
 
std::pair< MoveNode *, MoveNode * > findLoopLimitAndIndex (MoveNode &jumpMove)
 
std::pair< MoveNode *, int > findLoopIndexUpdate (MoveNode *indexMove)
 
MoveNodefindLoopIndexInit (MoveNode &updateMove)
 
bool writesJumpGuard (const MoveNode &moveNode)
 
void moveFUDependenciesToTrigger (MoveNode &trigger)
 
LiveRangefindLiveRange (MoveNode &lrNode, bool writingNode, bool guardUseNode) const
 
MoveNodefindLimitingAntidependenceSource (MoveNode &mn)
 
MoveNodefindLimitingAntidependenceDestination (MoveNode &mn)
 
DataDependenceGraph::UndoData sourceRenamed (MoveNode &mn)
 
DataDependenceGraph::UndoData guardRenamed (MoveNode &mn)
 
DataDependenceGraph::UndoData destRenamed (MoveNode &mn)
 
void renamedSimpleLiveRange (MoveNode &src, MoveNode &dest, MoveNode &antidepPoint, DataDependenceEdge &lrEdge, const TCEString &oldReg, const TCEString &newReg)
 
void copyExternalInEdges (MoveNode &nodeCopy, const MoveNode &source)
 
void copyExternalOutEdges (MoveNode &nodeCopy, const MoveNode &source)
 
DataDependenceGraph::EdgeSet updateRegWrite (const MoveNodeUse &mnd, const TCEString &reg, TTAProgram::BasicBlock &bb)
 
void updateRegUse (const MoveNodeUse &mnd, const TCEString &reg, TTAProgram::BasicBlock &bb)
 
void removeIncomingGuardEdges (MoveNode &node)
 
void removeOutgoingGuardWarEdges (MoveNode &node)
 
bool hasAllRegisterAntidependencies ()
 
bool hasSingleBBLoopRegisterAntidependencies ()
 
bool hasIntraBBRegisterAntidependencies ()
 
bool hasRegWaw (const MoveNodeUse &mnu, std::set< MoveNodeUse > targets) const
 
bool isNotAvoidable (const DataDependenceEdge &edge) const
 
bool isLoopInvariant (const MoveNode &mn) const
 
bool hasOtherRegWawSources (const MoveNode &mn) const
 
MoveNodefindBypassSource (const MoveNode &mn)
 
void copyIncomingRawEdges (const MoveNode &src, MoveNode &dst)
 
void fixAntidepsAfterLoopUnmergeUser (MoveNode &sourceNode, MoveNode &mergedNode, const TCEString &reg)
 
void setNodeBB (MoveNode &mn, BasicBlockNode &bblock, DataDependenceGraph *updater)
 
void undo (UndoData &undoData)
 
EdgeSet operationInEdges (const MoveNode &node) const
 
EdgeSet registerAndRAInEdges (const MoveNode &node) const
 
- Public Member Functions inherited from BoostGraph< MoveNode, DataDependenceEdge >
 BoostGraph (bool allowLoopEdges=true)
 
 BoostGraph (const TCEString &name, bool allowLoopEdges=true)
 
 BoostGraph (const BoostGraph &other, bool allowLoopEdges=true)
 
 ~BoostGraph ()
 
int nodeCount () const
 
int edgeCount () const
 
Nodenode (const int index) const
 
Nodenode (const int index, bool cacheResult) const
 
virtual Edgeedge (const int index) const
 
virtual EdgeoutEdge (const Node &node, const int index) const
 
virtual EdgeinEdge (const Node &node, const int index) const
 
virtual EdgeSet outEdges (const Node &node) const
 
virtual EdgeSet inEdges (const Node &node) const
 
virtual EdgeSet rootGraphOutEdges (const Node &node) const
 
virtual EdgeSet rootGraphInEdges (const Node &node) const
 
virtual EdgerootGraphInEdge (const Node &node, const int index) const
 
virtual EdgerootGraphOutEdge (const Node &node, const int index) const
 
virtual int rootGraphInDegree (const Node &node) const
 
virtual int rootGraphOutDegree (const Node &node) const
 
virtual int outDegree (const Node &node) const
 
virtual int inDegree (const Node &node) const
 
virtual NodetailNode (const Edge &edge) const
 
virtual NodeheadNode (const Edge &edge) const
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e)
 
virtual void disconnectNodes (const Node &nTail, const Node &nHead)
 
virtual void moveInEdges (const Node &source, const Node &destination)
 
virtual void moveOutEdges (const Node &source, const Node &destination)
 
virtual void moveInEdge (const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
 
virtual void moveOutEdge (const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
 
virtual void copyInEdge (const Node &destination, Edge &edge, const Node *tail=NULL)
 
virtual void copyOutEdge (const Node &destination, Edge &edge, const Node *head=NULL)
 
virtual void removeEdge (Edge &e)
 
virtual void dropNode (Node &node)
 
virtual void dropEdge (Edge &edge)
 
virtual bool hasEdge (const Node &nTail, const Node &nHead) const
 
virtual NodeSet rootNodes () const
 useful utility functions
 
virtual NodeSet sinkNodes () const
 
virtual NodeSet successors (const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
 
virtual NodeSet predecessors (const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
 
int maxPathLength (const MoveNode &node) const
 
int maxSinkDistance (const MoveNode &node) const
 
int maxSourceDistance (const MoveNode &node) const
 
bool isInCriticalPath (const MoveNode &node) const
 
int height () const
 
void findAllPaths () const
 
void detachSubgraph (BoostGraph &subGraph)
 
BoostGraphparentGraph ()
 
BoostGraphrootGraph ()
 
const BoostGraphrootGraph () const
 
bool hasNode (const Node &) const
 
virtual const TCEStringname () const
 
void setName (const TCEString &newName)
 
bool hasPath (MoveNode &src, const MoveNode &dest) const
 
void restoreNodeFromParent (MoveNode &node)
 
bool detectIllegalCycles () const
 
EdgeSet connectingEdges (const Node &nTail, const Node &nHead) const
 
- Public Member Functions inherited from GraphBase< GraphNode, GraphEdge >
 GraphBase ()
 
virtual ~GraphBase ()
 
virtual int outDegree (const Node &node) const =0
 
virtual int inDegree (const Node &node) const =0
 
virtual EdgeoutEdge (const Node &node, const int index) const =0
 
virtual EdgeinEdge (const Node &node, const int index) const =0
 
virtual EdgeSet outEdges (const Node &node) const =0
 
virtual EdgeSet inEdges (const Node &node) const =0
 
virtual NodetailNode (const Edge &edge) const =0
 
virtual NodeheadNode (const Edge &edge) const =0
 
virtual bool hasEdge (const Node &nTail, const Node &nHead) const =0
 
virtual EdgeSet connectingEdges (const Node &nTail, const Node &nHead) const =0
 
virtual void writeToDotFile (const TCEString &fileName) const
 
virtual void addNode (Node &node)=0
 
virtual void removeNode (Node &node)=0
 
virtual void removeEdge (Edge &e)=0
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e)=0
 
virtual void disconnectNodes (const Node &nTail, const Node &nHead)=0
 

Private Member Functions

bool queueRawPredecessors (NodeSet &queue, NodeSet &finalDest, NodeSet &predQueue, NodeSet &predFinalDest, bool guard) const
 
bool rWawRawEdgesOutUncond (MoveNode &mn)
 
int rAntiEdgesIn (MoveNode &mn)
 
bool isRootGraphProcedureDDG ()
 
bool hasEqualEdge (const MoveNode &tailNode, const MoveNode &headNode, const DataDependenceEdge &edge) const
 
int getOperationLatency (const TCEString &name) const
 

Private Attributes

std::set< TCEStringallParamRegs_
 
std::map< const TTAProgram::Move *, MoveNode * > nodesOfMoves_
 
POList programOperations_
 
std::map< const MoveNode *, BasicBlockNode * > moveNodeBlocks_
 
bool cycleGrouping_
 Dot printing related variables. Group the printed MoveNodes according to their cycles.
 
bool dotProgramOperationNodes_
 The moves belonging to the same program operation are merged to a single node. Reduces the complexity of the graph.
 
const TTAMachine::Machinemachine_
 
int delaySlots_
 
std::map< TCEString, int > operationLatencies_
 
int rrCost_
 
BasicBlockNodeownedBBN_
 
bool procedureDDG_
 
AntidependenceLevel registerAntidependenceLevel_
 
EdgeWeightHeuristics edgeWeightHeuristics_
 The heuristics to use to weight edges in the longest path computation.
 

Additional Inherited Members

- Protected Types inherited from BoostGraph< MoveNode, DataDependenceEdge >
typedef std::set< RemovedEdgeDatum > RemovedEdgeMap
 
typedef boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, Node *, Edge * > Graph
 Internal graph type, providing actual graph-like operations. This type definition relies on bundled properties of boost library, which need the host compiler to support partial template specialisation.
 
typedef boost::graph_traits< GraphGraphTraits
 Traits characterising the internal graph type.
 
typedef GraphTraits::out_edge_iterator OutEdgeIter
 Output edge iterator type.
 
typedef GraphTraits::in_edge_iterator InEdgeIter
 Input edge iterator type.
 
typedef GraphTraits::edge_iterator EdgeIter
 Iterator type for the list of all edges in the graph.
 
typedef GraphTraits::vertex_iterator NodeIter
 Iterator type for the list of all nodes in the graph.
 
typedef GraphTraits::edge_descriptor EdgeDescriptor
 Type with which edges of the graph are seen internally.
 
typedef GraphTraits::vertex_descriptor NodeDescriptor
 Type with which nodes of the graph are seen internally.
 
typedef hash_map< const Edge *, EdgeDescriptor, GraphHashFunctions > EdgeDescMap
 
typedef hash_map< const Node *, NodeDescriptor, GraphHashFunctions > NodeDescMap
 
typedef std::vector< std::vector< int > > PathCache
 
- Protected Member Functions inherited from BoostGraph< MoveNode, DataDependenceEdge >
NodetailNode (const Edge &edge, const NodeDescriptor &headNode) const
 
NodeheadNode (const Edge &edge, const NodeDescriptor &tailNode) const
 
virtual void connectNodes (const Node &nTail, const Node &nHead, Edge &e, GraphBase< MoveNode, DataDependenceEdge > *modifier, bool creatingSG=false)
 
void moveInEdges (const Node &source, const Node &destination, BoostGraph *modifierGraph)
 
virtual void moveOutEdges (const Node &source, const Node &destination, BoostGraph *modifierGraph)
 
virtual void removeNode (Node &node, BoostGraph *modifierGraph)
 
virtual void removeEdge (Edge &e, const MoveNode *tailNode, const MoveNode *headNode, BoostGraph *modifierGraph=NULL)
 
bool hasEdge (const Node &nTail, const Node &nHead, const Edge &edge) const
 
bool hasEdge (const Edge &edge, const Node *nTail=NULL, const Node *nHead=NULL) const
 
void restoreRemovedEdges (RemovedEdgeMap removedEdges)
 
EdgeDescriptor descriptor (const Edge &e) const
 
NodeDescriptor descriptor (const Node &n) const
 
EdgeDescriptor edgeDescriptor (const NodeDescriptor &tailNode, const Edge &e) const
 
EdgeDescriptor edgeDescriptor (const Edge &e, const NodeDescriptor &headNode) const
 
EdgeDescriptor connectingEdge (const Node &nTail, const Node &nHead) const
 
void replaceNodeWithLastNode (MoveNode &dest)
 
void calculatePathLengths () const
 
void calculatePathLengthsFast () const
 
void calculateSinkDistance (const MoveNode &node, int len, bool looping=false) const
 
void calculateSourceDistances (const MoveNode *startNode=NULL, int startingLength=0, bool looping=false) const
 
void calculatePathLengthsOnConnect (const MoveNode &nTail, const MoveNode &nHead, DataDependenceEdge &e)
 
void sinkDistDecreased (const MoveNode &n) const
 
void sourceDistDecreased (const MoveNode &n) const
 
void clearDescriptorCache (EdgeSet edges)
 
void constructSubGraph (BoostGraph &subGraph, NodeSet &nodes)
 
- Protected Member Functions inherited from GraphBase< GraphNode, GraphEdge >
virtual bool hasNode (const Node &) const =0
 
- Protected Attributes inherited from BoostGraph< MoveNode, DataDependenceEdge >
std::unordered_map< const MoveNode *, int > sourceDistances_
 
std::unordered_map< const MoveNode *, int > sinkDistances_
 
std::unordered_map< const MoveNode *, int > loopingSourceDistances_
 
std::unordered_map< const MoveNode *, int > loopingSinkDistances_
 
int height_
 
Graph graph_
 The internal graph structure.
 
EdgeDescMap edgeDescriptors_
 
NodeDescMap nodeDescriptors_
 
BoostGraph< MoveNode, DataDependenceEdge > * parentGraph_
 
std::vector< BoostGraph< MoveNode, DataDependenceEdge > * > childGraphs_
 
TCEString name_
 
int sgCounter_
 
std::set< Edge * > ownedEdges_
 
bool allowLoopEdges_
 
PathCachepathCache_
 

Detailed Description

Definition at line 67 of file DataDependenceGraph.hh.

Member Enumeration Documentation

◆ AntidependenceLevel

Enumerator
NO_ANTIDEPS 
INTRA_BB_ANTIDEPS 
SINGLE_BB_LOOP_ANTIDEPS 
ALL_ANTIDEPS 

Definition at line 78 of file DataDependenceGraph.hh.

◆ DumpFileFormat

Enumerator
DUMP_DOT 
DUMP_XML 

Definition at line 85 of file DataDependenceGraph.hh.

◆ EdgeWeightHeuristics

Enumerator
EWH_HEURISTIC 

Weights memory dependencies more, etc.

EWH_REAL 

Height returns the minimum cycle count for the schedule given enough resources.

EWH_DEFAULT 

Definition at line 90 of file DataDependenceGraph.hh.

90 {
91 EWH_HEURISTIC, ///< Weights memory dependencies more, etc.
92 EWH_REAL, ///< Height returns the minimum cycle count for the
93 ///< schedule given enough resources.
95 };
@ EWH_HEURISTIC
Weights memory dependencies more, etc.
@ EWH_REAL
Height returns the minimum cycle count for the schedule given enough resources.

Constructor & Destructor Documentation

◆ DataDependenceGraph()

DataDependenceGraph::DataDependenceGraph ( std::set< TCEString allParamRegs,
const TCEString name = "",
AntidependenceLevel  antidependenceLevel = ALL_ANTIDEPS,
BasicBlockNode ownedBBN = NULL,
bool  containsProcedure = false,
bool  noLoopEdges = false 
)

Constructor.

Parameters
nameThe graph can be named for debugging purposes.
containsProcedurewhether the DDG contains complete procedure.
ownedBBNif the DDG should delete a BBn at destructor.
containsProcedureif the ddg contains a whole procedure.
ifthe ddg should not accept loop edges.
antidependenceLevellevel of register antidependencies which this ddg should contain.

Definition at line 78 of file DataDependenceGraph.cc.

82 :
84 allParamRegs_(allParamRegs), cycleGrouping_(true),
86 machine_(NULL), delaySlots_(0), rrCost_(3), ownedBBN_(ownedBBN),
87 procedureDDG_(containsProcedure),
88 registerAntidependenceLevel_(antidependenceLevel),
90}
virtual const TCEString & name() const
bool dotProgramOperationNodes_
The moves belonging to the same program operation are merged to a single node. Reduces the complexity...
EdgeWeightHeuristics edgeWeightHeuristics_
The heuristics to use to weight edges in the longest path computation.
AntidependenceLevel registerAntidependenceLevel_
std::set< TCEString > allParamRegs_
bool cycleGrouping_
Dot printing related variables. Group the printed MoveNodes according to their cycles.
const TTAMachine::Machine * machine_

◆ ~DataDependenceGraph()

DataDependenceGraph::~DataDependenceGraph ( )
virtual

Deletes all MoveNodes and ProgramOperations.

Definition at line 95 of file DataDependenceGraph.cc.

95 {
96
97 if (parentGraph_ == NULL) {
98
99 //delete nodes.
100 int nc = nodeCount();
101 for (int i = 0; i < nc; i++) {
102 delete &node(i, false);
103 }
104 programOperations_.clear();
105 }
106 if (ownedBBN_ != NULL) {
107 delete ownedBBN_;
108 }
109}
Node & node(const int index) const
BoostGraph< MoveNode, DataDependenceEdge > * parentGraph_

References BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), ownedBBN_, BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, and programOperations_.

Here is the call graph for this function:

Member Function Documentation

◆ addNode() [1/3]

void DataDependenceGraph::addNode ( MoveNode moveNode)
virtual

◆ addNode() [2/3]

void DataDependenceGraph::addNode ( MoveNode moveNode,
BasicBlockNode bblock 
)

Adds a node into the graph.

Parameters
moveNodemoveNode being added.
bblockBasic block where the move logically belongs.

Definition at line 158 of file DataDependenceGraph.cc.

158 {
159 addNode(moveNode);
160 setNodeBB(moveNode, bblock, NULL);
161}
void setNodeBB(MoveNode &mn, BasicBlockNode &bblock, DataDependenceGraph *updater)
void addNode(MoveNode &moveNode)

References addNode(), and setNodeBB().

Here is the call graph for this function:

◆ addNode() [3/3]

void DataDependenceGraph::addNode ( MoveNode moveNode,
MoveNode relatedNode 
)

Adds a node into the graph.

Parameters
moveNodemoveNode being added.
relatedNodeanother node already existing in the graph where this movenode relates to. , for example is created by splitting that
Todo:
: also add to subgrapsh which have the related node?

Definition at line 172 of file DataDependenceGraph.cc.

172 {
173 addNode(moveNode);
174 setNodeBB(moveNode, getBasicBlockNode(relatedNode), NULL);
175 /// @todo: also add to subgrapsh which have the related node?
176}
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const

References addNode(), getBasicBlockNode(), and setNodeBB().

Here is the call graph for this function:

◆ addProgramOperation()

void DataDependenceGraph::addProgramOperation ( ProgramOperationPtr  po)

Adds a program operation to the graph, and its parent graphs.

Parameters
poProgramOperation being added.

Definition at line 298 of file DataDependenceGraph.cc.

298 {
299 for (int i = 0; i < programOperationCount(); i++) {
300 if (programOperations_[i] == po) {
301 return;
302 }
303 }
304 programOperations_.push_back(po);
305 if (parentGraph_ != NULL) {
306 dynamic_cast<DataDependenceGraph*>(parentGraph_)
308 }
309}
void addProgramOperation(ProgramOperationPtr po)

References addProgramOperation(), BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, programOperationCount(), and programOperations_.

Referenced by addProgramOperation(), LLVMTCEDataDependenceGraphBuilder::buildLocalDDG(), DataDependenceGraphBuilder::processResultRead(), DataDependenceGraphBuilder::processTriggerPO(), and BFRemoveLoopChecksAndJump::undoOnlyMe().

Here is the call graph for this function:

◆ combineNodes()

void DataDependenceGraph::combineNodes ( MoveNode node1,
MoveNode node2,
MoveNode destination 
)

Definition at line 2782 of file DataDependenceGraph.cc.

2783 {
2784
2787
2788 moveOutEdges(node2, destination);
2789 moveInEdges(node1, destination);
2790
2791 EdgeSet oEdges1 = outEdges(node1);
2792 EdgeSet iEdges2 = inEdges(node2);
2793
2794 // copy WARs over.
2795 for (EdgeSet::iterator i = oEdges1.begin(); i != oEdges1.end(); i++) {
2796 DataDependenceEdge& oEdge = **i;
2797
2799 || oEdge.edgeReason() == DataDependenceEdge::EDGE_RA) &&
2801
2802 MoveNode& head = headNode(oEdge,nd1);
2803 if (&head == &node2) {
2804 continue;
2805 }
2806 moveOutEdge(node1, destination, oEdge);
2807 }
2808 }
2809
2810 for (EdgeSet::iterator i = iEdges2.begin(); i != iEdges2.end(); i++) {
2811 DataDependenceEdge& iEdge = **i;
2812
2814 || iEdge.edgeReason() == DataDependenceEdge::EDGE_RA) &&
2817
2818 MoveNode& tail = tailNode(iEdge,nd2);
2819 if (&tail == &node1) {
2820 continue;
2821 }
2822 moveInEdge(node2, destination, iEdge);
2823 }
2824 }
2825}
EdgeDescriptor descriptor(const Edge &e) const
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
virtual void moveOutEdges(const Node &source, const Node &destination)
virtual Node & headNode(const Edge &edge) const
std::set< DataDependenceEdge *, typename GraphEdge::Comparator > EdgeSet
Definition BoostGraph.hh:87
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
virtual EdgeSet outEdges(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
virtual void moveInEdges(const Node &source, const Node &destination)
virtual EdgeSet inEdges(const Node &node) const
DependenceType dependenceType() const
EdgeReason edgeReason() const

References DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), BoostGraph< MoveNode, DataDependenceEdge >::moveInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::moveInEdges(), BoostGraph< MoveNode, DataDependenceEdge >::moveOutEdge(), BoostGraph< MoveNode, DataDependenceEdge >::moveOutEdges(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by PreOptimizer::tryToRemoveGuardInversingOp().

Here is the call graph for this function:

◆ connectOrDeleteEdge()

bool DataDependenceGraph::connectOrDeleteEdge ( const MoveNode tailNode,
const MoveNode headNode,
DataDependenceEdge edge 
)

Connects nodes with an edge if equal edge between nodes not exists. If equal edge already exists, deletes the given edge.

Parameters
tailNodetail node of edge
headNodehead node of edge
edgeedge which is added to graph or deleted.
Returns
true if connected, false if already existed.

Definition at line 3355 of file DataDependenceGraph.cc.

3357 {
3359 delete edge;
3360 return false;
3361 } else {
3363 return true;
3364 }
3365}
virtual Edge & edge(const int index) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
bool hasEqualEdge(const MoveNode &tailNode, const MoveNode &headNode, const DataDependenceEdge &edge) const

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), hasEqualEdge(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by DataDependenceGraphBuilder::checkAndCreateMemDep(), copyDepsOver(), copyDepsOver(), DataDependenceGraphBuilder::createOperationEdges(), createRegisterAntiDependenciesBetweenNodes(), DataDependenceGraphBuilder::createRegisterAntideps(), DataDependenceGraphBuilder::createSideEffectEdges(), fixInterBBAntiEdges(), DataDependenceGraphBuilder::processRegUse(), RegisterRenamer::updateAntiEdgesFromLRTo(), updateRegUse(), and updateRegWrite().

Here is the call graph for this function:

◆ copyDependencies()

void DataDependenceGraph::copyDependencies ( const MoveNode src,
MoveNode dst,
bool  ignoreSameBBBackedges,
bool  moveOverLoopEdge = true 
)

Copies all dependencies going to and from a movenode to another

Creates copy of all edges going to and from an movenode and make them to point to and fro another movenode.

Parameters
srcmovenode to copy dependencies from
dstmovenode to copy dependencies to
Todo:
should this method be in base class? would require graphedge.clone()

Definition at line 3816 of file DataDependenceGraph.cc.

3818 {
3819 // performance optimization
3820 NodeDescriptor nd = descriptor(src);
3821
3822 // use the internal data structures to make this fast.
3823 // edgeset has too much set overhead,
3824 // inedge(n,i) is O(n^2) , this is linear with no overhead
3825 std::pair<InEdgeIter, InEdgeIter> iEdges =
3826 boost::in_edges(nd, graph_);
3827
3828 for (InEdgeIter ii = iEdges.first; ii != iEdges.second; ii++) {
3829 EdgeDescriptor ed = *ii;
3831 MoveNode* tail = graph_[boost::source(ed, graph_)];
3832 if (ignoreSameBBBackedges && edge->isBackEdge() &&
3833 &getBasicBlockNode(src) == &getBasicBlockNode(*tail)) {
3834 continue;
3835 }
3837 *edge, (moveOverLoopEdge && tail != &src && tail != &dst));
3838 connectNodes(*tail, dst, *newEdge);
3839 }
3840
3841 std::pair<OutEdgeIter, OutEdgeIter> oEdges =
3842 boost::out_edges(nd, graph_);
3843
3844 for (OutEdgeIter oi = oEdges.first; oi != oEdges.second; oi++) {
3845 EdgeDescriptor ed = *oi;
3847 MoveNode* head = graph_[boost::target(ed, graph_)];
3848 if (ignoreSameBBBackedges && edge->isBackEdge() &&
3849 &getBasicBlockNode(src) == &getBasicBlockNode(*head)) {
3850 continue;
3851 }
3853 *edge, (moveOverLoopEdge && head != &src && head != &dst));
3854 connectNodes(dst, *head, *newEdge);
3855 }
3856}
GraphTraits::out_edge_iterator OutEdgeIter
Output edge iterator type.
GraphTraits::in_edge_iterator InEdgeIter
Input edge iterator type.
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
Graph graph_
The internal graph structure.
virtual bool isBackEdge() const
Definition GraphEdge.hh:63

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), getBasicBlockNode(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, and GraphEdge::isBackEdge().

Referenced by MoveNodeDuplicator::duplicateMoveNode(), and CopyingDelaySlotFiller::getMoveNode().

Here is the call graph for this function:

◆ copyDepsOver() [1/2]

DataDependenceGraph::EdgeSet DataDependenceGraph::copyDepsOver ( MoveNode node,
bool  anti,
bool  raw 
)

Copies dependencies over the node, like when the node is being deleted.

Converts WaR + WaW to WaR and WaW + WaW to WaW.

Parameters
nodenode whose in- and outgoing antideps are being combined/copied.

Definition at line 2422 of file DataDependenceGraph.cc.

2422 {
2423
2424 EdgeSet createdEdges;
2425
2427
2428 EdgeSet iEdges = inEdges(node);
2429 EdgeSet oEdges = outEdges(node);
2430
2431 // Loop thru all outedges.
2432 for (EdgeSet::iterator i = oEdges.begin(); i != oEdges.end(); i++) {
2433 DataDependenceEdge& oEdge = **i;
2434
2435 // Care about WaW edges. (WaW+Waw -> Waw, WaR+WaW->War)
2436 // Also raw edges (raw+raw -> raw)
2438 || oEdge.edgeReason() == DataDependenceEdge::EDGE_RA) &&
2439 (((oEdge.dependenceType() == DataDependenceEdge::DEP_WAW && anti)||
2440 (oEdge.dependenceType() == DataDependenceEdge::DEP_RAW && raw)))){
2441
2442 // Then loop all incoming edges.
2443 for (EdgeSet::iterator j = iEdges.begin();
2444 j != iEdges.end(); j++) {
2445 DataDependenceEdge& iEdge = **j;
2446
2447 // if WAW and same register, copy edge
2448 if (iEdge.dependenceType() == oEdge.dependenceType() &&
2451 iEdge.data() == oEdge.data()) {
2452
2453 MoveNode& tail = tailNode(iEdge,nd);
2454 MoveNode& head = headNode(oEdge,nd);
2455
2456 if (!exclusingGuards(tail, head) ||
2457 (oEdge.dependenceType() ==
2459 oEdge.guardUse())) {
2460 // create new edge
2461 // same other properties but sum loop depth
2464 iEdge.edgeReason(),
2465 iEdge.dependenceType(),
2466 iEdge.data(),
2467 iEdge.guardUse(),
2468 false,
2469 iEdge.tailPseudo(),
2470 oEdge.headPseudo(),
2471 iEdge.loopDepth() + oEdge.loopDepth());
2472
2473 if (connectOrDeleteEdge(tail, head, edge)) {
2474 createdEdges.insert(edge);
2475 }
2476 }
2477 }
2478
2479 // if WAR and same register, and oedge was waw, copy edge.
2484 iEdge.data() == oEdge.data()) {
2485
2486 MoveNode& tail = tailNode(iEdge,nd);
2487 MoveNode& head = headNode(oEdge,nd);
2488
2489 if (!exclusingGuards(tail, head) || iEdge.guardUse()) {
2490 // create new edge
2491 // same other properties but sum loop depth
2494 iEdge.edgeReason(),
2495 iEdge.dependenceType(),
2496 iEdge.data(),
2497 iEdge.guardUse(),
2498 false,
2499 iEdge.tailPseudo(),
2500 oEdge.headPseudo(),
2501 iEdge.loopDepth() + oEdge.loopDepth());
2502
2503 if (connectOrDeleteEdge(tail, head, edge)) {
2504 createdEdges.insert(edge);
2505 }
2506 }
2507 }
2508 }
2509 }
2510 }
2511 return createdEdges;
2512}
const TCEString data() const
bool exclusingGuards(const MoveNode &mn1, const MoveNode &mn2) const
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)

References connectOrDeleteEdge(), DataDependenceEdge::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), exclusingGuards(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), DataDependenceEdge::loopDepth(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), and DataDependenceEdge::tailPseudo().

Referenced by BUBasicBlockScheduler::bypassNode(), CycleLookBackSoftwareBypasser::bypassNode(), destRenamed(), mergeAndKeepSource(), BFDREEarly::operator()(), BFDRELate::operator()(), BFDRELoop::operator()(), BFPostpassDRE::operator()(), BFPostpassLoopDRE::operator()(), renamedSimpleLiveRange(), BasicBlockScheduler::tryToOptimizeWaw(), BUBasicBlockScheduler::tryToOptimizeWaw(), and PreOptimizer::tryToRemoveGuardInversingOp().

Here is the call graph for this function:

◆ copyDepsOver() [2/2]

void DataDependenceGraph::copyDepsOver ( MoveNode node1,
MoveNode node2,
bool  anti,
bool  raw 
)

Definition at line 2515 of file DataDependenceGraph.cc.

2516 {
2517
2520
2521 EdgeSet iEdges1 = inEdges(node1);
2522 EdgeSet oEdges1 = outEdges(node1);
2523 EdgeSet iEdges2 = inEdges(node2);
2524 EdgeSet oEdges2 = outEdges(node2);
2525
2526 // Loop through all outedges of last one
2527 for (EdgeSet::iterator i = oEdges2.begin(); i != oEdges2.end(); i++) {
2528 DataDependenceEdge& oEdge = **i;
2529
2530 // only care about register edges
2532 || oEdge.edgeReason() == DataDependenceEdge::EDGE_RA)) {
2533 continue;
2534 }
2535
2536 // are we copying this type edges?
2537 if (!(((oEdge.dependenceType() == DataDependenceEdge::DEP_WAW||
2538 oEdge.dependenceType() == DataDependenceEdge::DEP_WAR) && anti) ||
2539 (oEdge.dependenceType() == DataDependenceEdge::DEP_RAW && raw))) {
2540 continue;
2541 }
2542
2543 MoveNode& head = headNode(oEdge, nd2);
2544
2545 if (oEdge.dependenceType() == DataDependenceEdge::DEP_RAW && raw) {
2546 // Then loop all incoming edges for raw deps
2547 for (EdgeSet::iterator j = iEdges1.begin();
2548 j != iEdges1.end(); j++) {
2549 DataDependenceEdge& iEdge = **j;
2550
2551 // RAW going over node.
2552 if (iEdge.dependenceType() == oEdge.dependenceType() &&
2556 iEdge.data() == oEdge.data()) {
2557
2558 MoveNode& tail = tailNode(iEdge, nd1);
2559
2560 if (!exclusingGuards(tail, head) ||
2561 (oEdge.dependenceType() == oEdge.guardUse())) {
2562
2563 // create new edge
2564 // same other properties but sum loop depth
2567 iEdge.edgeReason(),
2568 iEdge.dependenceType(),
2569 iEdge.data(),
2570 iEdge.guardUse() || oEdge.guardUse(),
2571 false,
2572 iEdge.tailPseudo(),
2573 oEdge.headPseudo(),
2574 iEdge.loopDepth() + oEdge.loopDepth());
2575
2576 connectOrDeleteEdge(tail, head, edge);
2577 }
2578 }
2579 }
2580 }
2581
2582 if (!anti) {
2583 continue;
2584 }
2585
2587 // Then loop all incoming edges for waw deps
2588 for (EdgeSet::iterator j = iEdges2.begin();
2589 j != iEdges2.end(); j++) {
2590 DataDependenceEdge& iEdge = **j;
2591
2592 // WAW going over node.
2593 if (iEdge.dependenceType() == oEdge.dependenceType() &&
2597 iEdge.data() == oEdge.data()) {
2598
2599 MoveNode& tail = tailNode(iEdge);
2600
2601 if (!exclusingGuards(tail, head) && &tail != &node1) {
2602
2603 // create new edge
2604 // same other properties but sum loop depth
2607 iEdge.edgeReason(),
2608 iEdge.dependenceType(),
2609 iEdge.data(),
2610 iEdge.guardUse(),
2611 false,
2612 iEdge.tailPseudo(),
2613 oEdge.headPseudo(),
2614 iEdge.loopDepth() + oEdge.loopDepth());
2615
2616 connectOrDeleteEdge(tail, head, edge);
2617 }
2618 }
2619
2620 // if WAR and same register, and oedge was waw, copy edge.
2625 iEdge.data() == oEdge.data()) {
2626
2627 MoveNode& tail = tailNode(iEdge,nd2);
2628
2629 if (!exclusingGuards(tail, head)) {
2630 // create new edge
2631 // same other properties but sum loop depth
2634 iEdge.edgeReason(),
2635 iEdge.dependenceType(),
2636 iEdge.data(),
2637 iEdge.guardUse(),
2638 false,
2639 iEdge.tailPseudo(),
2640 oEdge.headPseudo(),
2641 iEdge.loopDepth() + oEdge.loopDepth());
2642
2643 if (&tail == &head) {
2644 std::cerr << "copydeps over copying edge same node(1)!" << tail.toString() << " edge: " << edge->toString()
2645 << std::endl;
2646 }
2647
2648 connectOrDeleteEdge(tail, head, edge);
2649 }
2650 }
2651 }
2652 }
2653
2654 // last one reads interesting register
2656 for (EdgeSet::iterator j = iEdges1.begin();
2657 j != iEdges1.end(); j++) {
2658 DataDependenceEdge& iEdge = **j;
2663 iEdge.data() == oEdge.data()) {
2664 MoveNode& tail = tailNode(iEdge,nd2);
2665
2666 if (!exclusingGuards(tail, head)) {
2667 // create new edge
2668 // same other properties but sum loop depth
2671 iEdge.edgeReason(),
2672 iEdge.dependenceType(),
2673 iEdge.data(),
2674 iEdge.guardUse(),
2675 false,
2676 iEdge.tailPseudo(),
2677 oEdge.headPseudo(),
2678 iEdge.loopDepth() + oEdge.loopDepth());
2679
2680 if (&tail == &head) {
2681 std::cerr << "copydeps over copying edge same node(2)!" << tail.toString() << " edge: " << edge->toString()
2682 << std::endl;
2683 }
2684 connectOrDeleteEdge(tail, head, edge);
2685 }
2686 }
2687 }
2688 }
2689 }
2690
2691 if (!anti) {
2692 return;
2693 }
2694
2695 // copy WARs over.
2696 for (EdgeSet::iterator i = oEdges1.begin(); i != oEdges1.end(); i++) {
2697 DataDependenceEdge& oEdge = **i;
2698
2699 // only care about register edges
2701 || oEdge.edgeReason() == DataDependenceEdge::EDGE_RA)) {
2702 continue;
2703 }
2704
2706
2707 MoveNode& head = headNode(oEdge,nd1);
2708 if (&head == &node2) {
2709 continue;
2710 }
2711
2712 // Then loop all incoming edges for waw deps
2713 for (EdgeSet::iterator j = iEdges2.begin();
2714 j != iEdges2.end(); j++) {
2715 DataDependenceEdge& iEdge = **j;
2716
2717 // WAW going over node.
2721 iEdge.data() == oEdge.data()) {
2722
2723 MoveNode& tail = tailNode(iEdge,nd2);
2724 if (!exclusingGuards(tail, head) && &tail != &node1) {
2725 // create new edge
2726 // same other properties but sum loop depth
2729 iEdge.edgeReason(),
2730 iEdge.dependenceType(),
2731 iEdge.data(),
2732 iEdge.guardUse(),
2733 false,
2734 iEdge.tailPseudo(),
2735 oEdge.headPseudo(),
2736 iEdge.loopDepth() + oEdge.loopDepth());
2737
2738 connectOrDeleteEdge(tail, head, edge);
2739 }
2740 }
2741 }
2742 }
2744 MoveNode& head = headNode(oEdge,nd1);
2745 if (&head == &node2) {
2746 continue;
2747 }
2748
2749 for (EdgeSet::iterator j = iEdges1.begin();
2750 j != iEdges1.end(); j++) {
2751 DataDependenceEdge& iEdge = **j;
2756 iEdge.data() == oEdge.data()) {
2757 MoveNode& tail = tailNode(iEdge,nd2);
2758
2759 if (!exclusingGuards(tail, head)) {
2760 // create new edge
2761 // same other properties but sum loop depth
2764 iEdge.edgeReason(),
2765 iEdge.dependenceType(),
2766 iEdge.data(),
2767 iEdge.guardUse(),
2768 false,
2769 iEdge.tailPseudo(),
2770 oEdge.headPseudo(),
2771 iEdge.loopDepth() + oEdge.loopDepth());
2772
2773 connectOrDeleteEdge(tail, head, edge);
2774 }
2775 }
2776 }
2777 }
2778 }
2779}
virtual TCEString toString() const
Definition GraphEdge.cc:66
std::string toString() const
Definition MoveNode.cc:576

References connectOrDeleteEdge(), DataDependenceEdge::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), exclusingGuards(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), DataDependenceEdge::loopDepth(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), DataDependenceEdge::tailPseudo(), GraphEdge::toString(), and MoveNode::toString().

Here is the call graph for this function:

◆ copyExternalInEdges()

void DataDependenceGraph::copyExternalInEdges ( MoveNode nodeCopy,
const MoveNode source 
)

Copies incoming edges which come from nodes on other BB's to a node into another node. If an edge comes from inside same BB, does not copy.

Parameters
sourcenode containing original incoming edges.
nodeCopynode where to copy the inedges to.

Definition at line 5323 of file DataDependenceGraph.cc.

5324 {
5325 const BasicBlockNode* origBB = &getBasicBlockNode(source);
5326
5327 EdgeSet edges = inEdges(source);
5328 for (EdgeSet::iterator i = edges.begin(); i != edges.end(); i++) {
5329 Edge& edge = **i;
5330 MoveNode& tail = tailNode(edge);
5331 if (&getBasicBlockNode(tail) != origBB) {
5333 connectNodes(tail, nodeCopy, *newEdge);
5334 }
5335 }
5336}
DataDependenceEdge Edge
The (base) edge type managed by this graph.
Definition BoostGraph.hh:92

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), getBasicBlockNode(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by LoopPrologAndEpilogBuilder::build().

Here is the call graph for this function:

◆ copyExternalOutEdges()

void DataDependenceGraph::copyExternalOutEdges ( MoveNode nodeCopy,
const MoveNode source 
)

Copies outgoing edges which goes from a node to nodes in other BB's into another node. If an edge goes to a node inside same BB, does not copy.

Parameters
sourcenode containing original outgoingcoming edges.
nodeCopynode where to copy the outedges to.

Definition at line 5346 of file DataDependenceGraph.cc.

5347 {
5348 const BasicBlockNode* origBB = &getBasicBlockNode(source);
5349
5350 EdgeSet edges = outEdges(source);
5351 for (EdgeSet::iterator i = edges.begin(); i != edges.end(); i++) {
5352 Edge& edge = **i;
5353 MoveNode& head = headNode(edge);
5354 if (&getBasicBlockNode(head) != origBB) {
5356 connectNodes(nodeCopy, head, *newEdge);
5357 }
5358 }
5359}

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), getBasicBlockNode(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by LoopPrologAndEpilogBuilder::build().

Here is the call graph for this function:

◆ copyIncomingGuardEdges()

void DataDependenceGraph::copyIncomingGuardEdges ( const MoveNode src,
MoveNode dst 
)

Copies all incoming guard dependencies going to a movenode to another

Parameters
srcmovenode to copy dependencies from
dstmovenode to copy dependencies to

Definition at line 3865 of file DataDependenceGraph.cc.

3866 {
3867
3868 // performance optimization
3869 NodeDescriptor nd = descriptor(src);
3870
3871 // use the internal data structures to make this fast.
3872 // edgeset has too much set overhead,
3873 // inedge(n,i) is O(n^2) , this is linear with no overhead
3874 std::pair<InEdgeIter, InEdgeIter> iEdges =
3875 boost::in_edges(nd, graph_);
3876
3877 for (InEdgeIter ii = iEdges.first; ii != iEdges.second; ii++) {
3878 EdgeDescriptor ed = *ii;
3880 if (edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3881 edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
3882 edge->guardUse()) {
3884 MoveNode& tail = *graph_[boost::source(ed, graph_)];
3885 connectNodes(tail, dst, *newEdge);
3886 }
3887 }
3888}

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, and BoostGraph< MoveNode, DataDependenceEdge >::graph_.

Referenced by CopyingDelaySlotFiller::collectMoves(), BasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ copyIncomingRawEdges()

void DataDependenceGraph::copyIncomingRawEdges ( const MoveNode src,
MoveNode dst 
)

Definition at line 5770 of file DataDependenceGraph.cc.

5770 {
5771
5772 // performance optimization
5773 NodeDescriptor nd = descriptor(src);
5774
5775 // use the internal data structures to make this fast.
5776 // edgeset has too much set overhead,
5777 // inedge(n,i) is O(n^2) , this is linear with no overhead
5778 std::pair<InEdgeIter, InEdgeIter> iEdges =
5779 boost::in_edges(nd, graph_);
5780
5781 for (InEdgeIter ii = iEdges.first; ii != iEdges.second; ii++) {
5782 EdgeDescriptor ed = *ii;
5784 if ((edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER
5785 || edge->edgeReason() == DataDependenceEdge::EDGE_RA) &&
5786 edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
5787 !edge->guardUse()) {
5789 MoveNode& tail = *graph_[boost::source(ed, graph_)];
5790 connectNodes(tail, dst, *newEdge);
5791 }
5792 }
5793}

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, and BoostGraph< MoveNode, DataDependenceEdge >::graph_.

Here is the call graph for this function:

◆ copyOutgoingGuardWarEdges()

void DataDependenceGraph::copyOutgoingGuardWarEdges ( const MoveNode src,
MoveNode dst 
)

Copies all outgoing guard war dependencies going to a movenode to another

Parameters
srcmovenode to copy dependencies from
dstmovenode to copy dependencies to

Definition at line 3897 of file DataDependenceGraph.cc.

3898 {
3899
3900 // performance optimization
3901 NodeDescriptor nd = descriptor(src);
3902
3903 // use the internal data structures to make this fast.
3904 // edgeset has too much set overhead,
3905 // inedge(n,i) is O(n^2) , this is linear with no overhead
3906 std::pair<OutEdgeIter, OutEdgeIter> oEdges =
3907 boost::out_edges(nd, graph_);
3908
3909 for (OutEdgeIter oi = oEdges.first; oi != oEdges.second; oi++) {
3910 EdgeDescriptor ed = *oi;
3912 if (edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3913 edge->dependenceType() == DataDependenceEdge::DEP_WAR &&
3914 edge->guardUse()) {
3916 MoveNode& head = *graph_[boost::target(ed, graph_)];
3917 connectNodes(dst, head, *newEdge);
3918 }
3919 }
3920}

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::DEP_WAR, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, and BoostGraph< MoveNode, DataDependenceEdge >::graph_.

Referenced by BasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ createRegisterAntiDependenciesBetweenNodes()

void DataDependenceGraph::createRegisterAntiDependenciesBetweenNodes ( DataDependenceGraph::NodeSet nodes)

Creates antidependencies between certains nodes of a ddg.

This is used after regcopyadded to insert antideps between the temp registers added by the regcopyadder.

All nodes given to the method should be scheduled. The nodes should have already been added to the graph.

Parameters
nodesnodes whose antidependencies to add.

Definition at line 4381 of file DataDependenceGraph.cc.

4382 {
4383
4384 typedef std::map<int, NodeSet >
4385 MovesByCycles;
4386 MovesByCycles movesInCycles;
4387 typedef std::map<TCEString, NodeSet> NodeSetMap;
4388
4389 NodeSetMap reads;
4390 NodeSetMap writes;
4391 // insert all moves int correct cycle in bookkeeping
4392 for (NodeSet::iterator nsIter = nodes.begin();
4393 nsIter != nodes.end(); nsIter++) {
4394 MoveNode* mn = *nsIter;
4395 assert(mn->isPlaced());
4396 movesInCycles[mn->cycle()].insert(mn);
4397 }
4398
4399 // loop thru all cycles
4400 for (MovesByCycles::iterator i = movesInCycles.begin();
4401 i != movesInCycles.end(); i++) {
4402
4403 NodeSet& nodesInCycle = i->second;
4404 // then check sources of all nodes in the cycle
4405 for (NodeSet::iterator j = nodesInCycle.begin();
4406 j != nodesInCycle.end(); j++) {
4407 MoveNode* mn = *j;
4408 TTAProgram::Move& move = mn->move();
4409 TTAProgram::Terminal& src = move.source();
4410 if (src.isGPR()) {
4412 reads[reg].insert(mn);
4413 }
4414 }
4415
4416 // then check destinations of all nodes in the cycle
4417 for (NodeSet::iterator j = nodesInCycle.begin();
4418 j != nodesInCycle.end(); j++) {
4419
4420 MoveNode* mn = *j;
4421 TTAProgram::Move& move = mn->move();
4422 TTAProgram::Terminal& dst = move.destination();
4423 if (dst.isGPR()) {
4425
4426 NodeSet& readsFromReg = reads[reg];
4427 NodeSet& writesToReg = writes[reg];
4428
4429 // create the dependencies.
4430 // WaRs
4431 for (NodeSet::iterator k = readsFromReg.begin();
4432 k != readsFromReg.end(); k++) {
4433 MoveNode& prevMN = **k;
4434 if (!exclusingGuards(prevMN, *mn)) {
4439 connectOrDeleteEdge(**k, *mn, edge);
4440 }
4441 }
4442
4443 // WaWs.
4444 for (NodeSet::iterator k = writesToReg.begin();
4445 k != writesToReg.end(); k++) {
4446 MoveNode& prevMN = **k;
4447 if (!exclusingGuards(prevMN, *mn)) {
4452 connectOrDeleteEdge(**k, *mn, edge);
4453 }
4454 }
4455
4456 // if this is unconditional, kills previous writes to the reg
4457 if (move.isUnconditional()) {
4458 writes[reg].clear();
4459 reads[reg].clear();
4460 }
4461 writes[reg].insert(mn);
4462 }
4463 }
4464 }
4465}
#define assert(condition)
std::set< MoveNode *, typename GraphNode::Comparator > NodeSet
Definition BoostGraph.hh:86
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
int cycle() const
Definition MoveNode.cc:421
bool isPlaced() const
Definition MoveNode.cc:352
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual bool isGPR() const
Definition Terminal.cc:107

References assert, connectOrDeleteEdge(), MoveNode::cycle(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, exclusingGuards(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), MoveNode::move(), DisassemblyRegister::registerName(), and TTAProgram::Move::source().

Referenced by RegisterCopyAdder::operandsScheduled(), and RegisterCopyAdder::resultsScheduled().

Here is the call graph for this function:

◆ createSubgraph() [1/3]

DataDependenceGraph * DataDependenceGraph::createSubgraph ( NodeSet nodes,
bool  includeLoops = false 
)

Creates a subgraph of a ddg from set of cede snippets which contains instructions which contains moves in this graph.

Parameters
nodescode being included in the subgraph
includeLoopswhether to include loop-carried dependencies
Returns
the created subgraph

Definition at line 3377 of file DataDependenceGraph.cc.

3378 {
3379 DataDependenceGraph* subGraph =
3382 !includeLoops);
3383
3384 if (machine_ != NULL) {
3385 subGraph->setMachine(*machine_);
3386 }
3387
3388 constructSubGraph(*subGraph, nodes);
3389
3390 typedef std::set<ProgramOperationPtr, ProgramOperationPtrComparator> POSet;
3391 POSet subgraphPOs;
3392
3393 // copy the node -> bbn mapping.
3394 // also find POs to copy.
3395 for (int i = 0, nc = subGraph->nodeCount(); i < nc; i++) {
3396 MoveNode& mn = subGraph->node(i);
3397 BasicBlockNode* bbn = moveNodeBlocks_[&mn];
3398 subGraph->moveNodeBlocks_[&mn] = bbn;
3399 if (mn.isSourceOperation()) {
3400 subgraphPOs.insert(mn.sourceOperationPtr());
3401 }
3402
3403 if (mn.isDestinationOperation()) {
3404 subgraphPOs.insert(mn.destinationOperationPtr());
3405 }
3406 }
3407 for (auto i: subgraphPOs) {
3408 subGraph->programOperations_.push_back(i);
3409 }
3410 return subGraph;
3411}
void constructSubGraph(BoostGraph &subGraph, NodeSet &nodes)
void setMachine(const TTAMachine::Machine &machine)
std::map< const MoveNode *, BasicBlockNode * > moveNodeBlocks_
ProgramOperationPtr sourceOperationPtr() const
Definition MoveNode.cc:458
bool isDestinationOperation() const
bool isSourceOperation() const
Definition MoveNode.cc:168
ProgramOperationPtr destinationOperationPtr(unsigned int index=0) const

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), MoveNode::destinationOperationPtr(), MoveNode::isDestinationOperation(), MoveNode::isSourceOperation(), machine_, moveNodeBlocks_, BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), programOperations_, registerAntidependenceLevel_, setMachine(), and MoveNode::sourceOperationPtr().

Referenced by BUMoveNodeSelector::BUMoveNodeSelector(), BBSchedulerController::createDDGFromBB(), createSubgraph(), createSubgraph(), and CriticalPathBBMoveNodeSelector::CriticalPathBBMoveNodeSelector().

Here is the call graph for this function:

◆ createSubgraph() [2/3]

DataDependenceGraph * DataDependenceGraph::createSubgraph ( std::list< TTAProgram::CodeSnippet * > &  codeSnippets,
bool  includeLoops = false 
)

Creates a subgraph of a ddg from set of cede snippets which contains instructions which contains moves in this graph.

Parameters
codeSnippetscode being included in the subgraph
includeLoopswhether to include loop-carried dependencies
Returns
the created subgraph

Definition at line 3563 of file DataDependenceGraph.cc.

3564 {
3565 NodeSet moveNodes;
3566
3567 int nc = nodeCount();
3568 for (int i = 0; i < nc; i++) {
3569 MoveNode& mn = node(i,false);
3570 if (mn.isMove()) {
3571 TTAProgram::Move& move = mn.move();
3572 TTAProgram::Instruction& parentIns = move.parent();
3573 if (parentIns.isInProcedure()) { // is in code snippet
3574 for (std::list<TTAProgram::CodeSnippet*>::iterator iter =
3575 codeSnippets.begin();
3576 iter != codeSnippets.end(); iter++) {
3577 TTAProgram::CodeSnippet& cs = **iter;
3578 if (&move.parent().parent() == &cs) {
3579 moveNodes.insert(&mn);
3580 }
3581 }
3582 }
3583 }
3584 }
3585 return createSubgraph(moveNodes, includeLoops);
3586}
DataDependenceGraph * createSubgraph(NodeSet &nodes, bool includeLoops=false)
CodeSnippet & parent() const
Instruction & parent() const
Definition Move.cc:115

References createSubgraph(), TTAProgram::Instruction::isInProcedure(), MoveNode::isMove(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Instruction::parent(), and TTAProgram::Move::parent().

Here is the call graph for this function:

◆ createSubgraph() [3/3]

DataDependenceGraph * DataDependenceGraph::createSubgraph ( TTAProgram::CodeSnippet cs,
bool  includeLoops = false 
)

Creates a subgraph of a ddg from set of cede snippets which contains instructions which contains moves in this graph.

Parameters
cscode being included in the subgraph
includeLoopswhether to include loop-carried dependencies
Returns
the created subgraph

Definition at line 3532 of file DataDependenceGraph.cc.

3533 {
3534 NodeSet moveNodes;
3535 int nc = nodeCount();
3536 for (int i = 0; i < nc; i++) {
3537 MoveNode& mn = node(i,false);
3538 if (mn.isMove()) {
3539 TTAProgram::Move& move = mn.move();
3540 if (move.isInInstruction()) {
3541 TTAProgram::Instruction& parentIns = move.parent();
3542 if (parentIns.isInProcedure()) { // is in code snippet
3543 if (&parentIns.parent() == &cs) {
3544 moveNodes.insert(&mn);
3545 }
3546 }
3547 }
3548 }
3549 }
3550 return createSubgraph(moveNodes, includeLoops);
3551}
bool isInInstruction() const
Definition Move.cc:144

References createSubgraph(), TTAProgram::Move::isInInstruction(), TTAProgram::Instruction::isInProcedure(), MoveNode::isMove(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Instruction::parent(), and TTAProgram::Move::parent().

Here is the call graph for this function:

◆ criticalPathGraph()

DataDependenceGraph * DataDependenceGraph::criticalPathGraph ( )

Returns a version of the graph with only nodes that are in the critical path.

Definition at line 3458 of file DataDependenceGraph.cc.

3458 {
3459 DataDependenceGraph* subGraph =
3461 allParamRegs_, "critical path DDG",
3462 registerAntidependenceLevel_, NULL, false, false);
3463
3464 if (machine_ != NULL)
3465 subGraph->setMachine(*machine_);
3466
3467 NodeSet nodes;
3468 for (int i = 0; i < nodeCount(); ++i) {
3469 if (isInCriticalPath(node(i)))
3470 nodes.insert(&node(i));
3471 }
3472 constructSubGraph(*subGraph, nodes);
3473
3474 return subGraph;
3475}
bool isInCriticalPath(const MoveNode &node) const

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), BoostGraph< MoveNode, DataDependenceEdge >::isInCriticalPath(), machine_, BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), registerAntidependenceLevel_, and setMachine().

Referenced by ResourceConstraintAnalyzer::analyze(), and BasicBlockScheduler::ddgSnapshot().

Here is the call graph for this function:

◆ deleteNode()

void DataDependenceGraph::deleteNode ( MoveNode node)

Removes a MoveNode from a graph and deletes it.

Parameters
nodeMoveNode being deleted.

Definition at line 2882 of file DataDependenceGraph.cc.

2882 {
2884 delete &node;
2885}
void removeNode(MoveNode &node)

References BoostGraph< MoveNode, DataDependenceEdge >::node(), and removeNode().

Referenced by PreOptimizer::tryToPrecalcConstantAdd(), and PreOptimizer::tryToRemoveGuardInversingOp().

Here is the call graph for this function:

◆ destRenamed()

DataDependenceGraph::UndoData DataDependenceGraph::destRenamed ( MoveNode mn)

Destination of a move is renamed to a register which is not used in this ddg. Removes old edges not needed anymore and updates some edges. Assumes all the RAW successors of this node are also udpated to read thr new register.

Definition at line 5055 of file DataDependenceGraph.cc.

5055 {
5056
5057 UndoData undoData;
5058 undoData.newEdges = copyDepsOver(mn, true, false);
5059
5060 TTAProgram::Terminal& term = mn.move().destination();
5061 const TCEString newReg = DisassemblyRegister::registerName(term);
5062
5063 for (int i = 0 ; i < inDegree(mn); i++) {
5064 DataDependenceEdge& iEdge = inEdge(mn,i);
5065 MoveNode& tail = tailNode(iEdge);
5066
5067 // WAR's
5070 !iEdge.headPseudo()) {
5071
5072 TTAProgram::Terminal& writeTerm = tail.move().destination();
5073
5074 // if this edge disappers because of the renaming?
5075 if (iEdge.tailPseudo() ||
5076 (writeTerm.isGPR() && (
5077 writeTerm.index() != term.index() ||
5078 &writeTerm.registerFile() != &term.registerFile()))) {
5079 undoData.removedEdges.insert(RemovedEdgeDatum(tail, mn, iEdge));
5080 removeEdge(iEdge, NULL, &mn);
5081 i--; // don't skip one edge here!
5082 } else {
5083 // update the edge. also other end changed
5084 undoData.changedDataEdges[&iEdge] = iEdge.data();
5085 iEdge.setData(newReg);
5086 }
5087 }
5088
5091 !iEdge.headPseudo()) {
5092
5093 bool removeE = false;
5094 if (iEdge.tailPseudo()) {
5095 removeE = true;
5096 continue;
5097 }
5098
5099 if (!iEdge.guardUse()) {
5100 TTAProgram::Terminal& readTerm = tail.move().source();
5101 if (readTerm.isGPR() && (
5102 readTerm.index() != term.index() ||
5103 &readTerm.registerFile() != &term.registerFile())) {
5104 removeE = true;
5105 }
5106 }
5107
5108 if (iEdge.guardUse()) {
5109 if (tail.move().isUnconditional()) {
5110 removeE = true;
5111/* something is wrong. but ignore it for now
5112 std::cerr << "failing node: " << mn.toString() << std::endl;
5113 std::cerr << "failinf tail: " << tail.toString() << std::endl;
5114 std::cerr << "EDGE: " << iEdge.toString() << std::endl;
5115 writeToDotFile("uncond_gu_war.dot");
5116*/
5117
5118 } else {
5119 const TTAMachine::RegisterGuard* rg =
5120 dynamic_cast<const TTAMachine::RegisterGuard*>(
5121 &tail.move().guard().guard());
5122 if (rg->registerFile() != &term.registerFile() ||
5123 rg->registerIndex() != term.index()) {
5124 removeE = true;
5125 }
5126 }
5127 }
5128 // if this edge disappers because of the renaming?
5129 if (removeE) {
5130 undoData.removedEdges.insert(RemovedEdgeDatum(tail, mn, iEdge));
5131 removeEdge(iEdge, NULL, &mn);
5132 i--; // don't skip one edge here!
5133 } else {
5134 // update the edge. also other end changed
5135 undoData.changedDataEdges[&iEdge] = iEdge.data();
5136 iEdge.setData(newReg);
5137 }
5138 }
5139 }
5140
5141 for (int i = 0; i < outDegree(mn); i++) {
5143
5144 if (edge.edgeReason() != DataDependenceEdge::EDGE_REGISTER) {
5145 continue;
5146 }
5147
5148 if (edge.dependenceType() == DataDependenceEdge::DEP_RAW &&
5149 !edge.tailPseudo()) {
5150 // update the data!
5151 edge.setData(newReg);
5152
5153 } else {
5154 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW) {
5155 MoveNode& head = headNode(edge);
5156 TTAProgram::Terminal& writeTerm = head.move().destination();
5157
5158 // if this edge disappers because of the renaming?
5159 if (edge.tailPseudo()) {
5160 continue;
5161 }
5162 if (edge.headPseudo() ||
5163 (writeTerm.isGPR() && (
5164 writeTerm.index() != term.index() ||
5165 &writeTerm.registerFile() != &term.registerFile()))){
5166 undoData.removedEdges.insert(
5167 RemovedEdgeDatum(mn, head, edge));
5168 removeEdge(edge, &mn, NULL);
5169 i--;
5170 } else {
5171 // update the edge. also other end changed
5172 undoData.changedDataEdges[&edge] = edge.data();
5173 edge.setData(newReg);
5174 }
5175 }
5176 }
5177 }
5178 return undoData;
5179}
virtual Edge & outEdge(const Node &node, const int index) const
virtual Edge & inEdge(const Node &node, const int index) const
virtual int inDegree(const Node &node) const
virtual int outDegree(const Node &node) const
void setData(const TCEString &newData)
EdgeSet copyDepsOver(MoveNode &node, bool anti, bool raw)
const RegisterFile * registerFile() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
virtual int index() const
Definition Terminal.cc:274
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225

References DataDependenceGraph::UndoData::changedDataEdges, copyDepsOver(), DataDependenceEdge::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), TTAProgram::Terminal::index(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isUnconditional(), MoveNode::move(), DataDependenceGraph::UndoData::newEdges, BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DisassemblyRegister::registerName(), DataDependenceGraph::UndoData::removedEdges, BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), DataDependenceEdge::setData(), TTAProgram::Move::source(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), and DataDependenceEdge::tailPseudo().

Referenced by BFRenameLiveRange::renameLiveRange(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ dotString()

TCEString DataDependenceGraph::dotString ( ) const
virtual

Dot printing related methods.

Returns the graph as a string formatted in GraphViz Dot format.

This version is able to order the nodes according to their cycles to make the output more readable.

Returns
Graph represented as a Dot string.

Reimplemented from GraphBase< GraphNode, GraphEdge >.

Definition at line 1562 of file DataDependenceGraph.cc.

1562 {
1563
1564 // TODO group based on both BB and cycle
1565 std::ostringstream s;
1566 s << "digraph " << name() << " {" << std::endl;
1567
1569 // print the "time line"
1570 s << "\t{" << std::endl
1571 << "\t\tnode [shape=plaintext];" << std::endl
1572 << "\t\t";
1573 const int smallest = smallestCycle();
1574 const int largest = largestCycle();
1575 for (int c = smallest; c <= largest; ++c) {
1576 s << "\"cycle " << c << "\" -> ";
1577 }
1578 s << "\"cycle " << largest + 1 << "\"; "
1579 << std::endl << "\t}" << std::endl;
1580
1581 // print the nodes that have cycles
1582 for (int c = smallest; c <= largest; ++c) {
1583 NodeSet moves = movesAtCycle(c);
1584 if (moves.size() > 0) {
1585 s << "\t{ rank = same; \"cycle " << c << "\"; ";
1586 for (NodeSet::iterator i = moves.begin();
1587 i != moves.end(); ++i) {
1588 Node& n = **i;
1589 s << "n" << n.nodeID() << "; ";
1590 }
1591 s << "}" << std::endl;
1592 }
1593 }
1594 }
1595
1596 // print all the nodes and their properties
1597 for (int i = 0; i < nodeCount(); ++i) {
1598 Node& n = node(i);
1599
1600 // in PONode mode, print the node for a single move only if
1601 // it doesn't belong to an operation
1602 if (dotProgramOperationNodes_ && n.isOperationMove())
1603 continue;
1604
1605 TCEString nodeStr(n.dotString());
1606 if (false && isInCriticalPath(n)) {
1607 // convert critical path node shapes to invtriangle to make
1608 // the path stand out in the graph, this slows down the
1609 // printout probably quite a bit, TODO: optimize by caching
1610 // critical path data
1611 nodeStr.replaceString("shape=box", "shape=invtriangle");
1612 nodeStr.replaceString("shape=ellipse", "shape=invtriangle");
1613 }
1614 s << "\tn" << n.nodeID() << " [" << nodeStr << "]; " << std::endl;
1615 }
1616
1617 typedef std::set<ProgramOperation*> POSet;
1618 POSet programOps;
1619
1620 // edges. optimized low-level routines.
1621 typedef std::pair<EdgeIter, EdgeIter> EdgeIterPair;
1622 EdgeIterPair edges = boost::edges(graph_);
1623 for (EdgeIter i = edges.first; i != edges.second; i++) {
1624 EdgeDescriptor ed = *i;
1625 Edge& e = *graph_[ed];
1626 Node& tail = *graph_[boost::source(ed, graph_)];
1627 Node& head = *graph_[boost::target(ed, graph_)];
1628
1629 TCEString tailNodeId;
1630 TCEString headNodeId;
1631
1632 if (dotProgramOperationNodes_ && tail.isOperationMove()) {
1633 if (tail.isSourceOperation()) {
1634 tailNodeId << "po" << tail.sourceOperation().poId();
1635 programOps.insert(&tail.sourceOperation());
1636 } else {
1637 tailNodeId << "po" << tail.destinationOperation().poId();
1638 programOps.insert(&tail.destinationOperation());
1639 }
1640 } else {
1641 tailNodeId << "n" << tail.nodeID();
1642 }
1643
1644 if (dotProgramOperationNodes_ && head.isOperationMove()) {
1645 if (head.isSourceOperation()) {
1646 headNodeId << "po" << head.sourceOperation().poId();
1647 programOps.insert(&head.sourceOperation());
1648 } else {
1649 headNodeId << "po" << head.destinationOperation().poId();
1650 programOps.insert(&head.destinationOperation());
1651 }
1652 } else {
1653 headNodeId << "n" << head.nodeID();
1654 }
1655
1656 if (tailNodeId == headNodeId) continue;
1657
1658 float weight = 1.0f;
1659 s << "\t" << tailNodeId
1660 << " -> " << headNodeId << "[";
1661
1662 if (e.isFalseDep()) {
1663 weight = 0.3f;
1664 s << "color=\"red\", ";
1665 }
1666
1667 if (e.isBackEdge()) {
1668 s << "constraint=false,";
1669 weight = 0.1f;
1670 }
1671
1672 if (e.edgeReason() == DataDependenceEdge::EDGE_OPERATION) {
1673 weight = 10.0f;
1674 }
1675
1676 if (e.edgeReason() == DataDependenceEdge::EDGE_MEMORY && !e.certainAlias()) {
1677 weight /= 2.0f;
1678 }
1679
1680 s << "label=\""
1681 << e.toString(tail)
1682 << "\",weight=" << weight << "];" << std::endl;
1683 }
1684
1685 // implicit operand to trigger edges
1686 for (int i = 0; i < nodeCount() && !dotProgramOperationNodes_; ++i) {
1687 Node& n = node(i);
1688 if (n.isMove() && n.move().isTriggering() &&
1689 n.isDestinationOperation()) {
1690 ProgramOperation &dst = n.destinationOperation();
1691 for (int j = 0; j < dst.inputMoveCount(); ++j) {
1692 if (dst.inputMove(j).nodeID() != n.nodeID()) {
1693 s << "\tn" << dst.inputMove(j).nodeID()
1694 << " -> n" << n.nodeID() << "["
1695 << "label=\"T\", weight=10.0" << "];" << std::endl;
1696 }
1697 }
1698 }
1699 }
1700
1702 for (POSet::iterator i = programOps.begin();
1703 i != programOps.end(); ++i) {
1704 const ProgramOperation& po = **i;
1705 TCEString label;
1706
1707 int lineNo = -1;
1708
1709 for (int i = 0; i < po.inputMoveCount(); ++i) {
1710 label += po.inputMove(i).toString() + "\\n";
1711 if (po.inputMove(i).move().hasSourceLineNumber())
1712 lineNo = po.inputMove(i).move().sourceLineNumber();
1713 }
1714 label += "\\n";
1715 for (int i = 0; i < po.outputMoveCount(); ++i) {
1716 label += po.outputMove(i).toString() + "\\n";
1717 }
1718
1719 if (lineNo != -1)
1720 label << "src line: " << lineNo << "\\n";
1721
1722 s << "\tpo" << po.poId() << " [label=\""
1723 << label << "\",shape=box];" << std::endl;
1724 }
1725 }
1726
1727 s << "}" << std::endl;
1728
1729 return s.str();
1730}
MoveNode Node
The (base) node type managed by this graph.
Definition BoostGraph.hh:90
GraphTraits::edge_iterator EdgeIter
Iterator type for the list of all edges in the graph.
NodeSet movesAtCycle(int cycle) const
int nodeID() const
int outputMoveCount() const
unsigned int poId() const
int inputMoveCount() const
MoveNode & inputMove(int index) const
MoveNode & outputMove(int index) const
bool hasSourceLineNumber() const
Definition Move.cc:445
int sourceLineNumber() const
Definition Move.cc:459

References DataDependenceEdge::certainAlias(), cycleGrouping_, MoveNode::destinationOperation(), dotProgramOperationNodes_, MoveNode::dotString(), DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, TTAProgram::Move::hasSourceLineNumber(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), DataDependenceEdge::isBackEdge(), MoveNode::isDestinationOperation(), DataDependenceEdge::isFalseDep(), BoostGraph< MoveNode, DataDependenceEdge >::isInCriticalPath(), MoveNode::isMove(), MoveNode::isOperationMove(), MoveNode::isSourceOperation(), TTAProgram::Move::isTriggering(), largestCycle(), MoveNode::move(), movesAtCycle(), BoostGraph< MoveNode, DataDependenceEdge >::name(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), GraphNode::nodeID(), ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), ProgramOperation::poId(), procedureDDG_, TCEString::replaceString(), smallestCycle(), TTAProgram::Move::sourceLineNumber(), MoveNode::sourceOperation(), DataDependenceEdge::toString(), and MoveNode::toString().

Here is the call graph for this function:

◆ dropBackEdges()

void DataDependenceGraph::dropBackEdges ( )

Drops loop edges from a sub-DDG.

This works only with simple control structures; Only works for edges marked as loop edges. Currently loop edges spanning over multiple basic blocks may be missing.

Definition at line 3620 of file DataDependenceGraph.cc.

3620 {
3621 const int nc = nodeCount();
3622
3623 // first loop thru all nodes.
3624 for (int n = 0; n < nc; n++) {
3625 NodeDescriptor nd = boost::vertex(n, graph_);
3626
3627 // the thru all output edges of the node.
3628 // this is propably the fastest way to iterate over
3629 // all edges of a graph. (or is just all edges faster?)
3630 std::pair<OutEdgeIter, OutEdgeIter> edges =
3631 boost::out_edges(nd, graph_);
3632
3633 for (OutEdgeIter ei = edges.first; ei != edges.second;) {
3634 DataDependenceEdge* e = graph_[(*ei)];
3635 if (e->isBackEdge()) {
3636 // remove from internal bookkeeping
3637 boost::remove_edge(*ei, graph_);
3638
3639 // iterators must be resetted when deleted something.
3640 edges = boost::out_edges(nd, graph_);
3641 ei = edges.first;
3642
3643 // remove from edge descriptor cache
3644 DataDependenceGraph::EdgeDescMap::iterator
3645 edIter = edgeDescriptors_.find(e);
3646 if (edIter != edgeDescriptors_.end()) {
3647 edgeDescriptors_.erase(edIter);
3648 }
3649
3650 for (unsigned int i = 0; i < childGraphs_.size(); i++) {
3651 childGraphs_.at(i)->dropEdge(*e);
3652 }
3653 } else {
3654 ei++;
3655 }
3656 }
3657 }
3658}
std::vector< BoostGraph< MoveNode, DataDependenceEdge > * > childGraphs_

References BoostGraph< MoveNode, DataDependenceEdge >::childGraphs_, BoostGraph< MoveNode, DataDependenceEdge >::edgeDescriptors_, BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::isBackEdge(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Here is the call graph for this function:

◆ dropProgramOperation()

void DataDependenceGraph::dropProgramOperation ( ProgramOperationPtr  po)

Drops a program operation to the graph, but not its parent graphs.

Parameters
poProgramOperation being added.

Definition at line 361 of file DataDependenceGraph.cc.

361 {
362 for (auto i = programOperations_.begin();
363 i != programOperations_.end();i++) {
364 if (*i == po) {
365 programOperations_.erase(i);
366 return;
367 }
368 }
369}

References programOperations_.

Referenced by BFRemoveLoopChecksAndJump::operator()().

◆ earliestCycle()

int DataDependenceGraph::earliestCycle ( const MoveNode moveNode,
unsigned int  ii = UINT_MAX,
bool  ignoreRegWaRs = false,
bool  ignoreRegWaWs = false,
bool  ignoreGuards = false,
bool  ignoreFuDeps = false,
bool  ignoreSameOperationEdges = false,
bool  assumeBypassing = false 
) const

Returns the earliest cycle this move can be scheduled at given the cycles of the dependencies.

Checks all the parent nodes of the move in the DDG and finds their max cycle if they are scheduled, if none found, 0 is returned, if at least one of the preceeding nodes is unscheduled, returns INT_MAX.

Parameters
moveNodeThe move node for which to find the earliest cycle.
assumeBypassingIf the preceeding MoveNodes are register writes, assume a reading MoveNode will be able to bypass from the source to save a cycle.
Returns
The earliest cycle the move can be scheduled to according to data dependencies, INT_MAX if unknown.
Todo:
clean this up: should be the same code as the edgeWeight when EWH_REAL is used.

Definition at line 388 of file DataDependenceGraph.cc.

391 {
392
393 if (machine_ == NULL) {
394 throw InvalidData(__FILE__,__LINE__,__func__,
395 " setMachine() must be called before this");
396 }
397 const EdgeSet edges = inEdges(moveNode);
398 int minCycle = 0;
399 for (EdgeSet::const_iterator i = edges.begin(); i != edges.end(); ++i) {
401
402 if (ignoreGuards && edge.guardUse()) {
403 continue;
404 }
405
406 if (ignoreFuDeps &&
407 (edge.edgeReason() == DataDependenceEdge::EDGE_FUSTATE ||
408 edge.edgeReason() == DataDependenceEdge::EDGE_MEMORY)) {
409 continue;
410 }
411
412 if (ignoreSameOperationEdges &&
414 continue;
415 }
416
417 MoveNode& tail = tailNode(edge);
418 if (&tail == &moveNode) {
419 continue;
420 }
421
422 if (ignoreSameOperationEdges && !edge.isBackEdge() &&
423 moveNode.isSourceOperation() &&
424 tail.isDestinationOperation() &&
425 &moveNode.sourceOperation() == &tail.destinationOperation()) {
426 continue;
427 }
428
429
430 if (tail.isPlaced()) {
431 int effTailCycle = tail.cycle();
432
433 // If call, make sure all incoming deps fit into delay slots,
434 // can still be later than the call itself
435 // dependence type does not matter.
436 if (edge.headPseudo()) {
437 effTailCycle -= delaySlots_;
438 } else {
439 /// @todo clean this up: should be the same code as the edgeWeight
440 /// when EWH_REAL is used.
441 if (edge.edgeReason() == DataDependenceEdge::EDGE_OPERATION &&
442 moveNode.isSourceOperation() && tail.inSameOperation(moveNode)) {
443 effTailCycle += getOperationLatency(edge.data());
444 } else if (edge.dependenceType() == DataDependenceEdge::DEP_WAW) {
445
446 // ignore reg antidep? then skip over this edge.
447 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER
448 && !edge.headPseudo() &&
449 ignoreRegWaWs) {
450 continue;
451 }
452 // latency does not matter with WAW. always +1.
453 effTailCycle += 1;
454 } else {
455 int latency;
456 if (assumeBypassing) {
457 latency = 0;
458 } else {
459 latency = 1;
460 }
461 if (edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
462 // ignore reg antidep? then skip over this edge.
463 if (edge.edgeReason() ==
465 !edge.headPseudo() && ignoreRegWaRs) {
466 continue;
467 }
468
469 // WAR allows writing at same cycle than reading.
470 // in WAR also the latency goes backwards,
471 // new value can
472 // be written before old is read is latency is big.
473 if (edge.guardUse()) {
474 latency = tail.guardLatency();
475 }
476
477 // TODO: generate some hasAutomaticBundling()
478 // property to ADF
480 latency = 0;
481 }
482 effTailCycle = effTailCycle - latency + 1;
483 } else {
484 // RAW
485 if (edge.guardUse()) {
486 latency = moveNode.guardLatency();
487 }
488 // in case of RAW, we have to wait latency cycles
489 // before we can use the written value.
490 effTailCycle += latency;
491 }
492 }
493 }
494
495 assert ((ii != 0 || edge.loopDepth() ==0) &&
496 "ii should not be 0 if we have an loop edge");
497
498 effTailCycle -= (ii * edge.loopDepth());
499 minCycle = std::max(effTailCycle, minCycle);
500 }
501 }
502
503 // on architectures with hw data hazard detection this is needed.
504 // TODO: now does this for all input moves, not just trigger
506 moveNode.isDestinationOperation()) {
507
508 ProgramOperation& po = moveNode.destinationOperation();
509 MoveNode* trigger = po.triggeringMove();
510 if (trigger == nullptr || trigger == &moveNode) {
511 for (int i = 0; i < po.outputMoveCount(); i++) {
512 MoveNode& outMove = po.outputMove(i);
513 if (hasNode(outMove)) {
514 minCycle =
515 std::max(minCycle,
516 earliestCycle(outMove, ii,
517 ignoreRegWaRs,
518 ignoreRegWaWs,
519 ignoreGuards,
520 true, // ignoreFuDeps
521 true)); // operation edges ignored
522 }
523 }
524 }
525 }
526 return minCycle;
527}
#define __func__
int earliestCycle(const MoveNode &moveNode, unsigned int ii=UINT_MAX, bool ignoreRegWaRs=false, bool ignoreRegWaWs=false, bool ignoreGuards=false, bool ignoreFUDeps=false, bool ignoreSameOperationEdges=false, bool assumeBypassing=false) const
int getOperationLatency(const TCEString &name) const
int guardLatency() const
Definition MoveNode.cc:779
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
bool inSameOperation(const MoveNode &other) const
Definition MoveNode.cc:306
ProgramOperation & destinationOperation(unsigned int index=0) const
MoveNode * triggeringMove() const
bool triggerInvalidatesResults() const
Definition Machine.cc:958

References __func__, assert, MoveNode::cycle(), delaySlots_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, MoveNode::destinationOperation(), earliestCycle(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_FUSTATE, DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, getOperationLatency(), MoveNode::guardLatency(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), MoveNode::inSameOperation(), GraphEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isPlaced(), MoveNode::isSourceOperation(), machine_, ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), MoveNode::sourceOperation(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), ProgramOperation::triggeringMove(), and TTAMachine::Machine::triggerInvalidatesResults().

Referenced by ResourceConstraintAnalyzer::analyzeMoveNode(), CycleLookBackSoftwareBypasser::bypass(), CycleLookBackSoftwareBypasser::bypassNode(), MoveNodeGroup::earliestCycle(), earliestCycle(), ResourceConstraintAnalyzer::findResourceConstrainedParent(), ResourceConstraintAnalyzer::memoryBoundScheduleResourceUsage(), BFPushAntidepDown::operator()(), BFPushMoveUp::operator()(), BFPushMoveUp2::operator()(), BFRescheduleSuccessorsClose::operator()(), BFScheduleBU::operator()(), BFScheduleExact::operator()(), BUBasicBlockScheduler::scheduleMove(), BasicBlockScheduler::scheduleMove(), BasicBlockScheduler::scheduleOperandWrites(), BasicBlockScheduler::tryToOptimizeWaw(), and BasicBlockScheduler::tryToSwitchInputs().

Here is the call graph for this function:

◆ edgeLatency()

int DataDependenceGraph::edgeLatency ( const DataDependenceEdge edge,
int  ii,
const MoveNode tail,
const MoveNode head 
) const

Definition at line 311 of file DataDependenceGraph.cc.

314 {
315
316 int latency = 1;
317 if (edge.edgeReason() == DataDependenceEdge::EDGE_OPERATION) {
318 if (head == NULL) {
319 head = &headNode(edge);
320 }
321 if (head->isSourceOperation()) {
322 if (tail == NULL) {
323 tail = &tailNode(edge);
324 }
325 if (tail->inSameOperation(*head)) {
326 latency = getOperationLatency(edge.data());
327 }
328 }
329 } else if (edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
330 latency = 0;
331 }
332
333 if (edge.headPseudo()) {
334 latency -= delaySlots_;
335 }
336
337 if (edge.tailPseudo()) {
338 latency += delaySlots_;
339 }
340
341 if (edge.guardUse()) {
342 if (edge.dependenceType() == DataDependenceEdge::DEP_RAW) {
343 latency += (head->guardLatency()-1);
344 } else {
345 if (edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
346 latency -= (tail->guardLatency()-1);
347 } else {
348 std::cerr << "invalid guard edge: " << edge.toString();
349 }
350 }
351 }
352 return latency - ii*edge.loopDepth();
353}

References delaySlots_, DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, getOperationLatency(), MoveNode::guardLatency(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), MoveNode::inSameOperation(), MoveNode::isSourceOperation(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), and GraphEdge::toString().

Referenced by BFPushDepsUp::operator()().

Here is the call graph for this function:

◆ edgeWeight()

int DataDependenceGraph::edgeWeight ( DataDependenceEdge e,
const MoveNode n 
) const
virtual

Calculates a weight value for edges, to be used for path weight calculation for selector

Current implementation quite simple to have something better than fixed weight without having to analyze the machine. 3 equals about one cycle.

In order to use a version that computes the weight strictly using only the operation latencies, thus gives the minimum achievable schedule length given enough resources (with operation latencies as in the machine), call setEdgeWeightHeuristics(EWH_REAL) before calling this. To get back to the default one, call setEdgeWeightHeuristics(EWH_DEFAULT).

Todo:
EWH_HEURISTIC is incomplete. It should take in account the number of resources in the current target machine and not assume a "generic machine".
Parameters
eedge whose weight is being measured
nhead node of the edge.
Returns
weigth of the edge.

Reimplemented from BoostGraph< MoveNode, DataDependenceEdge >.

Definition at line 2910 of file DataDependenceGraph.cc.

2911 {
2912
2913 if (e.weight() != -1) {
2914 return e.weight();
2915 }
2916
2918
2919 if (e.headPseudo()) {
2920 // pseudo deps do not really limit the scheduling.
2921 e.setWeight(0);
2922 return 0;
2923 }
2924
2925 switch (e.edgeReason()) {
2927 int ew = getOperationLatency(e.data()) * 3;
2928 e.setWeight(ew);
2929 return ew;
2930 }
2932
2934 // the number 9 seems to work well on most benchmarks.
2935 // big weight for these makes stores to be scheduled earlier,
2936 // which both helps register pressure and helps stores to
2937 // come earlier, as memory is often worse bottleneck than
2938 // registers or calculation.
2939 e.setWeight(9);
2940 return 9;
2941 }
2942 // for memory WaR's and WaW's this seem to work quite well,
2943 // forces memory ops to be scheduled before other ops.
2944 e.setWeight(5);
2945 return 5;
2946 }
2947
2949 switch (e.dependenceType()) {
2950 // TODO: some connectivity heuristics
2952 // push guards a bit earlier.
2953 int latency = 0;
2954
2955 if (e.guardUse()) {
2956 int glat = n.guardLatency();
2957 // jump guard?
2958
2959 // for predicated control flow ops the edge weight is
2960 // guard latency + delay slots, as the predicated cflow
2961 // ins has to be scehduled delay slots cycles before end.
2962 if (n.isMove() && n.move().isControlFlowMove()) {
2963 int ew = std::max(1, 3*(glat + delaySlots_));
2964 e.setWeight(ew);
2965 return ew;
2966 }
2967 // some other predicated operation
2968 int ew = std::max(1, 3 * glat);
2969 e.setWeight(ew);
2970 return ew;
2971 } else {
2972 // jump address of indirect branch
2973 // indirect control flow ops the delay slots is added
2974 // to the edgeweight, as the indirect control flow ins
2975 // has to be scehduled delay slots cycles before end.
2976 if (n.isMove() && n.move().isControlFlowMove()) {
2977 latency += 3*delaySlots_;
2978 }
2979 }
2980 // rrcost is heurictic on how often we usually can bypass,
2981 // and how often we have to add extra regcopy.
2982 // it's anaylyzed from the machine.
2983 int ew = latency + rrCost_;
2984 e.setWeight(ew);
2985 return ew;
2986 }
2988 e.setWeight(1);
2989 return 1; // can be scheduled to same cycle. but put 1 still.
2990 }
2992 // 3 means 1 cycle. Keeps the order, but no extra delay.
2993 e.setWeight(3);
2994 return 3;
2995 }
2996 default: {
2997 // 3 means 1 cycle. Keeps the order, but no extra delay.
2998 e.setWeight(3);
2999 return 3;
3000 }
3001 }
3002 }
3004 if (n.isMove() && n.move().isJump()) {
3005 int ew = delaySlots_ != 0 ?
3006 (delaySlots_*3)+rrCost_ :
3007 3;
3008 e.setWeight(ew);
3009 return ew;
3010 } else {
3011 e.setWeight(rrCost_);
3012 return rrCost_;
3013 }
3014 }
3015 default:
3016 // 3 means 1 cycle. Keeps the order, but no extra delay.
3017 e.setWeight(3);
3018 return 3;
3019 }
3020 } else if (edgeWeightHeuristics_ == EWH_REAL) {
3021// return edgeLatency(e, ii, tail, head);
3022// }
3023
3024 if (e.headPseudo()) {
3025 // pseudo deps do not really limit the scheduling.
3026 e.setWeight(0);
3027 return 0;
3028 }
3029
3030 switch (e.edgeReason()) {
3032 return getOperationLatency(e.data());
3033 }
3036 // allowed to write a new value at the same cycle
3037 // another reads it (the load gets the old value)
3038 // TODO: this is a bug. this should be WAR, not RAW
3039 e.setWeight(0);
3040 return 0;
3041 } else {
3042 e.setWeight(1);
3043 return 1;
3044 }
3045 }
3048 switch (e.dependenceType()) {
3049 // TODO: some connectivity heuristics
3051 if (e.guardUse()) {
3052 int glat = n.guardLatency();
3053 // jump guard?
3054
3055 // for predicated control flow ops the edge weight is
3056 // guard latency + delay slots, as the predicated cflow
3057 // ins has to be scehduled delay slots cycles before end.
3058 if (n.isMove() && n.move().isControlFlowMove()) {
3059 int ew = std::max(1, glat + delaySlots_);
3060 e.setWeight(ew);
3061 return ew;
3062 }
3063 // some other predicated operation
3064 int ew = std::max(1, glat);
3065 e.setWeight(ew);
3066 return ew;
3067 } else {
3068 // jump address of indirect branch
3069 // indirect control flow ops the delay slots is added
3070 // to the edgeweight, as the indirect control flow ins
3071 // has to be scehduled delay slots cycles before end.
3072 if (n.isMove() && n.move().isControlFlowMove()) {
3073 int ew = delaySlots_ +1;
3074 e.setWeight(ew);
3075 return ew;
3076 }
3077 }
3078 e.setWeight(1);
3079 return 1;
3080
3081 }
3083 e.setWeight(0);
3084 return 0; // can be scheduled to same cycle
3085 }
3086 default: {
3087 e.setWeight(1);
3088 return 1;
3089 }
3090 }
3091 }
3092 default:
3093 e.setWeight(1);
3094 return 1; // can be scheduled to the next cycle (default)
3095 }
3096
3097 } else {
3098 abortWithError("Unknown edge weight heuristics.");
3099 }
3100 e.setWeight(1);
3101 return 1;
3102}
#define abortWithError(message)
void setWeight(int w)
Definition GraphEdge.hh:74
int weight() const
Definition GraphEdge.hh:73
bool isControlFlowMove() const
Definition Move.cc:233
bool isJump() const
Definition Move.cc:164

References abortWithError, DataDependenceEdge::data(), delaySlots_, DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), edgeWeightHeuristics_, EWH_HEURISTIC, EWH_REAL, getOperationLatency(), MoveNode::guardLatency(), DataDependenceEdge::guardUse(), DataDependenceEdge::headPseudo(), TTAProgram::Move::isControlFlowMove(), TTAProgram::Move::isJump(), MoveNode::isMove(), MoveNode::move(), rrCost_, GraphEdge::setWeight(), and GraphEdge::weight().

Here is the call graph for this function:

◆ exclusingGuards()

bool DataDependenceGraph::exclusingGuards ( const MoveNode mn1,
const MoveNode mn2 
) const

Definition at line 4480 of file DataDependenceGraph.cc.

4481 {
4482 if (!mn1.isMove() || !mn2.isMove()) {
4483 return false;
4484 }
4485 const TTAProgram::Move& move1 = mn1.move();
4486 const TTAProgram::Move& move2 = mn2.move();
4487 if (move1.isUnconditional() || move2.isUnconditional()) {
4488 return false;
4489 }
4490 TTAProgram::MoveGuard& mg1 = move1.guard();
4491 TTAProgram::MoveGuard& mg2 = move2.guard();
4492 if (mg1.isInverted() == mg2.isInverted()) {
4493 return false;
4494 }
4495 NodeSet incomingGuards1 =
4497
4498 NodeSet incomingGuards2 =
4500
4501 return !incomingGuards1.empty() &&
4502 incomingGuards1 == incomingGuards2;
4503}
NodeSet guardRawPredecessors(const MoveNode &node) const
bool isInverted() const
Definition MoveGuard.cc:76

References TTAProgram::Move::guard(), guardRawPredecessors(), TTAProgram::MoveGuard::isInverted(), MoveNode::isMove(), TTAProgram::Move::isUnconditional(), and MoveNode::move().

Referenced by DataDependenceGraphBuilder::checkAndCreateMemDep(), copyDepsOver(), copyDepsOver(), RegisterCopyAdder::createAntidepsForReg(), BFRegCopy::createAntidepsForReg(), createRegisterAntiDependenciesBetweenNodes(), DataDependenceGraphBuilder::createRegisterAntideps(), DataDependenceGraphBuilder::createSideEffectEdges(), ExecutionPipelineResource::exclusiveMoves(), mergeAndKeepAllowed(), mergeAndKeepUser(), DataDependenceGraphBuilder::processRegUse(), DataDependenceGraphBuilder::processRegWrite(), BasicBlockScheduler::tryToOptimizeWaw(), BUBasicBlockScheduler::tryToOptimizeWaw(), and unMergeUser().

Here is the call graph for this function:

◆ findBypassSource()

MoveNode * DataDependenceGraph::findBypassSource ( const MoveNode mn)

Definition at line 5734 of file DataDependenceGraph.cc.

5734 {
5735
5737 DataDependenceGraph::EdgeSet::iterator edgeIter = edges.begin();
5738 DataDependenceEdge* bypassEdge = NULL;
5739
5740 // find one incoming raw edge. if multiple, cannot bypass.
5741 while (edgeIter != edges.end()) {
5742
5743 DataDependenceEdge& edge = *(*edgeIter);
5744 // if the edge is not a real reg/ra raw edge, skip to next edge
5745 if (edge.edgeReason() != DataDependenceEdge::EDGE_REGISTER ||
5746 edge.dependenceType() != DataDependenceEdge::DEP_RAW ||
5747 edge.guardUse() || edge.headPseudo()) {
5748 edgeIter++;
5749 continue;
5750 }
5751
5752 if (bypassEdge == NULL) {
5753 bypassEdge = &edge;
5754 } else {
5755 // cannot bypass if multiple inputs
5756 return 0;
5757 }
5758 edgeIter++;
5759 }
5760
5761 // if no bypassable edge found, cannot bypass
5762 if (bypassEdge == NULL || bypassEdge->isBackEdge()) {
5763 return 0;
5764 }
5765
5766 MoveNode& source = tailNode(*bypassEdge);
5767 return &source;
5768}
std::set< GraphEdge *, typename GraphEdge::Comparator > EdgeSet
Definition Graph.hh:54

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), DataDependenceEdge::isBackEdge(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Here is the call graph for this function:

◆ findLimitingAntidependenceDestination()

MoveNode * DataDependenceGraph::findLimitingAntidependenceDestination ( MoveNode mn)

Definition at line 5293 of file DataDependenceGraph.cc.

5293 {
5294 NodeDescriptor nd = descriptor(mn);
5295 MoveNode* limitingAntidep = NULL;
5296 EdgeSet oEdges = outEdges(mn);
5297 for (EdgeSet::iterator oe = oEdges.begin(); oe != oEdges.end(); oe++) {
5298 DataDependenceEdge& e = **oe;
5299 // TODO: WAW?
5300
5301
5304 !e.headPseudo() && !e.tailPseudo() && !e.guardUse()) {
5305 MoveNode& head = headNode(e,nd);
5306 if (head.isPlaced() && (limitingAntidep == NULL ||
5307 head.cycle()<limitingAntidep->cycle())){
5308 limitingAntidep = &head;
5309 }
5310 }
5311 }
5312 return limitingAntidep;
5313}

References MoveNode::cycle(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), and DataDependenceEdge::tailPseudo().

Referenced by BUBasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ findLimitingAntidependenceSource()

MoveNode * DataDependenceGraph::findLimitingAntidependenceSource ( MoveNode mn)

Definition at line 5272 of file DataDependenceGraph.cc.

5272 {
5273 NodeDescriptor nd = descriptor(mn);
5274 MoveNode* limitingAntidep = NULL;
5275 EdgeSet iEdges = inEdges(mn);
5276 for (EdgeSet::iterator ie = iEdges.begin(); ie != iEdges.end(); ie++) {
5277 DataDependenceEdge& e = **ie;
5278 // TODO: WAW?
5281 !e.headPseudo() && !e.tailPseudo() && !e.guardUse()) {
5282 MoveNode& tail = tailNode(e,nd);
5283 if (tail.isPlaced() && (limitingAntidep == NULL ||
5284 tail.cycle()>limitingAntidep->cycle())){
5285 limitingAntidep = &tail;
5286 }
5287 }
5288 }
5289 return limitingAntidep;
5290}

References MoveNode::cycle(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), and DataDependenceEdge::tailPseudo().

Referenced by BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ findLiveRange()

LiveRange * DataDependenceGraph::findLiveRange ( MoveNode moveNode,
bool  dest,
bool  guard 
) const

Finds a liverange, consisting of one (or multiple if guarded writes) write and one or multiple reads to same registers. if none found, returns empty pair.

Returns
first set contains writes, second set uses

Definition at line 4827 of file DataDependenceGraph.cc.

4828 {
4829
4830 NodeSet queuedWrites;
4831 NodeSet queuedReads;
4832 NodeSet queuedGuards;
4833
4834 typedef EdgeSet::iterator EdgeIterator;
4835
4836 LiveRange* liveRange = new LiveRange;
4837
4838 if (dest == true) {
4839 queuedWrites.insert(&moveNode);
4840 } else {
4841 if (guard) {
4842 assert(moveNode.move().isUnconditional());
4843 queuedGuards.insert(&moveNode);
4844 } else {
4845 queuedReads.insert(&moveNode);
4846 }
4847 }
4848
4849 // loop as long as we have not checked successors of some
4850 // write or predecessors of some read.
4851
4852 // this is done in double-while-loop. only stop when neither
4853 // loop wants to continue.
4854 while (!queuedWrites.empty() || !queuedReads.empty() ||
4855 !queuedGuards.empty()) {
4856 // first check writes.
4857 while (!queuedWrites.empty()) {
4858 MoveNode& write = **queuedWrites.begin();
4859
4860 NodeDescriptor nd = descriptor(write);
4861 EdgeSet out = rootGraphOutEdges(write);
4862
4863 for (EdgeIterator i = out.begin(); i != out.end(); ++i) {
4864 DataDependenceEdge& e = **i;
4865
4866 // only register raws. pseudo deps not yet supported.
4869 MoveNode& succ =
4870 (static_cast<const DataDependenceGraph*>
4871 (rootGraph()))->headNode(e, nd);
4872
4873 if (e.isBackEdge() || e.headPseudo() ||
4874 e.tailPseudo() ||
4875 !hasNode(succ)) {
4876 liveRange->clear();
4877 return liveRange;
4878 } else {
4879 if (e.guardUse()) {
4880 // not yet handled. queue it
4881 if (liveRange->guards.find(&succ) ==
4882 liveRange->guards.end()) {
4883 queuedGuards.insert(&succ);
4884 }
4885 } else {
4886 // not yet handled. queue it
4887 if (liveRange->reads.find(&succ) ==
4888 liveRange->reads.end()) {
4889 queuedReads.insert(&succ);
4890 }
4891 }
4892 }
4893 }
4894 }
4895 // this is fully checked. add to result, remove from queue
4896 liveRange->writes.insert(&write);
4897 queuedWrites.erase(&write);
4898 }
4899
4901 queuedReads, liveRange->reads, queuedWrites,
4902 liveRange->writes, false)) {
4903 liveRange->clear();
4904 return liveRange;
4905 }
4906
4908 queuedGuards, liveRange->guards, queuedWrites,
4909 liveRange->writes, true)) {
4910 liveRange->clear();
4911 return liveRange;
4912 }
4913 }
4914 return liveRange;
4915}
virtual EdgeSet rootGraphOutEdges(const Node &node) const
bool queueRawPredecessors(NodeSet &queue, NodeSet &finalDest, NodeSet &predQueue, NodeSet &predFinalDest, bool guard) const
DataDependenceGraph::NodeSet reads
Definition LiveRange.hh:40
void clear()
Definition LiveRange.cc:129
DataDependenceGraph::NodeSet guards
Definition LiveRange.hh:41
DataDependenceGraph::NodeSet writes
Definition LiveRange.hh:39

References assert, LiveRange::clear(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), LiveRange::guards, DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), DataDependenceEdge::headPseudo(), DataDependenceEdge::isBackEdge(), TTAProgram::Move::isUnconditional(), MoveNode::move(), queueRawPredecessors(), LiveRange::reads, BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdges(), DataDependenceEdge::tailPseudo(), and LiveRange::writes.

Referenced by RegisterRenamer::renameDestinationRegister(), and RegisterRenamer::renameSourceRegister().

Here is the call graph for this function:

◆ findLoopIndexInit()

MoveNode * DataDependenceGraph::findLoopIndexInit ( MoveNode updateMove)

Definition at line 4755 of file DataDependenceGraph.cc.

4755 {
4756
4757 DataDependenceEdge* initEdge = NULL;
4758 EdgeSet iEdges = rootGraphInEdges(updateMove);
4759 for (EdgeSet::iterator i=iEdges.begin(); i != iEdges.end(); i++) {
4760 DataDependenceEdge* e = *i;
4763 !e->isBackEdge()) {
4764 if (initEdge != NULL) {
4765 return NULL;
4766 } else {
4767 initEdge = e;
4768 }
4769 }
4770 }
4771 if (initEdge == NULL) {
4772 return NULL;
4773 }
4774 return &rootGraph()->tailNode(*initEdge);
4775}
virtual EdgeSet rootGraphInEdges(const Node &node) const

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::isBackEdge(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdges(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Here is the call graph for this function:

◆ findLoopIndexUpdate()

std::pair< MoveNode *, int > DataDependenceGraph::findLoopIndexUpdate ( MoveNode indexMove)

Definition at line 4704 of file DataDependenceGraph.cc.

4704 {
4705 while (indexMove->isSourceVariable()) {
4706 indexMove = onlyRegisterRawSource(*indexMove);
4707 if (indexMove == NULL) {
4708 return std::pair<MoveNode*, int>(NULL,0);
4709 }
4710 }
4711 if (indexMove->isSourceOperation()) {
4712 ProgramOperation* po = &indexMove->sourceOperation();
4713 if (po->operation().name() == "ADD" ||
4714 po->operation().name() == "SUB") {
4715 MoveNodeSet& input1Set = po->inputNode(1);
4716 MoveNodeSet& input2Set = po->inputNode(2);
4717 if (input1Set.count() != 1 || input2Set.count() != 1) {
4718 return std::pair<MoveNode*, int>(NULL,0);
4719 //return NULL;
4720 }
4721 MoveNode& input1 = input1Set.at(0);
4722 MoveNode& input2 = input2Set.at(0);
4723 MoveNode* oldIndex = NULL;
4724 MoveNode* val = NULL;
4725 if (input1.move().source().isGPR() &&
4726 input2.move().source().isImmediate()) {
4727 oldIndex = &input1;
4728 val = &input2;
4729 } else if (input2.move().source().isGPR() &&
4730 input1.move().source().isImmediate()) {
4731 oldIndex = &input2;
4732 val = &input1;
4733 } else {
4734 return std::pair<MoveNode*, int>(NULL,0);
4735 }
4736 while (oldIndex->isSourceVariable()) {
4737 oldIndex = onlyRegisterRawSource(*oldIndex);
4738 if (oldIndex == NULL) {
4739 return std::pair<MoveNode*, int>(NULL,0);
4740 }
4741 }
4742 if (oldIndex->isSourceOperation()) {
4743 if (&oldIndex->sourceOperation() == po) {
4744 int value = (po->operation().name() == "SUB") ?
4745 -val->move().source().value().intValue() :
4746 val->move().source().value().intValue();
4747 return std::pair<MoveNode*, int>(oldIndex, value);
4748 }
4749 }
4750 }
4751 }
4752 return std::pair<MoveNode*, int>(NULL,0);
4753}
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
int count() const
MoveNode & at(int index)
bool isSourceVariable() const
Definition MoveNode.cc:196
virtual TCEString name() const
Definition Operation.cc:93
const Operation & operation() const
MoveNodeSet & inputNode(int in) const
int intValue() const
Definition SimValue.cc:895
virtual SimValue value() const
Definition Terminal.cc:178
virtual bool isImmediate() const
Definition Terminal.cc:63

References MoveNodeSet::at(), MoveNodeSet::count(), ProgramOperation::inputNode(), SimValue::intValue(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), MoveNode::move(), Operation::name(), onlyRegisterRawSource(), ProgramOperation::operation(), TTAProgram::Move::source(), MoveNode::sourceOperation(), and TTAProgram::Terminal::value().

Here is the call graph for this function:

◆ findLoopLimitAndIndex()

std::pair< MoveNode *, MoveNode * > DataDependenceGraph::findLoopLimitAndIndex ( MoveNode jumpMove)

Finds the move which writes the loop limit comparison value into the loop comparison operation.

If cannot find, returs null.

Assumes positively-gworing loop with ne (or eq + xor 1) as end condition. (llvm creates this kind of loops)

Parameters
jumpMovejump move of a loop.
Returns
loop limit move or NULL of not found.

Definition at line 4618 of file DataDependenceGraph.cc.

4618 {
4619
4620 MoveNode* guardDef = onlyGuardDefOfMove(jumpMove);
4621 if (guardDef == NULL) {
4622 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4623 }
4624 while (guardDef->isSourceVariable()) {
4625 guardDef = onlyRegisterRawSource(*guardDef);
4626 if (guardDef == NULL) {
4627 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4628 }
4629 }
4630 if (guardDef->isSourceOperation()) {
4631 ProgramOperation* gdpo = &guardDef->sourceOperation();
4632 bool inverted = jumpMove.move().guard().isInverted();
4633
4634 // machine does not have ne operation so eq + xor used.
4635 if (gdpo->operation().name() == "XOR") {
4636 MoveNodeSet& input1Set = gdpo->inputNode(1);
4637 MoveNodeSet& input2Set = gdpo->inputNode(2);
4638 if (input1Set.count() != 1 || input2Set.count() != 1) {
4639 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4640 }
4641 MoveNode& input1 = input1Set.at(0);
4642 MoveNode& input2 = input2Set.at(0);
4643
4644 MoveNode *regMove = NULL;
4645 if (input1.move().source().isGPR() &&
4646 input2.move().source().isImmediate()) {
4647 regMove = &input1;
4648 }
4649
4650 if (input2.move().source().isGPR() &&
4651 input1.move().source().isImmediate()) {
4652 regMove = &input2;
4653 }
4654
4655 // bypassed directly from eq?
4656 if (input1.isSourceOperation() &&
4657 input2.move().source().isImmediate()) {
4658 gdpo = &input1.sourceOperation();
4659 } else {
4660 if (input2.isSourceOperation() &&
4661 input1.move().source().isImmediate()) {
4662 gdpo = &input2.sourceOperation();
4663 } else { // not bypassed.
4664 if (regMove != NULL) {
4665 MoveNode* xorSrc = onlyRegisterRawSource(*regMove);
4666 if (xorSrc != NULL && xorSrc->isSourceOperation()) {
4667 inverted = !inverted;
4668 gdpo = &xorSrc->sourceOperation();
4669 } else {
4670 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4671 }
4672 } else {
4673 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4674 }
4675 }
4676 }
4677 }
4678
4679 if ((gdpo->operation().name() == "NE" && !inverted) ||
4680 (gdpo->operation().name() == "EQ" && inverted)) {
4681 MoveNodeSet& input1Set = gdpo->inputNode(1);
4682 MoveNodeSet& input2Set = gdpo->inputNode(2);
4683 if (input1Set.count() != 1 || input2Set.count() != 1) {
4684 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4685 }
4686 MoveNode& input1 = input1Set.at(0);
4687 MoveNode& input2 = input2Set.at(0);
4688 if ((input1.move().source().isGPR() ||
4689 input1.isSourceOperation()) &&
4690 input2.move().source().isImmediate()) {
4691 return std::pair<MoveNode*, MoveNode*>(&input2, &input1);
4692 }
4693 if ((input2.move().source().isGPR() ||
4694 input2.isSourceOperation()) &&
4695 input1.move().source().isImmediate()) {
4696 return std::pair<MoveNode*, MoveNode*>(&input1, &input2);
4697 }
4698 }
4699 }
4700 return std::pair<MoveNode*, MoveNode*>(NULL, NULL);
4701}
MoveNode * onlyGuardDefOfMove(MoveNode &moveNode)

References MoveNodeSet::at(), MoveNodeSet::count(), TTAProgram::Move::guard(), ProgramOperation::inputNode(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), TTAProgram::MoveGuard::isInverted(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), MoveNode::move(), Operation::name(), onlyGuardDefOfMove(), onlyRegisterRawSource(), ProgramOperation::operation(), TTAProgram::Move::source(), and MoveNode::sourceOperation().

Referenced by BUBasicBlockScheduler::handleLoopDDG(), and BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ firstRegisterCycle()

int DataDependenceGraph::firstRegisterCycle ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the lowest cycle where accesses the given register. If unscheudled moves accessing the register, returns -1. If none found, return INT_MAX

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
cycle, or -1 if some unscheduled found, or INT_MAX if none found.

Definition at line 981 of file DataDependenceGraph.cc.

982 {
983
984 int firstCycle = INT_MAX;
985 for (int i = nodeCount()-1; i >= 0; --i) {
986 MoveNode& n = node(i);
987 TTAProgram::Move& move = n.move();
988 const TTAMachine::BaseRegisterFile* currentRF = NULL;
989
990 // check source
991 TTAProgram::Terminal& source = move.source();
992 bool sourceImmReg = source.isImmediateRegister();
993 bool sourceGPR = source.isGPR();
994
995 if (sourceImmReg || sourceGPR) {
996
997 if (sourceImmReg)
998 currentRF = &source.immediateUnit();
999 else
1000 currentRF = &source.registerFile();
1001
1002 if (&rf == currentRF && source.index() == registerIndex) {
1003 if (!n.isPlaced()) {
1004 return -1;
1005 }
1006 if (n.cycle() < firstCycle) {
1007 firstCycle = n.cycle();
1008 }
1009 }
1010 }
1011
1012 // check destination
1013 TTAProgram::Terminal& destination = move.destination();
1014 if (destination.isGPR()) {
1015 currentRF = &destination.registerFile();
1016
1017 if (&rf == currentRF && destination.index() == registerIndex) {
1018 if (!n.isPlaced()) {
1019 return -1;
1020 }
1021 if (n.cycle() < firstCycle) {
1022 firstCycle = n.cycle();
1023 }
1024 // this is a write of (constant) into reg, and no antideps in?
1025 if (move.isUnconditional()) {
1026 if (inDegree(n) == 0) {
1027 assert(firstCycle == n.cycle());
1028 return firstCycle;
1029 }
1030 }
1031 }
1032 }
1033
1034 // check guard.
1035 if (!move.isUnconditional()) {
1036 const TTAMachine::Guard& guard = move.guard().guard();
1037 const TTAMachine::RegisterGuard* rg =
1038 dynamic_cast<const TTAMachine::RegisterGuard*>(&guard);
1039 if (rg != NULL) {
1040 if (rg->registerFile() == &rf &&
1041 rg->registerIndex() == registerIndex) {
1042 if (!n.isPlaced()) {
1043 return -1;
1044 }
1045 if (n.cycle() < firstCycle) {
1046 firstCycle = n.cycle();
1047 }
1048 }
1049 }
1050 }
1051 if (move.isFunctionCall()) {
1052 const TTAMachine::RegisterFile* rrf =
1053 dynamic_cast<const TTAMachine::RegisterFile*>(&rf);
1054 assert(rrf != NULL);
1055 TCEString reg =
1056 DisassemblyRegister::registerName(*rrf, registerIndex);
1057 if (allParamRegs_.find(reg) != allParamRegs_.end()) {
1058 if (!n.isPlaced()) {
1059 return -1;
1060 }
1061 if (n.cycle() + delaySlots_ < firstCycle) {
1062 firstCycle = n.cycle() + delaySlots_ ;
1063 }
1064 }
1065 }
1066 }
1067 return firstCycle;
1068}
bool isFunctionCall() const
Definition Move.cc:219
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240

References allParamRegs_, assert, MoveNode::cycle(), delaySlots_, TTAProgram::Move::destination(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAProgram::Terminal::immediateUnit(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), TTAProgram::Terminal::index(), TTAProgram::Move::isFunctionCall(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DisassemblyRegister::registerName(), and TTAProgram::Move::source().

Referenced by RegisterRenamer::findPartiallyUsedRegistersAfterCycle(), and RegisterRenamer::findPartiallyUsedRegistersInRFAfterCycle().

Here is the call graph for this function:

◆ firstScheduledRegisterKill()

MoveNode * DataDependenceGraph::firstScheduledRegisterKill ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the MoveNode of unconditional move with highest cycle that writes the given register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The MoveNode, NULL, if not found.

Definition at line 1320 of file DataDependenceGraph.cc.

1321 {
1322
1323 int firstCycle = INT_MAX;
1324 MoveNode* firstFound = NULL;
1325 int nodeCounter = nodeCount();
1326 for (int i = 0; i < nodeCounter; ++i) {
1327 MoveNode& n = node(i);
1328
1330 if (!n.isPlaced() || !dest.isGPR())
1331 continue;
1332
1333 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1334 currentRF = &dest.registerFile();
1335
1336 if (&rf == currentRF &&
1337 dest.index() == registerIndex &&
1338 n.cycle() < firstCycle &&
1339 n.move().isUnconditional()) {
1340 firstCycle = n.cycle();
1341 firstFound = &n;
1342 }
1343 }
1344 return firstFound;
1345}

References MoveNode::cycle(), TTAProgram::Move::destination(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), and TTAProgram::Terminal::registerFile().

Referenced by RegisterCopyAdder::createAntidepsForReg(), firstScheduledRegisterReads(), and firstScheduledRegisterWrites().

Here is the call graph for this function:

◆ firstScheduledRegisterRead()

MoveNode * DataDependenceGraph::firstScheduledRegisterRead ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex,
int  firstCycleToTest = 0 
) const

Returns the MoveNode with lowest cycle that reads the given register.

Parameters
rfThe register file.
registerIndexIndex of the register.
firstCycleToTestoptional argument from which cycle to start search.
Returns
The MoveNode, NULL, if not found.

Definition at line 808 of file DataDependenceGraph.cc.

810 {
811
812 int firstCycle = INT_MAX;
813 MoveNode* firstFound = NULL;
814 for (int i = 0; i < nodeCount(); ++i) {
815 MoveNode& n = node(i);
816
817 TTAProgram::Terminal& source = n.move().source();
818 if (!n.isPlaced() ||
819 !(source.isImmediateRegister() || source.isGPR()))
820 continue;
821
822 const TTAMachine::BaseRegisterFile* currentRF = NULL;
823 if (source.isImmediateRegister())
824 currentRF = &source.immediateUnit();
825 else
826 currentRF = &source.registerFile();
827
828 if (&rf == currentRF &&
829 source.index() == registerIndex &&
830 n.cycle() < firstCycle &&
831 n.cycle() >= firstCycleToTest) {
832 firstCycle = n.cycle();
833 firstFound = &n;
834 }
835 }
836 return firstFound;
837}

References MoveNode::cycle(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Terminal::registerFile(), and TTAProgram::Move::source().

Referenced by BUBasicBlockScheduler::bypassNode(), and BUBasicBlockScheduler::scheduleInputOperandTempMoves().

Here is the call graph for this function:

◆ firstScheduledRegisterReads()

DataDependenceGraph::NodeSet DataDependenceGraph::firstScheduledRegisterReads ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the set of MoveNodes which reads given register before first unconditional scheduled write to the register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The set of movenodes.

Definition at line 1121 of file DataDependenceGraph.cc.

1122 {
1123
1124 MoveNode* firstKill = firstScheduledRegisterKill(rf, registerIndex);
1125 int killCycle = firstKill == NULL ? -1 : firstKill->cycle();
1126 NodeSet firstReads;
1127
1128 // first search last kill.
1129 for (int i = 0; i < nodeCount(); ++i) {
1130 MoveNode& n = node(i);
1131
1132 TTAProgram::Terminal& source = n.move().source();
1133 if (!n.isPlaced() ||
1134 !(source.isImmediateRegister() || source.isGPR()))
1135 continue;
1136
1137 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1138 if (source.isImmediateRegister())
1139 currentRF = &source.immediateUnit();
1140 else
1141 currentRF = &source.registerFile();
1142
1143 if (&rf == currentRF &&
1144 source.index() == registerIndex) {
1145 if (n.cycle() < killCycle) {
1146 firstReads.insert(&n);
1147 }
1148 }
1149 }
1150 return firstReads;
1151}
MoveNode * firstScheduledRegisterKill(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const

References MoveNode::cycle(), firstScheduledRegisterKill(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Terminal::registerFile(), and TTAProgram::Move::source().

Here is the call graph for this function:

◆ firstScheduledRegisterWrite()

MoveNode * DataDependenceGraph::firstScheduledRegisterWrite ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the MoveNode with lowest cycle that writes the given register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The MoveNode, NULL, if not found.

Definition at line 847 of file DataDependenceGraph.cc.

848 {
849
850 int firstCycle = INT_MAX;
851 MoveNode* firstFound = NULL;
852 for (int i = 0; i < nodeCount(); ++i) {
853 MoveNode& n = node(i);
854
855 TTAProgram::Terminal& destination = n.move().destination();
856 if (!n.isPlaced() || !destination.isGPR())
857 continue;
858
859 const TTAMachine::BaseRegisterFile* currentRF = NULL;
860 currentRF = &destination.registerFile();
861
862 if (&rf == currentRF &&
863 destination.index() == registerIndex &&
864 n.cycle() < firstCycle) {
865 firstCycle = n.cycle();
866 firstFound = &n;
867 }
868 }
869 return firstFound;
870}

References MoveNode::cycle(), TTAProgram::Move::destination(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), and TTAProgram::Terminal::registerFile().

Referenced by BUBasicBlockScheduler::scheduleOperand(), BUBasicBlockScheduler::scheduleResultReads(), BUBasicBlockScheduler::scheduleResultReadTempMoves(), and BUBasicBlockScheduler::scheduleRRTempMoves().

Here is the call graph for this function:

◆ firstScheduledRegisterWrites()

DataDependenceGraph::NodeSet DataDependenceGraph::firstScheduledRegisterWrites ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the set of MoveNodes which writes given register after last unconditional scheduled write to the register, and the last unconditional write.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The set of movenodes.

Definition at line 1245 of file DataDependenceGraph.cc.

1246 {
1247
1248 // TODO: should this be able to be calculated from LR bookkeeping?
1249
1250 MoveNode* firstKill = firstScheduledRegisterKill(rf, registerIndex);
1251 int killCycle = firstKill == NULL ? INT_MAX : firstKill->cycle();
1252 NodeSet firstWrites;
1253
1254 int nodeCounter = nodeCount();
1255 // first search last kill.
1256 for (int i = 0; i < nodeCounter; ++i) {
1257 MoveNode& n = node(i);
1258
1260 if (!n.isPlaced() || !dest.isGPR())
1261 continue;
1262
1263 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1264 currentRF = &dest.registerFile();
1265
1266 if (&rf == currentRF &&
1267 dest.index() == registerIndex) {
1268 if (n.cycle() <= killCycle) {
1269 firstWrites.insert(&n);
1270 }
1271 }
1272 }
1273 return firstWrites;
1274}

References MoveNode::cycle(), TTAProgram::Move::destination(), firstScheduledRegisterKill(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), and TTAProgram::Terminal::registerFile().

Referenced by RegisterCopyAdder::createAntidepsForReg(), BFRegCopy::createAntidepsForReg(), BFRenameLiveRange::renameLiveRange(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ fixAntidepsAfterLoopUnmergeUser()

void DataDependenceGraph::fixAntidepsAfterLoopUnmergeUser ( MoveNode sourceNode,
MoveNode mergedNode,
const TCEString reg 
)

Definition at line 2213 of file DataDependenceGraph.cc.

2213 {
2214 for (int i = 0; i < outDegree(mergedNode); i++) {
2215 DataDependenceEdge& edge = outEdge(mergedNode,i);
2216 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2217 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
2218 edge.data() == reg) {
2219 return;
2220 }
2221 }
2222 DataDependenceEdge* newEdge =
2225 reg, false, false, false, false, false);
2226 connectNodes(mergedNode, sourceNode, *newEdge);
2227}

References BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::DEP_WAR, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdge().

Referenced by unMergeUser().

Here is the call graph for this function:

◆ fixInterBBAntiEdges()

void DataDependenceGraph::fixInterBBAntiEdges ( BasicBlockNode bbn1,
BasicBlockNode bbn2,
bool  loopEdges 
)

Addds inter-BB-Anti edges between the the basic blocks.

currently quite a heavy routine

Parameters
bbn1first basic block, executed first, sources of antidependence edges
bbn2second basic block, executed later, targets of antidependence edges

Definition at line 3689 of file DataDependenceGraph.cc.

3690 {
3691 std::map<TCEString, TTAProgram::Move*> firstWrites2;
3692 std::map<TCEString, TTAProgram::Move*> lastReads1;
3693 std::map<TCEString, TTAProgram::Move*> lastWrites1;
3694 std::map<TCEString, TTAProgram::Move*> lastGuards1;
3695
3696 TTAProgram::BasicBlock& bb1 = bbn1.basicBlock();
3697 TTAProgram::BasicBlock& bb2 = bbn2.basicBlock();
3698
3699 // find the first writes in the next BB.
3700 for (int i2 = 0; i2 < bb2.instructionCount(); i2++) {
3702 for (int j2 = 0; j2 < ins.moveCount(); j2++) {
3703 TTAProgram::Move& move = ins.move(j2);
3704 TTAProgram::Terminal& dest = move.destination();
3705 if (dest.isGPR()) {
3707
3708 std::map<TCEString, TTAProgram::Move*>::iterator iter2 =
3709 firstWrites2.find(reg2);
3710 if (iter2 == firstWrites2.end()) {
3711 firstWrites2[reg2] = &move;
3712 }
3713 }
3714 }
3715 }
3716
3717 // find the last reads, writes and guard uses from first BB.
3718 for (int i1 = bb1.instructionCount()-1; i1 >= 0 ; i1--) {
3720 for (int j1 = 0; j1 < ins.moveCount(); j1++) {
3721 TTAProgram::Move& move = ins.move(j1);
3722 TTAProgram::Terminal& dest = move.destination();
3723 TTAProgram::Terminal& src = move.source();
3724 // Writes for WaWs
3725 if (dest.isGPR()) {
3727
3728 std::map<TCEString, TTAProgram::Move*>::iterator iter1 =
3729 lastWrites1.find(reg1);
3730 if (iter1 == lastWrites1.end()) {
3731 lastWrites1[reg1] = &move;
3732 }
3733 }
3734 // reads for WaRs
3735 if (src.isGPR()) {
3737
3738 std::map<TCEString, TTAProgram::Move*>::iterator iter1 =
3739 lastReads1.find(reg1);
3740 if (iter1 == lastReads1.end()) {
3741 lastReads1[reg1] = &move;
3742 }
3743 }
3744 // guard uses
3745 if (!move.isUnconditional()) {
3746 const TTAMachine::Guard& g = move.guard().guard();
3747 const TTAMachine::RegisterGuard* rg =
3748 dynamic_cast<const TTAMachine::RegisterGuard*>(&g);
3749 if (rg != NULL) {
3751 *rg->registerFile(), rg->registerIndex());
3752
3753 std::map<TCEString, TTAProgram::Move*>::iterator iter2 =
3754 lastGuards1.find(reg1);
3755 if (iter2 == lastGuards1.end()) {
3756 lastGuards1[reg1] = &move;
3757 }
3758 }
3759 }
3760 }
3761 }
3762
3763 // then go thru them
3764 for (std::map<TCEString, TTAProgram::Move*>::iterator iter2 =
3765 firstWrites2.begin();
3766 iter2 != firstWrites2.end(); iter2++) {
3767 const TCEString& reg2 = iter2->first;
3768 MoveNode& mn2 = nodeOfMove(*(iter2->second));
3769
3770 // WaRs
3771 TTAProgram::Move* move1 = lastReads1[reg2];
3772 if (move1 != NULL) {
3776 DataDependenceEdge::DEP_WAR, reg2, false, false, false,
3777 false, loopEdges);
3778 connectOrDeleteEdge(nodeOfMove(*move1), mn2, edge);
3779 }
3780
3781 // WaWs
3782 move1 = lastWrites1[reg2];
3783 if (move1 != NULL) {
3787 DataDependenceEdge::DEP_WAW, reg2, false, false, false,
3788 false, loopEdges);
3789 connectOrDeleteEdge(nodeOfMove(*move1), mn2, edge);
3790 }
3791
3792 // guard WaRs
3793 move1 = lastGuards1[reg2];
3794 if (move1 != NULL) {
3798 DataDependenceEdge::DEP_WAR, reg2, true, false, false,
3799 false, loopEdges);
3800 connectOrDeleteEdge(nodeOfMove(*move1), mn2, edge);
3801 }
3802 }
3803}
TTAProgram::BasicBlock & basicBlock()
MoveNode & nodeOfMove(const TTAProgram::Move &move)
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
Move & move(int i) const

References BasicBlockNode::basicBlock(), connectOrDeleteEdge(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isUnconditional(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), nodeOfMove(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DisassemblyRegister::registerName(), and TTAProgram::Move::source().

Referenced by ControlFlowGraph::mergeNodes().

Here is the call graph for this function:

◆ getBasicBlockNode() [1/2]

const BasicBlockNode & DataDependenceGraph::getBasicBlockNode ( const MoveNode mn) const

Gives the basic block node where the node belongs to.

Parameters
mnMoveNode whose basic block we are asking
Returns
BasicBlockNode of the move

Definition at line 186 of file DataDependenceGraph.cc.

186 {
187 std::map<const MoveNode*, BasicBlockNode*>::const_iterator iter =
188 moveNodeBlocks_.find(&mn);
189 if (iter == moveNodeBlocks_.end()) {
190 TCEString msg = "MoveNode not in DDG!: ";
191 msg += mn.toString();
192 throw InvalidData(__FILE__,__LINE__,__func__,msg);
193 }
194 return *iter->second;
195}

References __func__, moveNodeBlocks_, and MoveNode::toString().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies(), RegisterCopyAdder::addConnectionRegisterCopiesImmediate(), addNode(), CopyingDelaySlotFiller::checkIncomingDeps(), copyDependencies(), copyExternalInEdges(), copyExternalOutEdges(), ProgramDependenceGraph::copyRegionEECComponent(), LoopAnalyzer::findEndCond(), BF2Scheduler::handleLoopDDG(), PreOptimizer::inverseGuardsOfHeads(), BFRegCopy::operator()(), ProgramDependenceGraph::ProgramDependenceGraph(), BF2Scheduler::revertBBLiveRangeBookkeepingForDestination(), BF2Scheduler::revertBBLiveRangeBookkeepingForSource(), PreOptimizer::tryToOptimizeAddressReg(), and updateRegWrite().

Here is the call graph for this function:

◆ getBasicBlockNode() [2/2]

BasicBlockNode & DataDependenceGraph::getBasicBlockNode ( MoveNode mn)

Gives the basic block node where the node belongs to.

Parameters
mnMoveNode whose basic block we are asking
Returns
BasicBlockNode of the move

Definition at line 204 of file DataDependenceGraph.cc.

204 {
205 std::map<const MoveNode*, BasicBlockNode*>::iterator iter =
206 moveNodeBlocks_.find(&mn);
207 if (iter == moveNodeBlocks_.end()) {
208 TCEString msg = "MoveNode not in DDG!: ";
209 msg += mn.toString();
210 throw InvalidData(__FILE__,__LINE__,__func__,msg);
211 }
212 return *iter->second;
213}

References __func__, moveNodeBlocks_, and MoveNode::toString().

Here is the call graph for this function:

◆ getOperationLatency()

int DataDependenceGraph::getOperationLatency ( const TCEString name) const
private

Gets the lowest instruction latency for given operation.

If latency is not known (no machine is given) does some simple heuristics.

This function should propably be on somewhere else.

Parameters
opoperation whose minimum latency is being searched
Returns
minimum latency of given operation.

Definition at line 3304 of file DataDependenceGraph.cc.

3304 {
3305 std::map<TCEString, int>::const_iterator iter =
3307 if (iter != operationLatencies_.end()) {
3308 return iter->second;
3309 } else {
3310 return 1;
3311 }
3312}
std::map< TCEString, int > operationLatencies_

References BoostGraph< MoveNode, DataDependenceEdge >::name(), and operationLatencies_.

Referenced by earliestCycle(), edgeLatency(), edgeWeight(), and latestCycle().

Here is the call graph for this function:

◆ guardConverted()

void DataDependenceGraph::guardConverted ( MoveNode guardSrc,
MoveNode dst 
)

Definition at line 5795 of file DataDependenceGraph.cc.

5795 {
5796 // similar than mergeAndKeepDestination
5797 ProgramOperationPtr srcPO = guardSrc.sourceOperationPtr();
5798 srcPO->addGuardOutputNode(dst);
5799 dst.setGuardOperationPtr(srcPO);
5800
5801 TCEString regName = removeRAWEdges(guardSrc, dst);
5802
5803 for (int i = 0; i < rootGraphInDegree(guardSrc); i++) {
5804 DataDependenceEdge& edge = rootGraphInEdge(guardSrc ,i);
5805 // skip antidependencies due bypassed register.. these are no more
5806 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
5807 edge.data() == regName) {
5808 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW ||
5809 edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
5810 continue;
5811 }
5812 }
5813 assert(!edge.guardUse());
5814 if (edge.edgeReason() != DataDependenceEdge::EDGE_OPERATION) {
5815 std::cerr << "Warning: non-operation edge: " << edge.toString()
5816 << " on guard bypass" << std::endl;
5817 continue;
5818 }
5819
5820 // copy other edges. (operation inputs)
5821 MoveNode& source = rootGraph()->tailNode(edge);
5822 DataDependenceEdge* newEdge =
5826
5827 rootGraph()->connectNodes(source, dst, *newEdge);
5828 }
5829
5830
5831 // remove WAR antideps out from this
5832 for (int i = 0; i < rootGraphOutDegree(dst); i++) {
5834
5835 // create new WaW in place of old WaR
5836 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
5837 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
5838 edge.data() == regName && edge.guardUse()) {
5839
5840 // and remove the old WaR
5841 (static_cast<DataDependenceGraph*>(rootGraph()))->
5842 removeEdge(edge, &dst, NULL);
5843 i--; // don't skip one edge here!
5844 }
5845 }
5846}
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
virtual int rootGraphInDegree(const Node &node) const
virtual int rootGraphOutDegree(const Node &node) const
virtual Edge & rootGraphInEdge(const Node &node, const int index) const
virtual Edge & rootGraphOutEdge(const Node &node, const int index) const
TCEString removeRAWEdges(MoveNode &sourceNode, MoveNode &userNode)
void setGuardOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:550

References assert, BoostGraph< GraphNode, GraphEdge >::connectNodes(), DataDependenceEdge::DEP_UNKNOWN, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), removeRAWEdges(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdge(), MoveNode::setGuardOperationPtr(), MoveNode::sourceOperationPtr(), BoostGraph< GraphNode, GraphEdge >::tailNode(), and GraphEdge::toString().

Referenced by BFLateBypassGuard::operator()(), and BFEarlyGuardBypass::operator()().

Here is the call graph for this function:

◆ guardDefMoves()

DataDependenceGraph::NodeSet DataDependenceGraph::guardDefMoves ( const MoveNode moveNode)

Returns all movenodes that define (write the value of) the guard the given move node is predicated with.

Parameters
moveNodeThe move node of which guard defining move to find.
Returns
The MoveNodes that produces the guard value. Can be multiple if the writes are predicated or in different BB. If not found, returns NULL

Definition at line 743 of file DataDependenceGraph.cc.

743 {
744
746 EdgeSet inputEdges = inEdges(moveNode);
747 for (EdgeSet::iterator i = inputEdges.begin();
748 i != inputEdges.end(); i++) {
750 if (edge.guardUse() &&
751 edge.dependenceType() == DataDependenceEdge::DEP_RAW) {
752 guardDefMoves.insert(&tailNode(edge));
753 }
754 }
755 return guardDefMoves;
756}
NodeSet guardDefMoves(const MoveNode &moveNode)

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), guardDefMoves(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by guardDefMoves(), guardsAllowBypass(), lastGuardDefMove(), onlyGuardDefOfMove(), and BasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ guardRawPredecessors()

DataDependenceGraph::NodeSet DataDependenceGraph::guardRawPredecessors ( const MoveNode node) const

Definition at line 4048 of file DataDependenceGraph.cc.

4048 {
4049 NodeSet preds;
4051 for (DataDependenceGraph::EdgeSet::iterator i = iEdges.begin();
4052 i != iEdges.end(); i++) {
4053 DataDependenceEdge* iEdge = *i;
4054 if (iEdge->guardUse() && iEdge->dependenceType() ==
4056 preds.insert(&tailNode(*iEdge));
4057 }
4058 }
4059 return preds;
4060}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by exclusingGuards(), and sameGuards().

Here is the call graph for this function:

◆ guardRenamed()

DataDependenceGraph::UndoData DataDependenceGraph::guardRenamed ( MoveNode mn)

Definition at line 5006 of file DataDependenceGraph.cc.

5006 {
5007
5008 UndoData undoData;
5009
5010 assert(!mn.move().isUnconditional());
5011 const TTAMachine::RegisterGuard* rg =
5012 dynamic_cast<const TTAMachine::RegisterGuard*>(
5013 &mn.move().guard().guard());
5014 assert(rg != NULL);
5015 const TCEString newReg = rg->registerFile()->name() +
5017
5018 for (int i = 0; i < outDegree(mn); i++) {
5019 DataDependenceEdge& oEdge = outEdge(mn,i);
5020
5023 !oEdge.tailPseudo() && oEdge.guardUse()) {
5024
5025 MoveNode& head = headNode(oEdge);
5026 TTAProgram::Terminal& writeTerm = head.move().destination();
5027
5028 // if this edge disappers because of the renaming?
5029 if (oEdge.headPseudo() ||
5030 (writeTerm.isGPR() && (
5031 writeTerm.index() != rg->registerIndex() ||
5032 &writeTerm.registerFile() != rg->registerFile()))) {
5033 undoData.removedEdges.insert(RemovedEdgeDatum(mn, head, oEdge));
5034 removeEdge(oEdge, NULL, &mn);
5035 i--; // don't skip one edge here!
5036 } else {
5037 // update the edge. also other end changed
5038 undoData.changedDataEdges[&oEdge] = oEdge.data();
5039 oEdge.setData(newReg);
5040 }
5041 }
5042 }
5043 return undoData;
5044}
static std::string toString(const T &source)
virtual TCEString name() const

References assert, DataDependenceGraph::UndoData::changedDataEdges, DataDependenceEdge::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isUnconditional(), MoveNode::move(), TTAMachine::Component::name(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DataDependenceGraph::UndoData::removedEdges, BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), DataDependenceEdge::setData(), DataDependenceEdge::tailPseudo(), and Conversion::toString().

Referenced by BFRenameLiveRange::renameLiveRange(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ guardRestored()

void DataDependenceGraph::guardRestored ( MoveNode guardSrc,
MoveNode dst 
)

Definition at line 5849 of file DataDependenceGraph.cc.

5849 {
5850 // similar than mergeAndKeepDestination
5851 ProgramOperation& srcPO = guardSrc.sourceOperation();
5852 srcPO.removeGuardOutputNode(dst);
5853 dst.unsetGuardOperation();
5854
5855 // remove the incoming guard operation edges.
5856 for (int i = 0; i < inDegree(dst); i++) {
5857 DataDependenceEdge& edge = inEdge(dst,i);
5858 if (edge.guardUse() &&
5859 edge.edgeReason() == DataDependenceEdge::EDGE_OPERATION) {
5860 removeEdge(edge, &dst, NULL);
5861 i--;
5862 }
5863 }
5864
5865 // name of the bypass reg.
5866 TTAProgram::Terminal& dest = guardSrc.move().destination();
5867 assert(dest.isGPR());
5869
5870 // create register edge between nodes.
5871 // this was removed by the merge.
5875 true, false, false, false);
5876 connectNodes(guardSrc, dst, *dde);
5877
5878 // TODO: restore the guard antidep edges.
5879
5880 // All all outgoing WAR's to merged node. The war's go to
5881 // all same places where WAW's fo from source node.
5882 for (int i = 0; i < outDegree(guardSrc); i++) {
5883 DataDependenceEdge& edge = outEdge(guardSrc,i);
5884 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
5885 edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
5886 edge.data() == regName) {
5887 MoveNode& head = headNode(edge);
5888 // skip nodes with exclusive guard.
5891 DataDependenceEdge::DEP_WAR, regName, true, false,
5892 false, edge.headPseudo(), edge.loopDepth());
5893 connectNodes(dst, head, *newEdge);
5894 }
5895 }
5896}
void unsetGuardOperation()
Definition MoveNode.cc:771
void removeGuardOutputNode(MoveNode &node)

References assert, BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), TTAProgram::Terminal::isGPR(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), DisassemblyRegister::registerName(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), ProgramOperation::removeGuardOutputNode(), MoveNode::sourceOperation(), and MoveNode::unsetGuardOperation().

Referenced by BFLateBypassGuard::operator()(), BFLateBypassGuard::undoOnlyMe(), and BFEarlyGuardBypass::undoOnlyMe().

Here is the call graph for this function:

◆ guardsAllowBypass()

bool DataDependenceGraph::guardsAllowBypass ( const MoveNode defNode,
const MoveNode useNode,
bool  loopBypass = false 
)

Checks whether guards allow bypassing.

Parameters
defNodenode defining a value, bypass source.
useNodenode using the value, node being bypassed.
Returns
true if guards do not prevent bypassing.

Definition at line 4543 of file DataDependenceGraph.cc.

4544 {
4545
4546 // can always bypass from unconditional
4547 if (defNode.move().isUnconditional()) {
4548 return true;
4549 }
4550
4551 // cannot bypass from conditional to unconditional
4552 if (useNode.move().isUnconditional()) {
4553 return false;
4554 }
4555
4556 NodeSet defGuardDefMoves = guardDefMoves(defNode);
4557 NodeSet useGuardDefMoves = guardDefMoves(useNode);
4558
4559 // guard value changed between iterations, cannot trust same src!
4560 // could check the backedge property from the guard edges,
4561 // this is suboptimal and safe
4562 if (loopBypass && !defGuardDefMoves.empty()) {
4563 return false;
4564 }
4565
4566 // if guards defined in different place,
4567 // we do now know if they are equal.
4568 if (defGuardDefMoves != useGuardDefMoves) {
4569 return false;
4570 }
4571
4572 // if guards are equal, bypass allowed.
4573 return defNode.move().guard().guard().isEqual(
4574 useNode.move().guard().guard());
4575}
virtual bool isEqual(const Guard &guard) const =0

References TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), guardDefMoves(), TTAMachine::Guard::isEqual(), TTAProgram::Move::isUnconditional(), and MoveNode::move().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies(), BUBasicBlockScheduler::bypassNode(), CycleLookBackSoftwareBypasser::bypassNode(), and BFLateBypasses::operator()().

Here is the call graph for this function:

◆ hasAllRegisterAntidependencies()

bool DataDependenceGraph::hasAllRegisterAntidependencies ( )
inline

◆ hasEqualEdge()

bool DataDependenceGraph::hasEqualEdge ( const MoveNode tailNode,
const MoveNode headNode,
const DataDependenceEdge edge 
) const
private

Checks if the graph already has an edge with same properties from same node to same node.

Parameters
tailNodetail node of edge
headNodehead node of edge
edgeedge which for to test equality
Returns
true if equal edge exists, false if not exist

Definition at line 3324 of file DataDependenceGraph.cc.

3327 {
3328
3329 typedef GraphTraits::out_edge_iterator outEdgeIter;
3330 std::pair<outEdgeIter, outEdgeIter> edges = boost::out_edges(
3333
3334 for (outEdgeIter ei = edges.first; ei != edges.second; ei++) {
3335 if (boost::target(*ei, graph_) == hnd) {
3336 DataDependenceEdge* dde = graph_[(*ei)];
3337 if (*dde == edge) {
3338 return true;
3339 }
3340 }
3341 }
3342 return false;
3343}

References BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, BoostGraph< MoveNode, DataDependenceEdge >::headNode(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by connectOrDeleteEdge().

Here is the call graph for this function:

◆ hasIntraBBRegisterAntidependencies()

bool DataDependenceGraph::hasIntraBBRegisterAntidependencies ( )
inline

◆ hasOtherRegWawSources()

bool DataDependenceGraph::hasOtherRegWawSources ( const MoveNode mn) const

Definition at line 5701 of file DataDependenceGraph.cc.

5701 {
5702 EdgeSet iEdges = inEdges(mn);
5703 for (auto e: iEdges) {
5704 if (e->edgeReason() != DataDependenceEdge::EDGE_REGISTER ||
5705 e->dependenceType() != DataDependenceEdge::DEP_WAW) {
5706 continue;
5707 }
5708 MoveNode& tail = tailNode(*e);
5709 if (&tail != &mn) {
5710 return true;
5711 }
5712 }
5713 return false;
5714}

References DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Here is the call graph for this function:

◆ hasRegWaw()

bool DataDependenceGraph::hasRegWaw ( const MoveNodeUse mnu,
std::set< MoveNodeUse targets 
) const

Definition at line 5518 of file DataDependenceGraph.cc.

5519 {
5520 NodeDescriptor nd = descriptor(*mnu.mn());
5521
5522 std::pair<OutEdgeIter, OutEdgeIter> edges =
5523 boost::out_edges(nd, graph_);
5524
5525 // loop thru all edges
5526 for (OutEdgeIter ei = edges.first; ei != edges.second; ei++ ) {
5527 EdgeDescriptor ed = *ei;
5529 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
5530 edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
5531 !edge.isBackEdge()) {
5532
5533 MoveNode* target = graph_[boost::target(ed, graph_)];
5534 if (AssocTools::containsKey(targets, MoveNodeUse(*target))) {
5535 return true;
5536 }
5537 }
5538 }
5539 return false;
5540}
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
const MoveNode * mn() const

References AssocTools::containsKey(), DataDependenceEdge::DEP_WAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::graph_, GraphEdge::isBackEdge(), and MoveNodeUse::mn().

Referenced by DataDependenceGraphBuilder::processRegUse().

Here is the call graph for this function:

◆ hasSingleBBLoopRegisterAntidependencies()

bool DataDependenceGraph::hasSingleBBLoopRegisterAntidependencies ( )
inline

◆ hasUnscheduledPredecessors()

bool DataDependenceGraph::hasUnscheduledPredecessors ( const MoveNode mn) const

Definition at line 5594 of file DataDependenceGraph.cc.

5594 {
5595
5597 for (DataDependenceGraph::NodeSet::iterator i = pred.begin();
5598 i != pred.end(); ++i) {
5599 if (!(**i).isPlaced()) {
5600 return true;
5601 }
5602 }
5603 return false;
5604}
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53

References BoostGraph< MoveNode, DataDependenceEdge >::predecessors().

Here is the call graph for this function:

◆ hasUnscheduledSuccessors()

bool DataDependenceGraph::hasUnscheduledSuccessors ( const MoveNode mn) const

Definition at line 5607 of file DataDependenceGraph.cc.

5607 {
5608
5610 for (DataDependenceGraph::NodeSet::iterator i = succ.begin();
5611 i != succ.end(); ++i) {
5612 if (!(**i).isPlaced()) {
5613 return true;
5614 }
5615 }
5616 return false;
5617}
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const

References BoostGraph< MoveNode, DataDependenceEdge >::successors().

Here is the call graph for this function:

◆ isLoopBypass()

bool DataDependenceGraph::isLoopBypass ( MoveNode sourceNode,
MoveNode userNode 
)

Definition at line 1916 of file DataDependenceGraph.cc.

1916 {
1917 EdgeSet edges = connectingEdges(
1918 sourceNode, userNode);
1919
1920 for (EdgeSet::iterator i = edges.begin();
1921 i != edges.end(); i++ ) {
1923 if (edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
1924 edge->isBackEdge()) {
1925 return true;
1926 }
1927 }
1928 return false;
1929}
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const

References BoostGraph< MoveNode, DataDependenceEdge >::connectingEdges(), DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), and GraphEdge::isBackEdge().

Referenced by mergeAndKeepSource(), mergeAndKeepUser(), and BFMergeAndKeepUser::operator()().

Here is the call graph for this function:

◆ isLoopInvariant()

bool DataDependenceGraph::isLoopInvariant ( const MoveNode mn) const

Definition at line 5688 of file DataDependenceGraph.cc.

5688 {
5689 EdgeSet iEdges = inEdges(mn);
5690 for (EdgeSet::iterator i = iEdges.begin(); i != iEdges.end(); i++) {
5691 DataDependenceEdge& e = **i;
5694 !e.guardUse()) {
5695 return false;
5696 }
5697 }
5698 return true;
5699}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), and BoostGraph< MoveNode, DataDependenceEdge >::inEdges().

Here is the call graph for this function:

◆ isNotAvoidable()

bool DataDependenceGraph::isNotAvoidable ( const DataDependenceEdge edge) const

Returns true in case the given dependency cannot be (currently) avoided by techniques such as register renaming or speculation.

If the edge is "avoidable", it doesn't meen it always is. E.g., sometimes the register renamer can find a better register to remove the dependency, sometimes it cannot. That is, this method returns true only if it's certain we cannot do anything about the dependency with the current compiler backend or by, e.g., adding more registers to the machine.

Definition at line 5553 of file DataDependenceGraph.cc.

5553 {
5554
5555 if (!edge.isFalseDep()) return true;
5556 MoveNode& tail = tailNode(edge);
5557 MoveNode& head = headNode(edge);
5558
5559 /* The control dependency caused antidep case. In case the antidep
5560 overwrites the register with a different predicate than the other,
5561 it is not possible to simply rename the other register, but, e.g.,
5562 speculative execution has to be added with a final write to the
5563 original register.
5564
5565 Example:
5566
5567 a) p1: foo -> r1
5568 b) p1: r1 -> X
5569 c) p2: foo -> r1
5570 d) p2 r1 -> Y jne
5571 e) r1 -> foo
5572
5573 In case p2 = !p1 then we can parallelize freely. In case
5574 p2 = p1 then we can parallelize after a reg rename of r1.
5575 Otherwise, speculative or similar transformation has to be
5576 done, which currently is not supported by tcecc.
5577 */
5578 if ((edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER) &&
5579 (!tail.move().isUnconditional() && !head.move().isUnconditional()) &&
5580 !(tail.move().guard().guard().isEqual(head.move().guard().guard()) ||
5581 tail.move().guard().guard().isOpposite(head.move().guard().guard())))
5582 return true;
5583
5584 if ((edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER) &&
5585 ((tail.move().isUnconditional() && !head.move().isUnconditional()) ||
5586 (!tail.move().isUnconditional() && head.move().isUnconditional())))
5587 return true;
5588
5589
5590 return false;
5591}
virtual bool isOpposite(const Guard &guard) const =0

References BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), TTAMachine::Guard::isEqual(), TTAMachine::Guard::isOpposite(), TTAProgram::Move::isUnconditional(), MoveNode::move(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by trueDependenceGraph().

Here is the call graph for this function:

◆ isRootGraphProcedureDDG()

bool DataDependenceGraph::isRootGraphProcedureDDG ( )
private

Tells whether the root graph is a procedure-wide ddg or created from a smaller piece of code.

This is needed for dead result elimination.

Returns
if root graph of the subgraph tree contains whole procedure.

Definition at line 3669 of file DataDependenceGraph.cc.

3669 {
3670 if (parentGraph_ == NULL) {
3671 return procedureDDG_;
3672 } else {
3673 return static_cast<DataDependenceGraph*>(parentGraph_)
3675 }
3676}

References isRootGraphProcedureDDG(), BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, and procedureDDG_.

Referenced by isRootGraphProcedureDDG(), and resultUsed().

Here is the call graph for this function:

◆ largestCycle()

int DataDependenceGraph::largestCycle ( ) const

Returns the largest cycle of a move in the DDG.

Current implementation is quite slow, so don't call in critical places.

Returns
The largest cycle of a move.

Definition at line 1838 of file DataDependenceGraph.cc.

1838 {
1839
1840 int maxCycle = 0;
1841 for (int i = 0; i < nodeCount(); ++i) {
1842 Node& n = node(i);
1843 if (n.isPlaced()) {
1844 maxCycle = std::max(maxCycle, n.cycle());
1845 }
1846 }
1847
1848 return maxCycle;
1849}

References MoveNode::cycle(), MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by ResourceConstraintAnalyzer::analyzeRegisterAntideps(), LoopPrologAndEpilogBuilder::build(), dotString(), BBSchedulerController::executeDDGPass(), BasicBlockScheduler::handleLoopDDG(), BUBasicBlockScheduler::handleLoopDDG(), and BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ lastGuardDefMove()

MoveNode * DataDependenceGraph::lastGuardDefMove ( MoveNode moveNode)

Returns the MoveNode that defines (writes the value of) the guard the given move node is predicated with. If there are multiple, returns the last.

Parameters
moveNodeThe move node of which guard defining move to find.
Returns
The MoveNode that produces the guard value. If not found, returns NULL

Definition at line 721 of file DataDependenceGraph.cc.

721 {
722 NodeSet guardDefs = guardDefMoves(moveNode);
723 MoveNode* last = NULL;
724 for (NodeSet::iterator i = guardDefs.begin();
725 i != guardDefs.end(); i++) {
726 if (last == NULL || last->cycle() < (*i)->cycle()) {
727 last = *i;
728 }
729 }
730 return last;
731}

References MoveNode::cycle(), and guardDefMoves().

Here is the call graph for this function:

◆ lastRegisterCycle()

int DataDependenceGraph::lastRegisterCycle ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the highest cycle where accesses the given register. If unscheudled moves accessing the register, returns INT_MAX; If none found, returns -1.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
cycle, or INT_MAX if some unscheduled found.

Definition at line 882 of file DataDependenceGraph.cc.

883 {
884
885 int lastCycle = -1;
886 for (int i = 0; i < nodeCount(); ++i) {
887 MoveNode& n = node(i);
888 TTAProgram::Move& move = n.move();
889 const TTAMachine::BaseRegisterFile* currentRF = NULL;
890
891 // check source
892 TTAProgram::Terminal& source = move.source();
893 bool sourceImmReg = source.isImmediateRegister();
894 bool sourceGPR = source.isGPR();
895
896 if (sourceImmReg || sourceGPR) {
897
898 if (sourceImmReg)
899 currentRF = &source.immediateUnit();
900 else
901 currentRF = &source.registerFile();
902
903 if (&rf == currentRF && source.index() == registerIndex) {
904 if (!n.isPlaced()) {
905 return INT_MAX;
906 }
907 if (n.cycle() > lastCycle) {
908 lastCycle = n.cycle();
909 }
910 }
911 }
912
913 // check destination
914 TTAProgram::Terminal& destination = move.destination();
915 if (destination.isGPR()) {
916 currentRF = &destination.registerFile();
917
918 if (&rf == currentRF && destination.index() == registerIndex) {
919 if (!n.isPlaced()) {
920 return INT_MAX;
921 }
922 if (n.cycle() > lastCycle) {
923 lastCycle = n.cycle();
924 }
925
926 if (move.isUnconditional()) {
927 if (outDegree(n) == 0) {
928 assert(lastCycle == n.cycle());
929 return lastCycle;
930 }
931 }
932 }
933 }
934
935 // check guard.
936 if (!move.isUnconditional()) {
937 const TTAMachine::Guard& guard = move.guard().guard();
938 const TTAMachine::RegisterGuard* rg =
939 dynamic_cast<const TTAMachine::RegisterGuard*>(&guard);
940 if (rg != NULL) {
941 if (rg->registerFile() == &rf &&
942 rg->registerIndex() == registerIndex) {
943 if (!n.isPlaced()) {
944 return INT_MAX;
945 }
946 if (n.cycle() > lastCycle) {
947 lastCycle = n.cycle();
948 }
949 }
950 }
951 }
952 if (move.isFunctionCall()) {
953 const TTAMachine::RegisterFile* rrf =
954 dynamic_cast<const TTAMachine::RegisterFile*>(&rf);
955 assert(rrf != NULL);
956 TCEString reg =
957 DisassemblyRegister::registerName(*rrf, registerIndex);
958 if (allParamRegs_.find(reg) != allParamRegs_.end()) {
959 if (!n.isPlaced()) {
960 return INT_MAX;
961 }
962 if (n.cycle() + delaySlots_> lastCycle) {
963 lastCycle = n.cycle() + delaySlots_ ;
964 }
965 }
966 }
967 }
968 return lastCycle;
969}

References allParamRegs_, assert, MoveNode::cycle(), delaySlots_, TTAProgram::Move::destination(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::Move::isFunctionCall(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DisassemblyRegister::registerName(), and TTAProgram::Move::source().

Referenced by RegisterRenamer::findPartiallyUsedRegistersBeforeCycle(), and RegisterRenamer::findPartiallyUsedRegistersInRFBeforeCycle().

Here is the call graph for this function:

◆ lastScheduledRegisterGuardReads()

DataDependenceGraph::NodeSet DataDependenceGraph::lastScheduledRegisterGuardReads ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the set of MoveNodes which reads given register as guard after last unconditional scheduled write to the register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The set of movenodes.

Definition at line 1163 of file DataDependenceGraph.cc.

1164 {
1165
1166 MoveNode* lastKill = lastScheduledRegisterKill(rf, registerIndex);
1167 int killCycle = lastKill == NULL ? -1 : lastKill->cycle();
1168 NodeSet lastGuards;
1169
1170 int nodeCounter = nodeCount();
1171 // first search last kill.
1172 for (int i = 0; i < nodeCounter; ++i) {
1173 MoveNode& n = node(i);
1174 TTAProgram::Move& move = n.move();
1175 if (move.isUnconditional() || !n.isPlaced()) {
1176 continue;
1177 }
1178
1179 const TTAMachine::Guard* guard = &move.guard().guard();
1180 const TTAMachine::RegisterGuard* rg =
1181 dynamic_cast<const TTAMachine::RegisterGuard*>(guard);
1182 if (rg == NULL) {
1183 continue;
1184 }
1185 const TTAMachine::BaseRegisterFile* currentRF = rg->registerFile();
1186 if (&rf == currentRF &&
1187 rg->registerIndex() == registerIndex) {
1188 if (n.cycle() > killCycle) {
1189 lastGuards.insert(&n);
1190 }
1191 }
1192 }
1193 return lastGuards;
1194}
MoveNode * lastScheduledRegisterKill(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const

References MoveNode::cycle(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), lastScheduledRegisterKill(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAMachine::RegisterGuard::registerFile(), and TTAMachine::RegisterGuard::registerIndex().

Referenced by RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ lastScheduledRegisterKill()

MoveNode * DataDependenceGraph::lastScheduledRegisterKill ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the MoveNode of unconditional move with highest cycle that writes the given register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The MoveNode, NULL, if not found.

Definition at line 1285 of file DataDependenceGraph.cc.

1286 {
1287
1288 int lastCycle = -1;
1289 MoveNode* lastFound = NULL;
1290 int nodeCounter = nodeCount();
1291 for (int i = 0; i < nodeCounter; ++i) {
1292 MoveNode& n = node(i);
1293
1295 if (!n.isPlaced() || !dest.isGPR())
1296 continue;
1297
1298 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1299 currentRF = &dest.registerFile();
1300
1301 if (&rf == currentRF &&
1302 dest.index() == registerIndex &&
1303 n.cycle() > lastCycle &&
1304 n.move().isUnconditional()) {
1305 lastCycle = n.cycle();
1306 lastFound = &n;
1307 }
1308 }
1309 return lastFound;
1310}

References MoveNode::cycle(), TTAProgram::Move::destination(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), TTAProgram::Move::isUnconditional(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), and TTAProgram::Terminal::registerFile().

Referenced by RegisterCopyAdder::createAntidepsForReg(), BFRegCopy::createAntidepsForReg(), lastScheduledRegisterGuardReads(), lastScheduledRegisterReads(), and lastScheduledRegisterWrites().

Here is the call graph for this function:

◆ lastScheduledRegisterRead()

MoveNode * DataDependenceGraph::lastScheduledRegisterRead ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex,
int  lastCycleToTest = INT_MAX 
) const

Returns the MoveNode with highest cycle that reads the given register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The MoveNode, NULL, if not found.

Definition at line 766 of file DataDependenceGraph.cc.

769 {
770
771 int lastCycle = -1;
772 MoveNode* lastFound = NULL;
773 for (int i = 0; i < nodeCount(); ++i) {
774 MoveNode& n = node(i);
775
776 TTAProgram::Terminal& source = n.move().source();
777 if (!n.isPlaced() ||
778 !(source.isImmediateRegister() || source.isGPR()))
779 continue;
780
781 const TTAMachine::BaseRegisterFile* currentRF = NULL;
782 if (source.isImmediateRegister())
783 currentRF = &source.immediateUnit();
784 else
785 currentRF = &source.registerFile();
786
787 if (&rf == currentRF &&
788 source.index() == registerIndex &&
789 n.cycle() > lastCycle &&
790 n.cycle() <= lastCycleToTest) {
791 lastCycle = n.cycle();
792 lastFound = &n;
793 }
794 }
795 return lastFound;
796}

References MoveNode::cycle(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Terminal::registerFile(), and TTAProgram::Move::source().

Referenced by BUBasicBlockScheduler::bypassNode(), BasicBlockScheduler::scheduleInputOperandTempMoves(), BasicBlockScheduler::scheduleResultReads(), BasicBlockScheduler::scheduleResultReadTempMoves(), and BasicBlockScheduler::scheduleRRTempMoves().

Here is the call graph for this function:

◆ lastScheduledRegisterReads()

DataDependenceGraph::NodeSet DataDependenceGraph::lastScheduledRegisterReads ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the set of MoveNodes which reads given register after last unconditional scheduled write to the register.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The set of movenodes.

Definition at line 1080 of file DataDependenceGraph.cc.

1081 {
1082
1083 MoveNode* lastKill = lastScheduledRegisterKill(rf, registerIndex);
1084 int killCycle = lastKill == NULL ? -1 : lastKill->cycle();
1085 NodeSet lastReads;
1086
1087 int nodeCounter = nodeCount();
1088 // first search last kill.
1089 for (int i = 0; i < nodeCounter; ++i) {
1090 MoveNode& n = node(i);
1091
1092 TTAProgram::Terminal& source = n.move().source();
1093 if (!n.isPlaced() ||
1094 !(source.isImmediateRegister() || source.isGPR()))
1095 continue;
1096
1097 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1098 if (source.isImmediateRegister())
1099 currentRF = &source.immediateUnit();
1100 else
1101 currentRF = &source.registerFile();
1102
1103 if (&rf == currentRF &&
1104 source.index() == registerIndex) {
1105 if (n.cycle() > killCycle) {
1106 lastReads.insert(&n);
1107 }
1108 }
1109 }
1110 return lastReads;
1111}

References MoveNode::cycle(), TTAProgram::Terminal::immediateUnit(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), MoveNode::isPlaced(), lastScheduledRegisterKill(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Terminal::registerFile(), and TTAProgram::Move::source().

Referenced by RegisterCopyAdder::createAntidepsForReg(), BFRegCopy::createAntidepsForReg(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ lastScheduledRegisterWrites()

DataDependenceGraph::NodeSet DataDependenceGraph::lastScheduledRegisterWrites ( const TTAMachine::BaseRegisterFile rf,
int  registerIndex 
) const

Returns the set of MoveNodes which writes given register after last unconditional scheduled write to the register, and the last unconditional write.

Parameters
rfThe register file.
registerIndexIndex of the register.
Returns
The set of movenodes.

Definition at line 1206 of file DataDependenceGraph.cc.

1207 {
1208
1209 MoveNode* lastKill = lastScheduledRegisterKill(rf, registerIndex);
1210 int killCycle = lastKill == NULL ? -1 : lastKill->cycle();
1211 NodeSet lastReads;
1212
1213 int nodeCounter = nodeCount();
1214 // first search last kill.
1215 for (int i = 0; i < nodeCounter; ++i) {
1216 MoveNode& n = node(i);
1217
1219 if (!n.isPlaced() || !dest.isGPR())
1220 continue;
1221
1222 const TTAMachine::BaseRegisterFile* currentRF = NULL;
1223 currentRF = &dest.registerFile();
1224
1225 if (&rf == currentRF &&
1226 dest.index() == registerIndex) {
1227 if (n.cycle() >= killCycle) {
1228 lastReads.insert(&n);
1229 }
1230 }
1231 }
1232 return lastReads;
1233}

References MoveNode::cycle(), TTAProgram::Move::destination(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::isPlaced(), lastScheduledRegisterKill(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), and TTAProgram::Terminal::registerFile().

Referenced by RegisterCopyAdder::createAntidepsForReg(), BFRegCopy::createAntidepsForReg(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ latestCycle()

int DataDependenceGraph::latestCycle ( const MoveNode moveNode,
unsigned int  ii = UINT_MAX,
bool  ignoreRegAntideps = false,
bool  ignoreUnscheduledSuccessors = true,
bool  ignoreGuards = false,
bool  ignoreFuDeps = false,
bool  ignoreSameOperationEdges = false 
) const

Returns the latest cycle this move can be scheduled at given the cycles of the dependencies.

This is assumed to be used with bottom-up scheduling. Checks all successor nodes and checks their min cycle if they are scheduled. If none found, INT_MAX is returned, if at least one of successors is unscheduled, returns 0.

Parameters
moveNodeThe move node for which to find the latest cycle.
Returns
The latest cycle the move can be scheduled to according to data dependencies, 0 if unknown.
Todo:
Consider the latency for result read move!

Definition at line 543 of file DataDependenceGraph.cc.

546 {
547
548 if (machine_ == NULL) {
549 throw InvalidData(__FILE__,__LINE__,__func__,
550 " setMachine() must be called before this");
551 }
552
553 const EdgeSet edges = outEdges(moveNode);
554 int maxCycle = INT_MAX;
555 for (EdgeSet::const_iterator i = edges.begin();
556 i != edges.end(); ++i) {
558
559 if (ignoreGuards && edge.guardUse()) {
560 continue;
561 }
562 if (ignoreFuDeps &&
563 (edge.edgeReason() == DataDependenceEdge::EDGE_FUSTATE ||
564 edge.edgeReason() == DataDependenceEdge::EDGE_MEMORY)) {
565 continue;
566 }
567
568 if (ignoreSameOperationEdges &&
570 continue;
571 }
572
573 MoveNode& head = headNode(edge);
574 if (&head == &moveNode) {
575 continue;
576 }
577
578 /// @todo Consider the latency for result read move!
579 if (head.isPlaced()) {
580 int latency = 1;
581 int effHeadCycle = head.cycle();
582
583 // If call, make sure all incoming deps fit into delay slots,
584 // can still be later than the call itself
585 // dependence type does not matter.
586 if (edge.headPseudo()) {
587 effHeadCycle += delaySlots_;
588 } else {
589 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW) {
590
591 // ignore deg antidep? then skip over this edge.
592 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER
593 && !edge.tailPseudo() && ignoreRegAntideps) {
594 continue;
595 }
596
597 // latency does not matter with WAW. always +1.
598 effHeadCycle -= 1;
599 } else {
600 if (edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
601
602 // ignore deg antidep? then skip over this edge.
603 if (edge.edgeReason() ==
605 !edge.tailPseudo() && ignoreRegAntideps) {
606 continue;
607 }
608
609 // WAR allows writing at same cycle than reading.
610 // in WAR also the latency goes backwards,
611 // new value can
612 // be written before old is read is latency is big.
613 if (edge.guardUse()) {
614 latency = moveNode.guardLatency();
615 }
616 // TODO: generate some hasAutomaticBundling()
617 // property to ADF
619 latency = 0;
620 }
621 effHeadCycle = effHeadCycle + latency - 1;
622 } else {
623 // RAW
624 if (edge.guardUse()) {
625 latency = head.guardLatency();
626 } else {
627 if (edge.edgeReason() ==
629 moveNode.isDestinationOperation() &&
630 head.inSameOperation(moveNode)) {
631 latency = getOperationLatency(edge.data());
632 }
633 }
634 // in case of RAW, value must be written latency
635 // cycles before it is used
636 effHeadCycle -= latency;
637 }
638 }
639 }
640
641 assert ((ii != 0 || edge.loopDepth() ==0) &&
642 "ii should not be 0 if we have an loop edge");
643 effHeadCycle += (ii * edge.loopDepth());
644
645 maxCycle = std::min(effHeadCycle, maxCycle);
646 } else {
647 if (!edge.isBackEdge()) {
648 if (!ignoreUnscheduledSuccessors) {
649 return -1;
650 }
651 }
652 }
653
654 // TODO: now does this for all input moves, not just trigger
656 head.isSourceOperation()) {
657 ProgramOperation& headPO = head.sourceOperation();
658 for (int i = 0; i < headPO.inputMoveCount(); i++) {
659 MoveNode& inputMove = headPO.inputMove(i);
660 if (!inputMove.isPlaced()) {
661 continue;
662 }
663
664 if (edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
665 (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER ||
666 edge.edgeReason() == DataDependenceEdge::EDGE_RA)) {
667
668 // same operation. 0 cycle war.
669 // TODO: also this if bundle ordering correct.
670 if (moveNode.isDestinationOperation() &&
671 &moveNode.destinationOperation() ==
672 &headPO && !edge.isBackEdge()) {
673 maxCycle = std::min(maxCycle, inputMove.cycle());
674 } else {
675 // different operation.1 cycle war,to be sure,for now
676 maxCycle = std::min(maxCycle, inputMove.cycle()-1);
677 }
678 }
679
680 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
681 (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER ||
682 edge.edgeReason() == DataDependenceEdge::EDGE_RA)) {
683 maxCycle = std::min(maxCycle, inputMove.cycle()-1);
684 }
685 }
686 }
687 }
688
689 return maxCycle;
690}

References __func__, assert, MoveNode::cycle(), delaySlots_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, MoveNode::destinationOperation(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_FUSTATE, DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, getOperationLatency(), MoveNode::guardLatency(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::inSameOperation(), GraphEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isPlaced(), MoveNode::isSourceOperation(), machine_, BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), MoveNode::sourceOperation(), and TTAMachine::Machine::triggerInvalidatesResults().

Referenced by CycleLookBackSoftwareBypasser::bypass(), BFPushAntidepDown::operator()(), BFPushAntidepsDown::operator()(), BFPushMoveUp::operator()(), BFPushMoveUp2::operator()(), BFScheduleExact::operator()(), BFSchedulePreLoopShared::operator()(), BFShareOperands::operator()(), BFRemoveGuardsFromSuccs::operator()(), BUBasicBlockScheduler::scheduleMove(), BasicBlockScheduler::scheduleMove(), BUBasicBlockScheduler::scheduleOperandWrites(), BasicBlockScheduler::tryToDelayOperands(), BUBasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToSwitchInputs().

Here is the call graph for this function:

◆ machine()

const TTAMachine::Machine & DataDependenceGraph::machine ( ) const
inline

◆ memoryDependenceGraph()

DataDependenceGraph * DataDependenceGraph::memoryDependenceGraph ( )

Returns a version of the graph with only nodes and edges that present memory dependencies.

Definition at line 3482 of file DataDependenceGraph.cc.

3482 {
3483 DataDependenceGraph* subGraph =
3485 allParamRegs_, "memory DDG",
3486 registerAntidependenceLevel_, NULL, false, false);
3487
3488 if (machine_ != NULL)
3489 subGraph->setMachine(*machine_);
3490
3491 NodeSet nodes;
3492 for (int i = 0; i < nodeCount(); ++i) {
3493
3494 MoveNode& mn = node(i);
3495 EdgeSet outEdg = outEdges(mn);
3496 bool found = false;
3497 for (EdgeSet::iterator ei = outEdg.begin(); ei != outEdg.end(); ei++) {
3498 Edge& edge = **ei;
3499 if (edge.edgeReason() == DataDependenceEdge::EDGE_MEMORY) {
3500 nodes.insert(&node(i));
3501 found = true;
3502 break;
3503 }
3504 }
3505
3506 if (found) continue;
3507 EdgeSet inEdg = inEdges(mn);
3508 for (EdgeSet::iterator ei = inEdg.begin(); ei != inEdg.end(); ei++) {
3509 Edge& edge = **ei;
3510 if (edge.edgeReason() == DataDependenceEdge::EDGE_MEMORY) {
3511 nodes.insert(&node(i));
3512 break;
3513 }
3514 }
3515
3516 }
3517 constructSubGraph(*subGraph, nodes);
3518
3519 return subGraph;
3520}

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_MEMORY, BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), machine_, BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), registerAntidependenceLevel_, and setMachine().

Referenced by ResourceConstraintAnalyzer::analyze().

Here is the call graph for this function:

◆ mergeAndKeepAllowed()

bool DataDependenceGraph::mergeAndKeepAllowed ( MoveNode sourceNode,
MoveNode userNode 
)

Checks if software bypassing is allowed without causing a deadlock through some circlar ddg dependence.

Parameters
sourceNodenode writing the value which is bypassed
userNodenode using the value, source of this node will be updated.

Definition at line 1880 of file DataDependenceGraph.cc.

1880 {
1881
1882 // check against to WAR's to each others caused by
1883 // A->B ; B-A trying to be bypassed to same cycle. don't allow this.
1884 // TODO: this does not handle/detect: A -> B ; C -> A; D -> C where
1885 // B -> D is being bypassed from A. creates a loop.
1886
1887 for (int i = 0; i < outDegree(sourceNode); i++) {
1888 DataDependenceEdge& edge = outEdge(sourceNode,i);
1889 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
1890 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
1891 !edge.tailPseudo()) {
1892 MoveNode& target = headNode(edge);
1893 if (!exclusingGuards(userNode, target)) {
1894 if (&target != &userNode && hasPath(target, userNode)) {
1895 return false;
1896 }
1897 }
1898 }
1899 }
1900
1901 if (!hasEdge(sourceNode, userNode)) {
1902 writeToDotFile("no_edge_on_merge.dot");
1903 throw Exception(
1904 __FILE__,__LINE__,__func__,"No edge between nodes being merged "
1905 + sourceNode.toString() + " " + userNode.toString());
1906 }
1907
1908 if (!sourceNode.isMove() || !userNode.isMove()) {
1909 throw Exception(
1910 __FILE__,__LINE__,__func__,"Cannot merge entry/exit node!");
1911 }
1912
1913 return true;
1914}
virtual bool hasEdge(const Node &nTail, const Node &nHead) const
bool hasPath(MoveNode &src, const MoveNode &dest) const
virtual void writeToDotFile(const TCEString &fileName) const

References __func__, DataDependenceEdge::DEP_WAR, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, exclusingGuards(), BoostGraph< MoveNode, DataDependenceEdge >::hasEdge(), BoostGraph< MoveNode, DataDependenceEdge >::hasPath(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), MoveNode::isMove(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), MoveNode::toString(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by mergeAndKeepSource(), and mergeAndKeepUser().

Here is the call graph for this function:

◆ mergeAndKeepSource()

bool DataDependenceGraph::mergeAndKeepSource ( MoveNode resultNode,
MoveNode userNode,
bool  force = false 
)

Definition at line 1962 of file DataDependenceGraph.cc.

1963 {
1964
1965 if (!force && !mergeAndKeepAllowed(sourceNode, userNode)) {
1966 return false;
1967 }
1968
1969 // update the move
1970 sourceNode.move().setDestination(userNode.move().destination().copy());
1971
1972 bool userIsRegToItselfCopy = false;
1973 // If source is an operation, set programOperation
1974 if (userNode.isDestinationOperation()) {
1975 // TODO: operand sharing, multiple users?
1977 dstOp->addInputNode(sourceNode);
1978 sourceNode.addDestinationOperationPtr(dstOp);
1979 // TODO: remove the source node operand fromt he operatioN!
1980
1981 // set fu annotations
1982 for (int j = 0; j < userNode.move().annotationCount(); j++) {
1983 TTAProgram::ProgramAnnotation anno = userNode.move().annotation(j);
1985 sourceNode.move().addAnnotation(
1988 }
1990 sourceNode.move().addAnnotation(
1993 }
1994 }
1995 } else {
1996 // bypassing from stupid reg-to-itself needs extra handling.
1997 if (userNode.move().source().equals(
1998 userNode.move().destination())) {
1999 userIsRegToItselfCopy = true;
2000 }
2001 }
2002
2003 bool loopBypass = isLoopBypass(sourceNode, userNode);
2004
2005 // remove RAW deps between source and user.
2006 TCEString regName = removeRAWEdges(sourceNode, userNode);
2007
2008
2009 for (int i = 0; i < rootGraphOutDegree(userNode); i++) {
2011
2012 // skip antidependencies due bypassed register.. these are no more
2013 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2014 edge.data() == regName) {
2015 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW ||
2016 edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
2017 continue;
2018 }
2019 }
2020
2021 // copy other edges.
2022 MoveNode& dst = rootGraph()->headNode(edge);
2023 DataDependenceEdge* newEdge = new DataDependenceEdge(edge, loopBypass);
2024
2025 // it the edge is a loop edge, put it only in root/parent graph.
2026 if (parentGraph_ != NULL) {
2027 static_cast<DataDependenceGraph*>(rootGraph())->
2028 connectNodes(sourceNode, dst, *newEdge,
2029 (edge.isBackEdge()?this:NULL));
2030 } else {
2031 connectNodes(sourceNode, dst, *newEdge);
2032 }
2033 }
2034
2035 // copy antideps over these two nodes
2036 copyDepsOver(sourceNode, userNode, true, false);
2037
2038 // fix WAR antidependencies to WaW
2039 for (int i = 0; i < inDegree(sourceNode); i++) {
2040 DataDependenceEdge& edge = inEdge(sourceNode,i);
2041
2042 // create new WaW in place of old WaR
2043 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2044 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
2045 edge.data() == regName) {
2046
2047 // if stupid reg to itself copy, keep to in edges..
2048 if (!userIsRegToItselfCopy) {
2049 // and remove the old WaR
2050 removeEdge(edge, NULL, &sourceNode);
2051 i--; // don't skip one edge here!
2052 }
2053 }
2054 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2055 edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
2056 edge.data() == regName) {
2057 removeEdge(edge, NULL, &sourceNode);
2058 i--; // don't skip one edge here!
2059 }
2060 }
2061
2062 for (int i = 0; i < rootGraphInDegree(userNode); i++) {
2063 DataDependenceEdge& e = rootGraphInEdge(userNode,i);
2064
2065 // do not copy guard use edges - the user already ahs them.
2066 // copying them leads to exponential increase in guard ege counts.
2068 continue;
2069 }
2070 if (&rootGraph()->tailNode(e) != &sourceNode) {
2071 rootGraph()->copyInEdge(sourceNode, e);
2072 }
2073 }
2074
2075 return true;
2076}
virtual void copyInEdge(const Node &destination, Edge &edge, const Node *tail=NULL)
bool isLoopBypass(MoveNode &sourceNode, MoveNode &userNode)
bool mergeAndKeepAllowed(MoveNode &sourceNode, MoveNode &userNode)
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
const std::vector< Byte > & payload() const
ProgramAnnotation::Id id() const
@ ANN_REJECTED_UNIT_DST
Dst. unit rejected.
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
virtual bool equals(const Terminal &other) const =0
virtual Terminal * copy() const =0

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), MoveNode::addDestinationOperationPtr(), TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_DST, TTAProgram::AnnotatedInstructionElement::annotation(), BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), TTAProgram::Terminal::copy(), copyDepsOver(), BoostGraph< GraphNode, GraphEdge >::copyInEdge(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), MoveNode::destinationOperationPtr(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, TTAProgram::Terminal::equals(), DataDependenceEdge::guardUse(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::ProgramAnnotation::id(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), GraphEdge::isBackEdge(), MoveNode::isDestinationOperation(), isLoopBypass(), mergeAndKeepAllowed(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, TTAProgram::ProgramAnnotation::payload(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), removeRAWEdges(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdge(), TTAProgram::Move::setDestination(), TTAProgram::Move::source(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Here is the call graph for this function:

◆ mergeAndKeepUser()

bool DataDependenceGraph::mergeAndKeepUser ( MoveNode resultNode,
MoveNode userNode,
bool  force = false 
)

Definition at line 2079 of file DataDependenceGraph.cc.

2080 {
2081
2082 if (!force && !mergeAndKeepAllowed(sourceNode, userNode)) {
2083 return false;
2084 }
2085
2086// writeToDotFile("before_merge.dot");
2087
2088 bool loopBypass = isLoopBypass(sourceNode, userNode);
2089
2090 // Cannot bypass over multiple loop iterations. even with force flag.
2091 if (loopBypass) {
2092 for (int i = 0; i < inDegree(sourceNode); i++) {
2093 DataDependenceEdge& edge = inEdge(sourceNode,i);
2094 if (!edge.isFalseDep() && edge.isBackEdge()) {
2095 return false;
2096 }
2097 }
2098 }
2099
2100 // update the move
2101 userNode.move().setSource(sourceNode.move().source().copy());
2102
2103 bool sourceIsRegToItselfCopy = false;
2104 // If source is an operation, set programOperation
2105 if (sourceNode.isSourceOperation()) {
2106 ProgramOperationPtr srcOp = sourceNode.sourceOperationPtr();
2107 srcOp->addOutputNode(userNode);
2108 userNode.setSourceOperationPtr(srcOp);
2109
2110 // set fu annotations
2111 for (int j = 0; j < sourceNode.move().annotationCount(); j++) {
2112 TTAProgram::ProgramAnnotation anno = sourceNode.move().annotation(j);
2114 userNode.move().addAnnotation(
2117 }
2119 userNode.move().addAnnotation(
2122 }
2124 userNode.move().addAnnotation(
2127 }
2128 }
2129 } else {
2130 // bypassing from stupid reg-to-itself needs extra handling.
2131 if (sourceNode.move().source().equals(
2132 sourceNode.move().destination())) {
2133 sourceIsRegToItselfCopy = true;
2134 }
2135 }
2136
2137 // remove RAW deps between source and user.
2138 TCEString regName = removeRAWEdges(sourceNode, userNode);
2139
2140
2141 // if we are bypassign from a register-to-register copy, we'll have to
2142 // copy incoming raw edges also in rootgraph level to preserve inter-bb
2143 // -dependencies.
2144 for (int i = 0; i < rootGraphInDegree(sourceNode); i++) {
2145 DataDependenceEdge& edge = rootGraphInEdge(sourceNode,i);
2146
2147 // skip antidependencies due bypassed register.. these are no more
2148 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2149 edge.data() == regName) {
2150 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW ||
2151 edge.dependenceType() == DataDependenceEdge::DEP_WAR) {
2152 continue;
2153 }
2154 }
2155
2156 // do not copy guard use edges - the user already ahs them.
2157 // copying them leads to exponential increase in guard ege counts.
2158 if (edge.guardUse()) {
2159 continue;
2160 }
2161
2162 // copy other edges.
2163 MoveNode& source = rootGraph()->tailNode(edge);
2164 DataDependenceEdge* newEdge = new DataDependenceEdge(edge, loopBypass);
2165 rootGraph()->connectNodes(source, userNode, *newEdge);
2166 }
2167
2168 if (sourceNode.isSourceVariable() || sourceNode.isSourceRA()) {
2169 // if bypassing reg-to-reg this copy anti edges resulting from the
2170 // read of the other register.
2171 for (int i = 0; i < rootGraphOutDegree(sourceNode); i++) {
2172 DataDependenceEdge& edge = rootGraphOutEdge(sourceNode,i);
2173 if ((edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER||
2174 edge.edgeReason() == DataDependenceEdge::EDGE_RA) &&
2175 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
2176 !edge.tailPseudo()) {
2177
2178 MoveNode& target = rootGraph()->headNode(edge);
2179
2180 if (!(static_cast<DataDependenceGraph*>(rootGraph()))
2181 ->exclusingGuards(userNode, target) &&
2182 &userNode != &target) {
2183 DataDependenceEdge* newEdge = new DataDependenceEdge(edge, loopBypass);
2184 // TODO: loop here!
2185 rootGraph()->connectNodes(userNode, target, *newEdge);
2186 }
2187 }
2188 }
2189 }
2190
2191 // fix WAR antidependencies to WaW
2192 for (int i = 0; i < rootGraphOutDegree(userNode); i++) {
2194
2195 // create new WaW in place of old WaR
2196 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2197 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
2198 edge.data() == regName) {
2199
2200 // if stupid reg to itself copy, keep to in edges..
2201 if (!sourceIsRegToItselfCopy) {
2202 // and remove the old WaR
2203 (static_cast<DataDependenceGraph*>(rootGraph()))->
2204 removeEdge(edge, &userNode, NULL);
2205 i--; // don't skip one edge here!
2206 }
2207 }
2208 }
2209 return true;
2210}
void setSourceOperationPtr(ProgramOperationPtr po)
Definition MoveNode.cc:541
void addAnnotation(const ProgramAnnotation &annotation)
void setSource(Terminal *src)
Definition Move.cc:312
@ ANN_REJECTED_UNIT_SRC
Src. unit rejected.
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_SRC, TTAProgram::AnnotatedInstructionElement::annotation(), BoostGraph< GraphNode, GraphEdge >::connectNodes(), TTAProgram::Terminal::copy(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, TTAProgram::Terminal::equals(), exclusingGuards(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::ProgramAnnotation::id(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), GraphEdge::isBackEdge(), isLoopBypass(), MoveNode::isSourceOperation(), MoveNode::isSourceRA(), MoveNode::isSourceVariable(), mergeAndKeepAllowed(), MoveNode::move(), TTAProgram::ProgramAnnotation::payload(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), removeRAWEdges(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutDegree(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdge(), TTAProgram::Move::setSource(), MoveNode::setSourceOperationPtr(), TTAProgram::Move::source(), MoveNode::sourceOperationPtr(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies(), BUBasicBlockScheduler::bypassNode(), and CycleLookBackSoftwareBypasser::bypassNode().

Here is the call graph for this function:

◆ moveFUDependenciesToTrigger()

void DataDependenceGraph::moveFUDependenciesToTrigger ( MoveNode trigger)

Trigger of an operation may change when scheduling. This method updates fu state dependence edges to point to trigger instead of some other node of an operation. (they should point to trigger).

Definition at line 4785 of file DataDependenceGraph.cc.

4785 {
4786 if (!trigger.isDestinationOperation()) {
4787 return;
4788 }
4789 ProgramOperation& po = trigger.destinationOperation();
4790
4791 // move input edges.
4792 for (int i = 0; i < po.inputMoveCount(); i++) {
4793 MoveNode& node = po.inputMove(i);
4794 if (&node != &trigger) {
4795 EdgeSet iEdges = rootGraphInEdges(node);
4796 for (EdgeSet::iterator i=iEdges.begin(); i != iEdges.end(); i++) {
4797 DataDependenceEdge& e = **i;
4799 moveInEdge(node, trigger, e);
4800 }
4801 }
4802 }
4803 }
4804
4805 // move output edges.
4806 for (int i = 0; i < po.inputMoveCount(); i++) {
4807 MoveNode& node = po.inputMove(i);
4808 if (&node != &trigger) {
4809 EdgeSet oEdges = rootGraphOutEdges(node);
4810 for (EdgeSet::iterator i=oEdges.begin(); i != oEdges.end(); i++) {
4811 DataDependenceEdge& e = **i;
4813 moveOutEdge(node, trigger, e);
4814 }
4815 }
4816 }
4817 }
4818}

References MoveNode::destinationOperation(), DataDependenceEdge::EDGE_FUSTATE, DataDependenceEdge::edgeReason(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), BoostGraph< MoveNode, DataDependenceEdge >::moveInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::moveOutEdge(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdges().

Referenced by BUBasicBlockScheduler::scheduleOperandWrites().

Here is the call graph for this function:

◆ movesAtCycle()

DataDependenceGraph::NodeSet DataDependenceGraph::movesAtCycle ( int  cycle) const

Returns the moves that are scheduled at the given cycle.

Parameters
cycleThe cycle.
Returns
Move that are scheduled at the given cycle.

Definition at line 699 of file DataDependenceGraph.cc.

699 {
700
701 NodeSet moves;
702 for (int i = 0; i < nodeCount(); ++i) {
703 Node& n = node(i);
704 if (n.isPlaced() && n.cycle() == cycle)
705 moves.insert(&n);
706 }
707
708 return moves;
709}

References MoveNode::cycle(), MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by dotString(), and BasicBlockScheduler::handleRemovedResultMoves().

Here is the call graph for this function:

◆ nodeOfMove()

MoveNode & DataDependenceGraph::nodeOfMove ( const TTAProgram::Move move)

Gets a node of a move.

Warning: this operations is currently O(n). Smarter data structure needed for faster operation, propably should be implemented.

Parameters
movemove.
Returns
MoveNode of the given move

Definition at line 3600 of file DataDependenceGraph.cc.

3600 {
3601
3602 auto i = nodesOfMoves_.find(&move);
3603 if (i != nodesOfMoves_.end()) {
3604 return *(i->second);
3605 }
3606
3607 TCEString msg = "move not in ddg: " +
3608 Conversion::toString(reinterpret_cast<long>(&move)) + " " +
3610 throw InstanceNotFound(__FILE__,__LINE__,__func__, msg);
3611}
static std::string disassemble(const TTAProgram::Move &move)

References __func__, POMDisassembler::disassemble(), nodesOfMoves_, and Conversion::toString().

Referenced by LoopAnalyzer::analyze(), CopyingDelaySlotFiller::collectMoves(), DataDependenceGraphBuilder::constructIndividualBB(), MoveNodeDuplicator::duplicateMove(), fixInterBBAntiEdges(), CopyingDelaySlotFiller::getMove(), ControlFlowGraph::mergeNodes(), BFShareOperandsLate::operator()(), ControlFlowGraph::removeJumpToTarget(), ControlFlowGraph::removeUnreachableNodes(), CopyingDelaySlotFiller::updateFTBBAndCfg(), and CopyingDelaySlotFiller::updateJumpsAndCfg().

Here is the call graph for this function:

◆ onlyGuardDefOfMove()

MoveNode * DataDependenceGraph::onlyGuardDefOfMove ( MoveNode moveNode)

Finds (only) node which writes the guard value of a move. If none or multiple, return NULL

Definition at line 4581 of file DataDependenceGraph.cc.

4581 {
4582 NodeSet guardDefs = guardDefMoves(moveNode);
4583 if (guardDefs.size() != 1) {
4584 return NULL;
4585 }
4586 return *guardDefs.begin();
4587}

References guardDefMoves().

Referenced by LoopAnalyzer::analyze(), findLoopLimitAndIndex(), BF2Scheduler::handleLoopDDG(), and writesJumpGuard().

Here is the call graph for this function:

◆ onlyIncomingGuard()

DataDependenceEdge * DataDependenceGraph::onlyIncomingGuard ( const MoveNode mn) const

Returns the only incoming guard edge to given node

if there are multiple incoming guard edges, return NULL.

Parameters
mnMoveNode whose incoming edges we are searching.
Returns
only guard edge to mn or NULL if no or multiple.

Definition at line 4024 of file DataDependenceGraph.cc.

4025 {
4026 DataDependenceEdge* guard = NULL;
4028
4029 for (DataDependenceGraph::EdgeSet::iterator i = iEdges.begin();
4030 i != iEdges.end(); i++) {
4031 DataDependenceEdge* iEdge = *i;
4032 if (iEdge->guardUse() && iEdge->dependenceType() ==
4034 if (guard == NULL) {
4035 guard = iEdge;
4036 } else {
4037 if (!(*guard == *iEdge) ||
4038 &tailNode(*iEdge) != &tailNode(*guard)) {
4039 return NULL; // too complicated guard
4040 }
4041 }
4042 }
4043 }
4044 return guard;
4045}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Here is the call graph for this function:

◆ onlyRegisterEdgeIn()

DataDependenceEdge * DataDependenceGraph::onlyRegisterEdgeIn ( MoveNode mn) const

Returns the only incoming register edge to a node. If none or multiple, returns NULL.

Definition at line 255 of file DataDependenceGraph.cc.

255 {
256
257 DataDependenceEdge* result = NULL;
258 for (int i = 0; i < inDegree(mn); i++) {
260 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER) {
261 if (result == NULL) {
262 result = &edge;
263 } else {
264 return NULL;
265 }
266 }
267 }
268 return result;
269}

References BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), and BoostGraph< MoveNode, DataDependenceEdge >::inEdge().

Here is the call graph for this function:

◆ onlyRegisterEdgeOut()

DataDependenceEdge * DataDependenceGraph::onlyRegisterEdgeOut ( MoveNode mn) const

Returns the only outgoing register edge from a node. If none or multiple, returns NULL.

Definition at line 276 of file DataDependenceGraph.cc.

276 {
277
278 DataDependenceEdge* result = NULL;
279 for (int i = 0; i < outDegree(mn); i++) {
281 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER) {
282 if (result == NULL) {
283 result = &edge;
284 } else {
285 return NULL;
286 }
287 }
288 }
289 return result;
290}

References BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdge().

Here is the call graph for this function:

◆ onlyRegisterRawAncestor()

const MoveNode * DataDependenceGraph::onlyRegisterRawAncestor ( const MoveNode mn,
const std::string &  sp 
) const

Tracks the origin of the data a movenode reads. Goes back thru DDG and tracks register-to register reads.

If data comes from operation, returns the operation result read. If data comes from stack pointer, returns the stack pointer read. If the data may come from multiple places (conditional writes to reg, or writes to same reg in multiple BB's), return the move which read the value from the reg.

Definition at line 4203 of file DataDependenceGraph.cc.

4204 {
4205 const MoveNode* node = &mn;
4206
4207 while(true) {
4208 if (node->isSourceReg(sp)) {
4209 return node;
4210 }
4212 if (src == NULL) {
4213 return node;
4214 } else {
4215 // this should not be needed if incoming code were sensible
4216 // but it often is not. extra check to prevetn forever loop.
4217 if (node == src) {
4218 return node;
4219 }
4220 node = src;
4221 }
4222 }
4223}

References BoostGraph< MoveNode, DataDependenceEdge >::node(), and onlyRegisterRawSource().

Referenced by OffsetAliasAnalyzer::analyze(), and OffsetAliasAnalyzer::isAddressTraceable().

Here is the call graph for this function:

◆ onlyRegisterRawDestinations()

DataDependenceGraph::NodeSet DataDependenceGraph::onlyRegisterRawDestinations ( const MoveNode mn,
bool  allowGuardEdges = false,
bool  allowBackEdges = false 
) const

Returns the destinations of ordinary register RAW edge to given node, ie the moves which reads the value this move writes.

Parameters
mnMoveNode whose succssor moves we are searching.
Returns
only move reading reg this writes or NULL if no or multiple.

Definition at line 4163 of file DataDependenceGraph.cc.

4164 {
4165 NodeSet destination;
4166 NodeDescriptor nd = descriptor(mn);
4167
4168 // use the internal data structures to make this fast.
4169 // edgeset has too much set overhead,
4170 // inedge(n,i) is O(n^2) , this is linear with no overhead
4171 std::pair<OutEdgeIter, OutEdgeIter> edges =
4172 boost::out_edges(nd, graph_);
4173
4174 for (OutEdgeIter ei = edges.first; ei != edges.second; ei++) {
4175 EdgeDescriptor ed = *ei;
4177 if (edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
4178 edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
4179 (allowGuardEdges || !edge->guardUse())
4180 && !edge->tailPseudo()) {
4181 if (!edge->headPseudo() && (allowBackEdges || !edge->isBackEdge())) {
4182 destination.insert(graph_[boost::target(ed, graph_)]);
4183 } else {
4184 destination.clear();
4185 break;
4186 }
4187 }
4188 }
4189 return destination;
4190}

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::graph_, and GraphEdge::isBackEdge().

Referenced by BF2ScheduleFront::allNodesOfSameOperation(), BUBasicBlockScheduler::bypassNode(), BUBasicBlockScheduler::findBypassDestinations(), and BUMoveNodeSelector::mightBeReady().

Here is the call graph for this function:

◆ onlyRegisterRawDestinationsWithEdges()

std::map< DataDependenceEdge *, MoveNode *, DataDependenceEdge::Comparator > DataDependenceGraph::onlyRegisterRawDestinationsWithEdges ( const MoveNode mn,
bool  allowBackEdges 
) const

Returns the destinations of ordinary register RAW edge to given node, ie the moves which reads the value this move writes.

Parameters
mnMoveNode whose succssor moves we are searching.
Returns
only move reading reg this writes or NULL if no or multiple.

Definition at line 4124 of file DataDependenceGraph.cc.

4125 {
4126 std::map<DataDependenceEdge*, MoveNode*, DataDependenceEdge::Comparator>
4127 destination;
4128 NodeDescriptor nd = descriptor(mn);
4129
4130 // use the internal data structures to make this fast.
4131 // edgeset has too much set overhead,
4132 // inedge(n,i) is O(n^2) , this is linear with no overhead
4133 std::pair<OutEdgeIter, OutEdgeIter> edges =
4134 boost::out_edges(nd, graph_);
4135
4136 for (OutEdgeIter ei = edges.first; ei != edges.second; ei++) {
4137 EdgeDescriptor ed = *ei;
4139 if (edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
4140 edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
4141 !edge->tailPseudo()) {
4142 if (!edge->headPseudo() && (allowBackEdges || !edge->isBackEdge())) {
4143 destination.insert(std::make_pair(edge, graph_[boost::target(ed, graph_)]));
4144 } else {
4145 destination.clear();
4146 break;
4147 }
4148 }
4149 }
4150 return destination;
4151}

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::graph_, and GraphEdge::isBackEdge().

Referenced by BFLateBypasses::operator()().

Here is the call graph for this function:

◆ onlyRegisterRawSource()

MoveNode * DataDependenceGraph::onlyRegisterRawSource ( const MoveNode mn,
int  guardEdges = 2,
int  backEdges = 0 
) const

Returns the source of only ordinary register RAW edge to given node, ie the only move which writes the value this move reads.

backEdges: 0: do not care 1: only backedges 2: no backedges

guardEdges: 0: do not care 1: only guard edges 2: no guard edges

if there are multiple nodes where the value may come, return NULL, or if none found.

Parameters
mnMoveNode whose predecessor noves we are searching.
Returns
only move writing reg this reads or NULL if no or multiple.

Definition at line 4083 of file DataDependenceGraph.cc.

4085 {
4086 MoveNode* source = NULL;
4087 NodeDescriptor nd = descriptor(mn);
4088
4089 // use the internal data structures to make this fast.
4090 // edgeset has too much set overhead,
4091 // inedge(n,i) is O(n^2) , this is linear with no overhead
4092 std::pair<InEdgeIter, InEdgeIter> edges =
4093 boost::in_edges(nd, graph_);
4094
4095 for (InEdgeIter ei = edges.first; ei != edges.second; ei++) {
4096 EdgeDescriptor ed = *ei;
4098 if (backEdges == 1 && !edge->isBackEdge()) continue;
4099 if (backEdges == 2 && edge->isBackEdge()) continue;
4100 if (guardEdges == 1 && !edge->guardUse()) continue;
4101 if (guardEdges == 2 && edge->guardUse()) continue;
4102 if (edge->dependenceType() == DataDependenceEdge::DEP_RAW &&
4103 edge->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
4104 !edge->headPseudo() && !edge->tailPseudo()) {
4105 if (source == NULL) {
4106 source = graph_[boost::source(ed, graph_)];
4107 } else {
4108 return NULL;
4109 }
4110 }
4111 }
4112 return source;
4113}

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::graph_, and GraphEdge::isBackEdge().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies(), BF2ScheduleFront::allNodesOfSameOperation(), LoopAnalyzer::analyze(), OffsetAliasAnalyzer::analyzeLoopPtrIncrease(), BUBasicBlockScheduler::findBypassDestinations(), LoopAnalyzer::findEndCond(), LoopAnalyzer::findInitAndUpdate(), findLoopIndexUpdate(), findLoopLimitAndIndex(), ConstantAliasAnalyzer::getConstantAddress(), StackAliasAnalyzer::getStackOffset(), BUMoveNodeSelector::mightBeReady(), onlyRegisterRawAncestor(), BFEarlyGuardBypass::operator()(), OffsetAliasAnalyzer::sameLoopAndPrevSources(), MemoryAliasAnalyzer::searchLoopIndexBasedIncrement(), PreOptimizer::tryToPrecalcConstantAdd(), PreOptimizer::tryToRemoveEq(), and LoopAnalyzer::tryTrackCommonAncestor().

Here is the call graph for this function:

◆ operationInEdges()

DataDependenceGraph::EdgeSet DataDependenceGraph::operationInEdges ( const MoveNode node) const

Definition at line 5913 of file DataDependenceGraph.cc.

5913 {
5914 std::pair<InEdgeIter, InEdgeIter> edges = boost::in_edges(
5916
5917 EdgeSet result;
5918
5919 for (InEdgeIter ei = edges.first; ei != edges.second; ++ei) {
5920 DataDependenceEdge* edge = graph_[(*ei)];
5921 if (edge->edgeReason() == DataDependenceEdge::EDGE_OPERATION) {
5922 edgeDescriptors_[edge] = *ei;
5923 result.insert(edge);
5924 }
5925 }
5926 return result;
5927}

References BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, BoostGraph< MoveNode, DataDependenceEdge >::edgeDescriptors_, BoostGraph< MoveNode, DataDependenceEdge >::graph_, and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by ExecutionPipelineBroker::isLoopBypass(), and BFPushMoveUp2::isLoopBypass().

Here is the call graph for this function:

◆ otherSuccessorsScheduled()

bool DataDependenceGraph::otherSuccessorsScheduled ( MoveNode node,
const NodeSet ignoredNodes 
) const

Definition at line 3266 of file DataDependenceGraph.cc.

3266 {
3267 // use the internal data structures to make this fast.
3268 // edgeset has too much set overhead,
3269 // inedge(n,i) is O(n^2) , this is linear with no overhead
3271 std::pair<OutEdgeIter, OutEdgeIter> edges =
3272 boost::out_edges(nd, graph_);
3273
3274 for (OutEdgeIter ei = edges.first; ei != edges.second; ei++) {
3275 EdgeDescriptor ed = *ei;
3277 if (edge.isBackEdge()) {
3278 continue;
3279 }
3280 MoveNode* m = graph_[boost::target(ed, graph_)];
3281 if (!m->isPlaced()) {
3282 if (!AssocTools::containsKey(ignoredNodes, m)) {
3283 return false;
3284 }
3285 }
3286 }
3287 return true;
3288}

References AssocTools::containsKey(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, GraphEdge::isBackEdge(), MoveNode::isPlaced(), and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BUMoveNodeSelector::isReadyToBeScheduled().

Here is the call graph for this function:

◆ predecessorsReady()

bool DataDependenceGraph::predecessorsReady ( MoveNode node) const

Checks whether the given node has all its predcessors scheduled.

Ignores intra operation edges, thus if the predecessors belongs to the same operation, it need not be scheduled for the node to be considered ready.

Returns
True in case all predecessors are scheduled.

Definition at line 3176 of file DataDependenceGraph.cc.

3176 {
3177
3178 // use the internal data structures to make this fast.
3179 // edgeset has too much set overhead,
3180 // inedge(n,i) is O(n^2) , this is linear with no overhead
3182 std::pair<InEdgeIter, InEdgeIter> edges =
3183 boost::in_edges(nd, graph_);
3184
3185 bool srcOp = node.isSourceOperation();
3186 bool dstOp = node.isDestinationOperation();
3187
3188 for (InEdgeIter ei = edges.first; ei != edges.second; ei++) {
3189 EdgeDescriptor ed = *ei;
3191 if (edge.isBackEdge()) {
3192 continue;
3193 }
3194 const MoveNode& m = *graph_[boost::source(ed, graph_)];
3195
3196 if (srcOp) {
3197 // operand move of same operation
3198 if ((m.isDestinationOperation() &&
3199 &node.sourceOperation() == &m.destinationOperation()) ||
3200 (m.isSourceOperation() &&
3201 &node.sourceOperation() == &m.sourceOperation())) {
3202 continue;
3203 }
3204 }
3205
3206 if (dstOp && m.isDestinationOperation() &&
3207 &node.destinationOperation() == &m.destinationOperation()) {
3208 continue;
3209 }
3210 if (!m.isPlaced()) {
3211 return false;
3212 }
3213 }
3214 return true;
3215
3216}

References BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), MoveNode::destinationOperation(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, GraphEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isPlaced(), MoveNode::isSourceOperation(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and MoveNode::sourceOperation().

Referenced by CriticalPathBBMoveNodeSelector::isReadyToBeScheduled().

Here is the call graph for this function:

◆ programOperation() [1/2]

ProgramOperation & DataDependenceGraph::programOperation ( int  index)

Returs programoperation which is in this graph.

Parameters
indexindex of the programoperation.

Definition at line 227 of file DataDependenceGraph.cc.

227 {
228 return *programOperations_.at(index);
229}

References programOperations_.

Referenced by BF2Scheduler::countLoopInvariantValueUsages(), PreOptimizer::handleCFGDDG(), and BF2Scheduler::reservePreallocatedFUs().

◆ programOperation() [2/2]

const ProgramOperation & DataDependenceGraph::programOperation ( int  index) const

Definition at line 232 of file DataDependenceGraph.cc.

232 {
233 return *programOperations_.at(index);
234}

References programOperations_.

◆ programOperationCount()

int DataDependenceGraph::programOperationCount ( ) const

Returns the number of programoperations in this ddg.

Definition at line 246 of file DataDependenceGraph.cc.

246 {
247 return programOperations_.size();
248}

References programOperations_.

Referenced by addProgramOperation(), BF2Scheduler::countLoopInvariantValueUsages(), PreOptimizer::handleCFGDDG(), and BF2Scheduler::reservePreallocatedFUs().

◆ programOperationPtr()

ProgramOperationPtr DataDependenceGraph::programOperationPtr ( int  index)

Definition at line 237 of file DataDependenceGraph.cc.

237 {
238 return programOperations_.at(index);
239}

References programOperations_.

◆ queueRawPredecessors()

bool DataDependenceGraph::queueRawPredecessors ( NodeSet queue,
NodeSet finalDest,
NodeSet predQueue,
NodeSet predFinalDest,
bool  guard 
) const
private

Definition at line 4918 of file DataDependenceGraph.cc.

4920 {
4921
4922 typedef EdgeSet::iterator EdgeIterator;
4923
4924 // check one read.
4925 while (!queue.empty()) {
4926 MoveNode& read = **queue.begin();
4927
4928 NodeDescriptor nd = descriptor(read);
4929 EdgeSet in = rootGraphInEdges(read);
4930
4931 for (EdgeIterator j = in.begin(); j != in.end(); j++) {
4932 DataDependenceEdge& e = **j;
4933
4936 e.guardUse() == guard) {
4937 MoveNode& pred =
4938 (static_cast<const DataDependenceGraph*>
4939 (rootGraph()))->tailNode(e, nd);
4940 if (e.isBackEdge() || e.headPseudo() ||
4941 e.tailPseudo() || !hasNode(pred)) {
4942 return false;
4943 } else {
4944 if (predFinalDest.find(&pred) ==
4945 predFinalDest.end()) {
4946 predQueue.insert(&pred);
4947 }
4948 }
4949 }
4950 }
4951 // this is fully checked. add to result, remove from queue
4952 finalDest.insert(&read);
4953 queue.erase(&read);
4954 }
4955 return true;
4956}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), DataDependenceEdge::headPseudo(), DataDependenceEdge::isBackEdge(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdges(), and DataDependenceEdge::tailPseudo().

Referenced by findLiveRange().

Here is the call graph for this function:

◆ rAntiEdgesIn()

int DataDependenceGraph::rAntiEdgesIn ( MoveNode mn)
private

Counts all incoming antidependence edges to a movenode.

Parameters
mnMoveNode whose edges we are counting
Returns
number of incoming antidependence edges.

Definition at line 4001 of file DataDependenceGraph.cc.

4001 {
4002 EdgeSet iEdges = inEdges(mn);
4003 int count = 0;
4004 for (EdgeSet::iterator iter =
4005 iEdges.begin(); iter != iEdges.end(); iter++) {
4006 if ((*iter)->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
4007 (((*iter)->dependenceType() == DataDependenceEdge::DEP_WAR) ||
4008 ((*iter)->dependenceType() == DataDependenceEdge::DEP_WAW))) {
4009 count++;
4010 }
4011 }
4012 return count;
4013}

References DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_REGISTER, and BoostGraph< MoveNode, DataDependenceEdge >::inEdges().

Here is the call graph for this function:

◆ regDepSiblings()

DataDependenceGraph::NodeSet DataDependenceGraph::regDepSiblings ( const MoveNode mn) const

Definition at line 5620 of file DataDependenceGraph.cc.

5620 {
5621
5622 NodeSet potentialSiblings;
5623 NodeSet siblings;
5624 NodeSet regDepSources;
5625
5626 EdgeSet ins = inEdges(mn);
5627 int edgeCounter = 0;
5628 for (auto e: ins) {
5629 if ((e->edgeReason() != DataDependenceEdge::EDGE_REGISTER &&
5630 e->edgeReason() != DataDependenceEdge::EDGE_RA) ||
5631 e->headPseudo() || e->tailPseudo() || e->guardUse()) {
5632 continue;
5633 }
5634 edgeCounter++;
5635
5636 MoveNode& tail = tailNode(*e);
5637 regDepSources.insert(&tail);
5638 const EdgeSet& outs = outEdges(tail);
5639 for (auto f: outs) {
5640 if ((f->edgeReason() != DataDependenceEdge::EDGE_REGISTER &&
5641 f->edgeReason() != DataDependenceEdge::EDGE_RA) ||
5642 f->headPseudo() || f->tailPseudo() || f->guardUse()) {
5643 continue;
5644 }
5645 if (e != f && *e == *f) {
5646 MoveNode& head = headNode(*f);
5647 if (&head != &mn) {
5648 potentialSiblings.insert(&head);
5649 }
5650 }
5651 }
5652 }
5653
5654 for (auto n : potentialSiblings) {
5655 bool ok = true;
5656 EdgeSet ins2 = inEdges(*n);
5657 int edgeCounter2 = 0;
5658 for (auto e: ins2) {
5659 if ((e->edgeReason() != DataDependenceEdge::EDGE_REGISTER &&
5660 e->edgeReason() != DataDependenceEdge::EDGE_RA) ||
5661 e->headPseudo() || e->tailPseudo() || e->guardUse()) {
5662 continue;
5663 }
5664
5665 bool foundSame = false;
5666 const MoveNode& tail = tailNode(*e);
5667 for (auto f : ins) {
5668 if (*e == *f && &tailNode(*f) == &tail) {
5669 foundSame = true;
5670 break;
5671 }
5672 }
5673
5674 // did not find similar edge from the inputs of the original node
5675 if (!foundSame) {
5676 ok = false;
5677 break;
5678 }
5679 edgeCounter2++;
5680 }
5681 if (ok && edgeCounter2 == edgeCounter) {
5682 siblings.insert(n);
5683 }
5684 }
5685 return siblings;
5686}

References DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by BFShareOperands::operator()().

Here is the call graph for this function:

◆ registerAndRAInEdges()

DataDependenceGraph::EdgeSet DataDependenceGraph::registerAndRAInEdges ( const MoveNode node) const

Definition at line 5930 of file DataDependenceGraph.cc.

5930 {
5931 std::pair<InEdgeIter, InEdgeIter> edges = boost::in_edges(
5933
5934 EdgeSet result;
5935
5936 for (InEdgeIter ei = edges.first; ei != edges.second; ++ei) {
5937 DataDependenceEdge* edge = graph_[(*ei)];
5938 if (edge->isRegisterOrRA()) {
5939 edgeDescriptors_[edge] = *ei;
5940 result.insert(edge);
5941 }
5942 }
5943 return result;
5944}

References BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::edgeDescriptors_, BoostGraph< MoveNode, DataDependenceEdge >::graph_, and BoostGraph< MoveNode, DataDependenceEdge >::node().

Here is the call graph for this function:

◆ regRawPredecessors()

DataDependenceGraph::NodeSet DataDependenceGraph::regRawPredecessors ( const MoveNode node,
int  backedges = 0 
) const

Returns the register raw predecessors of the given node.

If node has no register raw predecessors, an empty set is returned. Note: the node can also be a predecessor of itself. Register raw predecessor means predecessor which is connected by register or ra raw edge

backEdges: 0: do not care 1: only backedges 2: no backedges

Parameters
nodeThe node of which successors to find.
Returns
Set of root nodes, can be empty.

Definition at line 4310 of file DataDependenceGraph.cc.

4310 {
4311
4312 NodeSet pred;
4313
4315 EdgeSet in = inEdges(node);
4316 typedef EdgeSet::iterator EdgeIterator;
4317
4318 for (EdgeIterator i = in.begin(); i != in.end(); ++i) {
4319 DataDependenceEdge& e = **i;
4320 if (backedges == 1 && !e.isBackEdge()) {
4321 continue;
4322 } else if (backedges == 2 && e.isBackEdge()) {
4323 continue;
4324 }
4328 pred.insert(&tailNode(**i, nd));
4329 }
4330 }
4331 return pred;
4332}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), DataDependenceEdge::isBackEdge(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::tailNode().

Referenced by LoopAnalyzer::findInitAndUpdate().

Here is the call graph for this function:

◆ regRawSuccessorCount()

int DataDependenceGraph::regRawSuccessorCount ( const MoveNode mn,
bool  onlyScheduled 
)

Calculates number of register RAW dependecies originating from given node

Parameters
mnMovenodes whose dependencies to calculate
onlySchedulesonly care about dependencies to Scheduled nodes.
Returns
number of register RAW dependencies originating from given node

Definition at line 3952 of file DataDependenceGraph.cc.

3953 {
3954 int count = 0;
3955 EdgeSet oEdges = outEdges(mn);
3956 for (EdgeSet::iterator iter =
3957 oEdges.begin(); iter != oEdges.end(); iter++) {
3958 if ((*iter)->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3959 (*iter)->dependenceType() == DataDependenceEdge::DEP_RAW) {
3960 MoveNode& mn = headNode(**iter);
3961 if (!onlyScheduled || mn.isPlaced()) {
3962 count++;
3963 }
3964 }
3965 }
3966 return count;
3967}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::headNode(), MoveNode::isPlaced(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by OffsetAliasAnalyzer::analyze(), CycleLookBackSoftwareBypasser::bypassNode(), and OffsetAliasAnalyzer::isAddressTraceable().

Here is the call graph for this function:

◆ regRawSuccessors()

DataDependenceGraph::NodeSet DataDependenceGraph::regRawSuccessors ( const MoveNode node) const

Returns the register raw successors of the given node.

If node has no register raw successors, an empty set is returned. Note: the node can also be a successor of itself. Register raw successor means successor which is connected by register or ra raw edge

Parameters
nodeThe node of which successors to find.
Returns
Set of root nodes, can be empty.

Definition at line 4272 of file DataDependenceGraph.cc.

4272 {
4273
4274 NodeSet succ;
4275
4277 EdgeSet out = outEdges(node);
4278 typedef EdgeSet::iterator EdgeIterator;
4279
4280 for (EdgeIterator i = out.begin(); i != out.end(); ++i) {
4281 DataDependenceEdge& e = **i;
4285 succ.insert(&headNode(**i, nd));
4286 }
4287 }
4288
4289 return succ;
4290}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by BasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ regWarSuccessors()

DataDependenceGraph::NodeSet DataDependenceGraph::regWarSuccessors ( const MoveNode node) const

Returns the register war successors of the given node.

If node has no register war successors, an empty set is returned. Note: the node can also be a successor of itself. Register war successor means successor which is connected by register or ra war edge

Parameters
nodeThe node of which successors to find.
Returns
Set of root nodes, can be empty.

Definition at line 4239 of file DataDependenceGraph.cc.

4239 {
4240
4241 NodeSet succ;
4242
4244 EdgeSet out = outEdges(node);
4245 typedef EdgeSet::iterator EdgeIterator;
4246
4247 for (EdgeIterator i = out.begin(); i != out.end(); ++i) {
4248 DataDependenceEdge& e = **i;
4252 succ.insert(&headNode(**i, nd));
4253 }
4254 }
4255
4256 return succ;
4257}

References DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by CycleLookBackSoftwareBypasser::bypassNode().

Here is the call graph for this function:

◆ regWawSuccessors()

DataDependenceGraph::NodeSet DataDependenceGraph::regWawSuccessors ( const MoveNode node) const

Returns the register waw successors of the given node.

If node has no reg waw successors, an empty set is returned. Note: the node can also be a successor of itself. register waw successor means successor which is connected by register waw edge.

Parameters
nodeThe node of which successors to find.
Returns
Set of root nodes, can be empty.

Definition at line 4347 of file DataDependenceGraph.cc.

4347 {
4348
4349 NodeSet succ;
4350
4352 EdgeSet out = outEdges(node);
4353 typedef EdgeSet::iterator EdgeIterator;
4354
4355 for (EdgeIterator i = out.begin(); i != out.end(); ++i) {
4356 DataDependenceEdge& e = **i;
4357
4358 // if we would bypass also over ra, then allow also ra in following
4361 succ.insert(&headNode(**i, nd));
4362 }
4363 }
4364
4365 return succ;
4366}

References DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by CycleLookBackSoftwareBypasser::removeDeadResults().

Here is the call graph for this function:

◆ removeIncomingGuardEdges()

void DataDependenceGraph::removeIncomingGuardEdges ( MoveNode node)

Removes guard raw edges coming to some node.

This is called if the guard is removed from the node.

Parameters
nodeThe node.

Definition at line 5466 of file DataDependenceGraph.cc.

5466 {
5468 std::pair<InEdgeIter, InEdgeIter> edges =
5469 boost::in_edges(nd, graph_);
5470
5471 // loop thru all edges
5472 for (InEdgeIter ei = edges.first; ei != edges.second; ) {
5473 EdgeDescriptor ed = *ei;
5475 if (edge.guardUse() && edge.dependenceType() ==
5477 boost::remove_edge(*ei, graph_);
5478
5479 // removing messes up the iterator. start again from first.
5480 edges = boost::in_edges(nd, graph_);
5481 ei = edges.first;
5482 } else {
5483 ei++;
5484 }
5485 }
5486}

References DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BUBasicBlockScheduler::scheduleMove(), BasicBlockScheduler::scheduleMove(), BasicBlockScheduler::tryToOptimizeWaw(), BUBasicBlockScheduler::tryToOptimizeWaw(), and BFOptimization::unsetJumpGuard().

Here is the call graph for this function:

◆ removeNode()

void DataDependenceGraph::removeNode ( MoveNode node)
virtual

Removes MoveNode from graph and ProgramOperations.

Does not delete the movenode.

This does NOT update overgoing antideps - consider calling copyAntidepsOver(node); before calling this.

Parameters
nodeMoveNode being removed.

Reimplemented from BoostGraph< MoveNode, DataDependenceEdge >.

Definition at line 2843 of file DataDependenceGraph.cc.

2843 {
2844 // remove move -> movenode mapping.
2845 if (node.isMove()) {
2846 TTAProgram::Move* move = &node.move();
2847 auto i = nodesOfMoves_.find(move);
2848 if (i != nodesOfMoves_.end()) {
2849 nodesOfMoves_.erase(i);
2850 }
2851 }
2852
2853 // remove node from program operations
2854 if (node.isMove()) {
2855 if (node.isSourceOperation()) {
2856 ProgramOperation& srcOp = node.sourceOperation();
2857 srcOp.removeOutputNode(node);
2858 node.unsetSourceOperation();
2859 }
2860
2861 if (node.isDestinationOperation()) {
2862 for (int i = node.destinationOperationCount() - 1; i >= 0; i--) {
2863 ProgramOperation& dstOp = node.destinationOperation(i);
2864 dstOp.removeInputNode(node);
2865 }
2866 node.clearDestinationOperation();
2867 }
2868 }
2869
2870// copyAntidepsOver(node);
2871
2872 // remove node from graph
2874}
virtual void removeNode(Node &node)
void removeInputNode(MoveNode &node)
void removeOutputNode(MoveNode &node, int outputIndex)

References BoostGraph< MoveNode, DataDependenceEdge >::node(), nodesOfMoves_, ProgramOperation::removeInputNode(), BoostGraph< GraphNode, GraphEdge >::removeNode(), and ProgramOperation::removeOutputNode().

Referenced by deleteNode(), MoveNodeDuplicator::disposeMoveNode(), CopyingDelaySlotFiller::loseCopies(), ControlFlowGraph::removeJumpToTarget(), ControlFlowGraph::removeUnreachableNodes(), CopyingDelaySlotFiller::unassignTempAssigns(), BFRegCopy::undoDDG(), CopyingDelaySlotFiller::updateFTBBAndCfg(), and CopyingDelaySlotFiller::updateJumpsAndCfg().

Here is the call graph for this function:

◆ removeOutgoingGuardWarEdges()

void DataDependenceGraph::removeOutgoingGuardWarEdges ( MoveNode node)

Removes guard raw edges coming to some node.

This is called if the guard is removed from the node.

Parameters
nodeThe node.

Definition at line 5496 of file DataDependenceGraph.cc.

5496 {
5498 std::pair<OutEdgeIter, OutEdgeIter> edges =
5499 boost::out_edges(nd, graph_);
5500
5501 // loop thru all edges
5502 for (OutEdgeIter ei = edges.first; ei != edges.second; ) {
5503 EdgeDescriptor ed = *ei;
5505 if (edge.guardUse() && edge.dependenceType() ==
5507 boost::remove_edge(*ei, graph_);
5508
5509 // removing messes up the iterator. start again from first.
5510 edges = boost::out_edges(nd, graph_);
5511 ei = edges.first;
5512 } else {
5513 ei++;
5514 }
5515 }
5516}

References DataDependenceEdge::DEP_WAR, BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BasicBlockScheduler::tryToOptimizeWaw(), and BUBasicBlockScheduler::tryToOptimizeWaw().

Here is the call graph for this function:

◆ removeRAWEdges()

TCEString DataDependenceGraph::removeRAWEdges ( MoveNode sourceNode,
MoveNode userNode 
)

Removes raw edged between nodes.

Returns the register associated with the raw dependency

Definition at line 1937 of file DataDependenceGraph.cc.

1937 {
1938
1939 TCEString regName;
1940 EdgeSet edges = connectingEdges(sourceNode, userNode);
1941
1942 for (auto edge: edges) {
1943 if (edge->dependenceType() == DataDependenceEdge::DEP_RAW) {
1944 regName = edge->data();
1945 removeEdge(*edge, &sourceNode, &userNode);
1946 }
1947 }
1948
1949 // there must have been a register raw edge between source and user node
1950 if (regName == "") {
1951 std::cerr << "Missing RAW edge between: " << sourceNode.toString()
1952 << " and " << userNode.toString() << " on removeRawEdges."
1953 << " Wrote missing_raw.dot" << std::endl;
1954 writeToDotFile("missing_raw.dot");
1955 assert(false);
1956 }
1957
1958 return regName;
1959}

References assert, BoostGraph< MoveNode, DataDependenceEdge >::connectingEdges(), DataDependenceEdge::DEP_RAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), MoveNode::toString(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by guardConverted(), mergeAndKeepSource(), and mergeAndKeepUser().

Here is the call graph for this function:

◆ renamedSimpleLiveRange()

void DataDependenceGraph::renamedSimpleLiveRange ( MoveNode src,
MoveNode dest,
MoveNode antidepPoint,
DataDependenceEdge lrEdge,
const TCEString oldReg,
const TCEString newReg 
)

Definition at line 5182 of file DataDependenceGraph.cc.

5185 {
5186
5187 // if nothing changed, retuen
5188 if (oldReg == newReg) {
5189 return;
5190 }
5191
5192 // copy antideps over these two nodes
5193 copyDepsOver(src, dest, true, false);
5194
5195 NodeDescriptor ndADP = descriptor(antidepPoint);
5196 EdgeSet resultInEdges = inEdges(antidepPoint);
5197 EdgeSet firstInEdges = inEdges(src);
5198 EdgeSet firstOutEdges = outEdges(src);
5199 EdgeSet lastOutEdges = outEdges(dest);
5200
5201 // move antideps coming to adeppoint into src
5202 for (EdgeSet::iterator i = resultInEdges.begin();
5203 i != resultInEdges.end(); i++) {
5204 DataDependenceEdge& e = **i;
5206 !e.headPseudo() &&
5209 assert(e.data() == newReg);
5210 MoveNode& tail = tailNode(e, ndADP);
5211 // do not create loop.
5212 if (e.loopDepth() == 0 && &tail == &src) {
5213 removeEdge(e);
5214 } else {
5215 moveInEdge(antidepPoint, src, e);
5216 }
5217 }
5218 }
5219
5223 newReg, false, false, false, false, 0);
5224
5228 newReg, false, false, false, false, 0);
5229
5230 connectNodes(src, antidepPoint, *wawEdge);
5231 connectNodes(dest, antidepPoint, *warEdge);
5232
5233 assert(connectingEdge.data() == oldReg);
5234 connectingEdge.setData(newReg);
5235
5236 // remove antidep edges that were removed because of this renameing
5237 for (EdgeSet::iterator i = firstInEdges.begin();
5238 i != firstInEdges.end(); i++) {
5239 DataDependenceEdge& e = **i;
5243 removeEdge(e, NULL, &src);
5244 }
5245 }
5246
5247 for (EdgeSet::iterator i = firstOutEdges.begin();
5248 i != firstOutEdges.end(); i++) {
5249 DataDependenceEdge& e = **i;
5251 !e.tailPseudo() && e.data() == oldReg &&
5254 removeEdge(e, &src, NULL);
5255 }
5256 }
5257 for (EdgeSet::iterator i = lastOutEdges.begin();
5258 i != lastOutEdges.end(); i++) {
5259 DataDependenceEdge& e = **i;
5261 !e.tailPseudo() && e.data() == oldReg &&
5264 removeEdge(e, &src, NULL);
5265 }
5266 }
5267}
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const

References assert, BoostGraph< MoveNode, DataDependenceEdge >::connectingEdge(), BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), copyDepsOver(), DataDependenceEdge::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), DataDependenceEdge::loopDepth(), BoostGraph< MoveNode, DataDependenceEdge >::moveInEdge(), BoostGraph< MoveNode, DataDependenceEdge >::outEdges(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), and DataDependenceEdge::tailPseudo().

Referenced by PreOptimizer::tryToOptimizeAddressReg().

Here is the call graph for this function:

◆ resultUsed() [1/2]

bool DataDependenceGraph::resultUsed ( MoveNode resultNode)

Checks whether a result is used later or if the result move can be dropped.

Parameters
resultNodenode being checked for nonused results.

Definition at line 2348 of file DataDependenceGraph.cc.

2348 {
2349 return resultUsed(resultNode, NULL);
2350}
bool resultUsed(MoveNode &resultNode)

References resultUsed().

Referenced by BUBasicBlockScheduler::bypassNode(), CycleLookBackSoftwareBypasser::bypassNode(), BUBasicBlockScheduler::finalizeSchedule(), BUBasicBlockScheduler::handleDDG(), BUBasicBlockScheduler::handleLoopDDG(), resultUsed(), BUBasicBlockScheduler::scheduleResultReads(), BUBasicBlockScheduler::scheduleResultReadTempMoves(), and BUBasicBlockScheduler::scheduleRRTempMoves().

Here is the call graph for this function:

◆ resultUsed() [2/2]

bool DataDependenceGraph::resultUsed ( MoveNode resultNode,
MoveNode regCopy 
)

Checks whether a result is used later or if the result move can be dropped.

Parameters
resultNodenode being checked for nonused results.
regCopyRegister copy to be removed that might use the result

Definition at line 2360 of file DataDependenceGraph.cc.

2360 {
2361 //naming of this variabl si reverse logic, ok if not used
2362 bool killingWrite = true;
2363 if (!isRootGraphProcedureDDG()) {
2364 killingWrite = false;
2365 }
2366 bool hasRAW = false;
2367 bool hasOtherEdge = false;
2368
2369 EdgeSet edges = rootGraphOutEdges(resultNode);
2370 EdgeSet::iterator edgeIter = edges.begin();
2371 while (edgeIter != edges.end()) {
2372
2373 DataDependenceEdge& edge = *(*edgeIter);
2374 MoveNode& head =
2375 (static_cast<const DataDependenceGraph*>
2376 (rootGraph()))->headNode(edge);
2377 if (regCopy != NULL && &head == regCopy) {
2378 edgeIter++;
2379 continue;
2380 }
2381
2382 // don't case about operation edges.
2383 if (edge.edgeReason() == DataDependenceEdge::EDGE_OPERATION) {
2384 edgeIter++;
2385 continue;
2386 }
2387
2388 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER) {
2389 if (edge.dependenceType() == DataDependenceEdge::DEP_RAW) {
2390 // result is still going to be used
2391 hasRAW = true;
2392 break;
2393 }
2394
2395 if (killingWrite == false) {
2396 // TODO: does this break if the waw dest unconditional?
2397 if (edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
2398 !edge.headPseudo()) {
2399 if (head.isMove() && head.move().isUnconditional()) {
2400 killingWrite = true;
2401 }
2402 }
2403 }
2404
2405 } else {
2406 // there are some other outgoing edges
2407 hasOtherEdge = true;
2408 }
2409 edgeIter++;
2410 }
2411 return (!killingWrite || hasRAW || hasOtherEdge );
2412}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAW, BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, MoveNode::isMove(), isRootGraphProcedureDDG(), TTAProgram::Move::isUnconditional(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), and BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdges().

Here is the call graph for this function:

◆ rWarEdgesOut()

int DataDependenceGraph::rWarEdgesOut ( MoveNode mn)

Calculates number of register WAR antidependecies originating from given node

Parameters
mnMovenodes whose dependencies to calculate
Returns
number of register WAR antidependencies originating from given node

Definition at line 3930 of file DataDependenceGraph.cc.

3930 {
3931 int count = 0;
3932 EdgeSet oEdges = outEdges(mn);
3933 for (EdgeSet::iterator iter =
3934 oEdges.begin(); iter != oEdges.end(); iter++) {
3935 if ((*iter)->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3936 (*iter)->dependenceType() == DataDependenceEdge::DEP_WAR) {
3937 count++;
3938 }
3939 }
3940 return count;
3941}

References DataDependenceEdge::DEP_WAR, DataDependenceEdge::EDGE_REGISTER, and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies().

Here is the call graph for this function:

◆ rWawRawEdgesOutUncond()

bool DataDependenceGraph::rWawRawEdgesOutUncond ( MoveNode mn)
private

Calculates number of register antidependecies originating from given node

Parameters
mnMovenodes whose dependencies to calculate
Returns
number of register antidependencies originating from given node

Definition at line 3978 of file DataDependenceGraph.cc.

3978 {
3979 EdgeSet oEdges = outEdges(mn);
3980 for (EdgeSet::iterator iter =
3981 oEdges.begin(); iter != oEdges.end(); iter++) {
3982 if ((*iter)->edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3983 (((*iter)->dependenceType() == DataDependenceEdge::DEP_RAW) ||
3984 ((*iter)->dependenceType() == DataDependenceEdge::DEP_WAW))) {
3985 MoveNode& head = headNode(**iter);
3986 if (head.move().isUnconditional()) {
3987 return true;
3988 }
3989 }
3990 }
3991 return false;
3992
3993}

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_REGISTER, BoostGraph< MoveNode, DataDependenceEdge >::headNode(), TTAProgram::Move::isUnconditional(), MoveNode::move(), and BoostGraph< MoveNode, DataDependenceEdge >::outEdges().

Here is the call graph for this function:

◆ sameGuards()

bool DataDependenceGraph::sameGuards ( const MoveNode mn1,
const MoveNode mn2 
) const

Definition at line 4506 of file DataDependenceGraph.cc.

4507 {
4508 if (!mn1.isMove() || !mn2.isMove()) {
4509 return false;
4510 }
4511 const TTAProgram::Move& move1 = mn1.move();
4512 const TTAProgram::Move& move2 = mn2.move();
4513
4514 if (move1.isUnconditional() && move2.isUnconditional()) {
4515 return true;
4516 }
4517
4518 if (move1.isUnconditional() || move2.isUnconditional()) {
4519 return false;
4520 }
4521 TTAProgram::MoveGuard& mg1 = move1.guard();
4522 TTAProgram::MoveGuard& mg2 = move2.guard();
4523 if (mg1.isInverted() != mg2.isInverted()) {
4524 return false;
4525 }
4526 NodeSet incomingGuards1 =
4528
4529 NodeSet incomingGuards2 =
4531
4532 return !incomingGuards1.empty() &&
4533 incomingGuards1 == incomingGuards2;
4534}

References TTAProgram::Move::guard(), guardRawPredecessors(), TTAProgram::MoveGuard::isInverted(), MoveNode::isMove(), TTAProgram::Move::isUnconditional(), and MoveNode::move().

Referenced by DataDependenceGraphBuilder::checkAndCreateMemAntideps(), DataDependenceGraphBuilder::createRegisterAntideps(), DataDependenceGraphBuilder::earlierWritesWithSameGuard(), DataDependenceGraphBuilder::hasEarlierMemWriteToSameAddressWithSameGuard(), and DataDependenceGraphBuilder::hasEarlierWriteWithSameGuard().

Here is the call graph for this function:

◆ sanityCheck()

void DataDependenceGraph::sanityCheck ( ) const

Checks that the DDG is sane.

Goes through all edges in the DDG and ensures they make sense, for example, in case of R_RAW, the head should really read the register written by the tail.

Exceptions
Incase the graph contains failures. Exception message contains the reason.

Definition at line 1399 of file DataDependenceGraph.cc.

1399 {
1400 for (int i = 0; i < edgeCount(); ++i) {
1401 DataDependenceEdge& e = edge(i);
1402 MoveNode& tail = tailNode(e);
1403 const TTAProgram::Terminal& tailSource = tail.move().source();
1404 const TTAProgram::Terminal& tailDestination = tail.move().destination();
1405
1406 MoveNode& head = headNode(e);
1407 const TTAProgram::Terminal& headSource = head.move().source();
1408 const TTAProgram::Terminal& headDestination = head.move().destination();
1409
1410 switch (e.dependenceType()) {
1412 if (tailDestination.isFUPort() && headSource.isFUPort())
1413 break; // operation dependency is marked with DEP_UNKNOWN
1414 throw Exception(
1415 __FILE__, __LINE__, __func__,
1416 ((boost::format(
1417 "DEP_UNKNOWN in edge between %s and %s."))
1418 % tail.toString() % head.toString()).str());
1419 break;
1421 // the normal case
1422 if (tailDestination.equals(headSource))
1423 break;
1424
1425 // memory RAW
1427 tailDestination.isFUPort() &&
1428 tailDestination.hintOperation().writesMemory() &&
1429 headDestination.isFUPort() &&
1430 headDestination.hintOperation().readsMemory())
1431 break;
1432
1433 // W:gcu.ra R:ra
1434 if (tailDestination.isFUPort() &&
1435 &tailDestination.functionUnit() ==
1436 tailDestination.functionUnit().machine()->controlUnit() &&
1437 headSource.isFUPort())
1438 break;
1439
1440 // tail writes a reg the head is guarded with
1441 if (!head.move().isUnconditional() && tailDestination.isGPR() &&
1442 dynamic_cast<const TTAMachine::RegisterGuard*>(
1443 &head.move().guard().guard()) != NULL) {
1444 const TTAMachine::RegisterGuard& g =
1445 dynamic_cast<const TTAMachine::RegisterGuard&>(
1446 head.move().guard().guard());
1447 if (g.registerFile() == &tailDestination.registerFile())
1448 break; // TODO: check also the register index
1449 }
1450
1451 // return value register on procedure return
1452 if (tailDestination.isGPR() &&
1453 headDestination.isFUPort() &&
1454 head.move().isControlFlowMove())
1455 break;
1456
1457 writeToDotFile("faulty_raw_ddg.dot");
1458 throw Exception(
1459 __FILE__, __LINE__, __func__,
1460 ((boost::format(
1461 "DEP_RAW in edge between %s and %s."))
1462 % tail.toString() % head.toString()).str());
1463 break;
1465 if (headDestination.equals(tailSource))
1466 break;
1467
1468 // memory WAR
1470 tailDestination.isFUPort() &&
1471 tailDestination.hintOperation().readsMemory() &&
1472 headDestination.isFUPort() &&
1473 headDestination.hintOperation().writesMemory())
1474 break;
1475
1476 // memory WAR between memory op and call
1478 tailDestination.isFUPort() &&
1479 tailDestination.hintOperation().readsMemory() &&
1480 headDestination.isFUPort() &&
1481 head.move().isFunctionCall())
1482 break;
1483
1484 // call parameter register
1485 if (tailDestination.isFUPort() &&
1486 tailSource.isGPR() &&
1487 head.move().isFunctionCall())
1488 break;
1489
1490 // return value register has WaR to 'call'
1491 // no better heuristics yet as we don't know the register RV is
1492 // mapped to
1493 if (tailSource.isGPR() && head.move().isFunctionCall())
1494 break;
1495
1496 // a use (probably a store) of RA has a WaR to 'call'
1497 if (tailSource.isFUPort() && head.move().isFunctionCall())
1498 break;
1499
1500 writeToDotFile("faulty_war_ddg.dot");
1501 throw Exception(
1502 __FILE__, __LINE__, __func__,
1503 ((boost::format(
1504 "DEP_WAR in edge between %s and %s."))
1505 % tail.toString() % head.toString()).str());
1506 break;
1508 if (headDestination.equals(tailDestination))
1509 break;
1510
1511 // memory WAW - can also point to call?
1513 tailDestination.isFUPort() &&
1514 (tailDestination.hintOperation().writesMemory() &&
1515 ((headDestination.isFUPort() &&
1516 headDestination.hintOperation().writesMemory()) ||
1517 (headDestination.isFUPort() &&
1518 head.move().isFunctionCall()))))
1519 break;
1520
1521 // memory WAW between memory op and call
1523 tailDestination.isFUPort() &&
1524 tailDestination.hintOperation().writesMemory() &&
1525 headDestination.isFUPort() &&
1526 head.move().isFunctionCall())
1527 break;
1528
1529 // function parameter registers
1530 if (tailDestination.isGPR() &&
1531 headDestination.isFUPort() &&
1532 head.move().isFunctionCall())
1533 break;
1534
1535 writeToDotFile("faulty_waw_ddg.dot");
1536 throw Exception(
1537 __FILE__, __LINE__, __func__,
1538 ((boost::format(
1539 "DEP_WAW in edge between %s and %s."))
1540 % tail.toString() % head.toString()).str());
1541 break;
1542 default:
1543 throw Exception(
1544 __FILE__, __LINE__, __func__,
1545 ((boost::format(
1546 "Unknown edge type: %d in edge between %s and %s."))
1547 % e.dependenceType() % tail.toString() % head.toString()).
1548 str());
1549 }
1550 }
1551}
virtual bool readsMemory() const
Definition Operation.cc:242
virtual bool writesMemory() const
Definition Operation.cc:252
virtual Machine * machine() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual Operation & hintOperation() const
Definition Terminal.cc:341
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition Terminal.cc:251
virtual bool isFUPort() const
Definition Terminal.cc:118

References __func__, TTAMachine::Machine::controlUnit(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_UNKNOWN, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_MEMORY, BoostGraph< MoveNode, DataDependenceEdge >::edgeCount(), DataDependenceEdge::edgeReason(), TTAProgram::Terminal::equals(), TTAProgram::Terminal::functionUnit(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), TTAProgram::Terminal::hintOperation(), TTAProgram::Move::isControlFlowMove(), TTAProgram::Move::isFunctionCall(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isUnconditional(), TTAMachine::Component::machine(), MoveNode::move(), Operation::readsMemory(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Terminal::registerFile(), TTAProgram::Move::source(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), MoveNode::toString(), Operation::writesMemory(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by BasicBlockScheduler::scheduleOperation(), and BasicBlockScheduler::scheduleRRMove().

Here is the call graph for this function:

◆ scheduledMoves()

DataDependenceGraph::NodeSet DataDependenceGraph::scheduledMoves ( ) const

Returns all scheduled moves.

Parameters
cycleThe cycle.
Returns
Scheduled moves.

Definition at line 1375 of file DataDependenceGraph.cc.

1375 {
1376
1377 NodeSet moves;
1378 int nodeCounter = nodeCount();
1379 for (int i = 0; i < nodeCounter; ++i) {
1380 Node& n = node(i);
1381 if (n.isPlaced())
1382 moves.insert(&n);
1383 }
1384
1385 return moves;
1386}

References MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by ResourceConstraintAnalyzer::memoryBoundScheduleResourceUsage(), BasicBlockScheduler::unscheduleAllNodes(), and BUBasicBlockScheduler::unscheduleAllNodes().

Here is the call graph for this function:

◆ scheduledNodeCount()

int DataDependenceGraph::scheduledNodeCount ( ) const

Returns the count of nodes in the graph that have been scheduled.

Current implementation is quite slow, so don't call in critical places.

Returns
The count of scheduled nodes.

Definition at line 1859 of file DataDependenceGraph.cc.

1859 {
1860
1861 int scheduledCount = 0;
1862 for (int i = 0; i < nodeCount(); ++i) {
1863 Node& n = node(i);
1864 if (n.isPlaced())
1865 ++scheduledCount;
1866 }
1867
1868 return scheduledCount;
1869}

References MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by BUMoveNodeSelector::candidates(), CriticalPathBBMoveNodeSelector::candidates(), BUBasicBlockScheduler::handleDDG(), BasicBlockScheduler::handleDDG(), BF2Scheduler::handleLoopDDG(), BasicBlockScheduler::handleLoopDDG(), BUBasicBlockScheduler::handleLoopDDG(), CriticalPathBBMoveNodeSelector::isReadyToBeScheduled(), BF2Scheduler::scheduleDDG(), BasicBlockScheduler::scheduleMove(), and BUBasicBlockScheduler::unscheduleAllNodes().

Here is the call graph for this function:

◆ setBasicBlockNode()

void DataDependenceGraph::setBasicBlockNode ( const MoveNode mn,
BasicBlockNode bbn 
)

Definition at line 216 of file DataDependenceGraph.cc.

217 {
218 moveNodeBlocks_[&mn] = &bbn;
219}

References moveNodeBlocks_.

Referenced by ControlFlowGraph::mergeNodes().

◆ setCycleGrouping()

void DataDependenceGraph::setCycleGrouping ( bool  flag)
virtual

◆ setEdgeWeightHeuristics()

void DataDependenceGraph::setEdgeWeightHeuristics ( EdgeWeightHeuristics  ewh)

Definition at line 5716 of file DataDependenceGraph.cc.

5716 {
5717 if (edgeWeightHeuristics_ != ewh) {
5718 // force path recalculation
5719 height_ = -1;
5720 sourceDistances_.clear();
5721 sinkDistances_.clear();
5722 // nullify edge weights to recalc them
5723 typedef std::pair<EdgeIter, EdgeIter> EdgeIterPair;
5724 EdgeIterPair edges = boost::edges(graph_);
5725 for (EdgeIter i = edges.first; i != edges.second; i++) {
5726 GraphEdge* e = graph_[*i];
5727 e->setWeight(-1);
5728 }
5729 }
5731}
std::unordered_map< const MoveNode *, int > sourceDistances_
std::unordered_map< const MoveNode *, int > sinkDistances_

References edgeWeightHeuristics_, BoostGraph< MoveNode, DataDependenceEdge >::graph_, BoostGraph< MoveNode, DataDependenceEdge >::height_, GraphEdge::setWeight(), BoostGraph< MoveNode, DataDependenceEdge >::sinkDistances_, and BoostGraph< MoveNode, DataDependenceEdge >::sourceDistances_.

Referenced by ResourceConstraintAnalyzer::analyze(), ResourceConstraintAnalyzer::analyzeRegisterAntideps(), ResourceConstraintAnalyzer::dumpGraphWithStats(), ResourceConstraintAnalyzer::memoryBoundScheduleResourceUsage(), and ResourceConstraintAnalyzer::optimalScheduleResourceUsage().

Here is the call graph for this function:

◆ setMachine()

void DataDependenceGraph::setMachine ( const TTAMachine::Machine machine)

Sets a machine into DDG.

This machine is used to some heuristics and helper functions that selector uses, for example path length calculation and earliestCycle.

If no machine is set, these functions will still work but will give non-optimal results.

Parameters
machinemachine to be used for heristics

Definition at line 3116 of file DataDependenceGraph.cc.

3116 {
3117
3118 if (machine_ == &machine) {
3119 return;
3120 }
3121
3122 // nullify edge weights to recalc them
3123 typedef std::pair<EdgeIter, EdgeIter> EdgeIterPair;
3124 EdgeIterPair edges = boost::edges(graph_);
3125 for (EdgeIter i = edges.first; i != edges.second; i++) {
3126 GraphEdge* e = graph_[*i];
3127 e->setWeight(-1);
3128 }
3129
3130 machine_ = &machine;
3133
3135 rrCost_ = 3;
3136 } else {
3137 // heuristic value about connectivity delays.
3138 rrCost_ = int(
3139 std::max(2.0,
3140 3.0*((3-ma.bypassability()-(ma.connectivity()*2)))));
3141 }
3144
3145 operationLatencies_.clear();
3146 for (int i = 0; i < fuNav.count(); i++) {
3147 const TTAMachine::FunctionUnit* fu = fuNav.item(i);
3148 for (int j = 0; j < fu->operationCount(); j++) {
3149 TTAMachine::HWOperation* hwop = fu->operation(j);
3150 int latency = hwop->latency();
3152 // if does not exist or is existing is bigger update
3154 || latency < operationLatencies_[name]) {
3155 operationLatencies_[name] = latency;
3156 }
3157 }
3158 }
3159 height_ = -1; // force path recalculation
3160 sourceDistances_.clear();
3161 sinkDistances_.clear();
3162 loopingSinkDistances_.clear();
3164}
std::unordered_map< const MoveNode *, int > loopingSinkDistances_
std::unordered_map< const MoveNode *, int > loopingSourceDistances_
const TTAMachine::Machine & machine() const
static std::string stringToUpper(const std::string &source)
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
const std::string & name() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
static UniversalMachine & instance()

References MachineAnalysis::bypassability(), MachineAnalysis::connectivity(), AssocTools::containsKey(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::ControlUnit::delaySlots(), delaySlots_, TTAMachine::Machine::functionUnitNavigator(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, BoostGraph< MoveNode, DataDependenceEdge >::height_, UniversalMachine::instance(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAMachine::HWOperation::latency(), BoostGraph< MoveNode, DataDependenceEdge >::loopingSinkDistances_, BoostGraph< MoveNode, DataDependenceEdge >::loopingSourceDistances_, machine(), machine_, BoostGraph< MoveNode, DataDependenceEdge >::name(), TTAMachine::HWOperation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), operationLatencies_, rrCost_, GraphEdge::setWeight(), BoostGraph< MoveNode, DataDependenceEdge >::sinkDistances_, BoostGraph< MoveNode, DataDependenceEdge >::sourceDistances_, and StringTools::stringToUpper().

Referenced by DataDependenceGraphBuilder::build(), DataDependenceGraphBuilder::build(), BUMoveNodeSelector::BUMoveNodeSelector(), BUMoveNodeSelector::BUMoveNodeSelector(), BUMoveNodeSelector::BUMoveNodeSelector(), createSubgraph(), CriticalPathBBMoveNodeSelector::CriticalPathBBMoveNodeSelector(), CriticalPathBBMoveNodeSelector::CriticalPathBBMoveNodeSelector(), CriticalPathBBMoveNodeSelector::CriticalPathBBMoveNodeSelector(), criticalPathGraph(), BF2Scheduler::handleLoopDDG(), memoryDependenceGraph(), BF2Scheduler::scheduleDDG(), and trueDependenceGraph().

Here is the call graph for this function:

◆ setNodeBB()

void DataDependenceGraph::setNodeBB ( MoveNode mn,
BasicBlockNode bblock,
DataDependenceGraph modifier 
)

Sets bookkeeping that the given movende belongs to the given basic block.

Parameters
mnMoveNode given
bblockBasic Block node where the move node belongs
modifiermodifier graph on the subgraph tree

Definition at line 119 of file DataDependenceGraph.cc.

120 {
121 moveNodeBlocks_[&mn] = &bblock;
122
123 if (parentGraph_ != NULL && parentGraph_ != modifier) {
124 static_cast<DataDependenceGraph*>(parentGraph_)->
125 setNodeBB(mn, bblock, this);
126 }
127
128 for (unsigned int i = 0; i < childGraphs_.size(); i++) {
129 if ( childGraphs_[i] != modifier ) {
130 static_cast<DataDependenceGraph*>(childGraphs_[i])->
131 setNodeBB(mn,bblock,this);
132 }
133 }
134}

References BoostGraph< MoveNode, DataDependenceEdge >::childGraphs_, moveNodeBlocks_, BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, and setNodeBB().

Referenced by addNode(), addNode(), and setNodeBB().

Here is the call graph for this function:

◆ setProgramOperationNodes()

virtual void DataDependenceGraph::setProgramOperationNodes ( bool  flag)
inlinevirtual

◆ smallestCycle()

int DataDependenceGraph::smallestCycle ( ) const

Returns the smallest cycle of a move in the DDG.

Current implementation is quite slow, so don't call in critical places.

Returns
The smallest cycle of a move.

Definition at line 1818 of file DataDependenceGraph.cc.

1818 {
1819
1820 int minCycle = INT_MAX;
1821 for (int i = 0; i < nodeCount(); ++i) {
1822 Node& n = node(i);
1823 if (n.isPlaced())
1824 minCycle = std::min(minCycle, n.cycle());
1825 }
1826
1827 return minCycle;
1828}

References MoveNode::cycle(), MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by ResourceConstraintAnalyzer::analyzeRegisterAntideps(), dotString(), BBSchedulerController::executeDDGPass(), and BUBasicBlockScheduler::handleLoopDDG().

Here is the call graph for this function:

◆ sourceRenamed()

DataDependenceGraph::UndoData DataDependenceGraph::sourceRenamed ( MoveNode mn)

Source of a move is renamed to a register which is not used in this ddg. Removes old edges not needed anymore.

If destination of edge also renamed to this reg, keep the edge, update the data of the edge.

Parameters
mnMoveNode whose source or guard is renamed.
guardtrue if renamed gaurd, not source.

Definition at line 4970 of file DataDependenceGraph.cc.

4970 {
4971
4972 UndoData undoData;
4973
4974 TTAProgram::Terminal& term = mn.move().source();
4975 const TCEString newReg = DisassemblyRegister::registerName(term);
4976
4977 for (int i = 0; i < outDegree(mn); i++) {
4978 DataDependenceEdge& oEdge = outEdge(mn,i);
4979
4982 !oEdge.tailPseudo() && !oEdge.guardUse()) {
4983
4984 MoveNode& head = headNode(oEdge);
4985 TTAProgram::Terminal& writeTerm = head.move().destination();
4986
4987 // if this edge disappers because of the renaming?
4988 if (oEdge.headPseudo() ||
4989 (writeTerm.isGPR() && (
4990 writeTerm.index() != term.index() ||
4991 &writeTerm.registerFile() != &term.registerFile()))) {
4992 undoData.removedEdges.insert(RemovedEdgeDatum(mn, head, oEdge));
4993 removeEdge(oEdge, NULL, &mn);
4994 i--; // don't skip one edge here!
4995 } else {
4996 // update the edge. also other end changed
4997 undoData.changedDataEdges[&oEdge] = oEdge.data();
4998 oEdge.setData(newReg);
4999 }
5000 }
5001 }
5002 return undoData;
5003}

References DataDependenceGraph::UndoData::changedDataEdges, DataDependenceEdge::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), TTAProgram::Terminal::index(), TTAProgram::Terminal::isGPR(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), TTAProgram::Terminal::registerFile(), DisassemblyRegister::registerName(), DataDependenceGraph::UndoData::removedEdges, BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), DataDependenceEdge::setData(), TTAProgram::Move::source(), and DataDependenceEdge::tailPseudo().

Referenced by BFRenameLiveRange::renameLiveRange(), and RegisterRenamer::renameLiveRange().

Here is the call graph for this function:

◆ successorsReady()

bool DataDependenceGraph::successorsReady ( MoveNode node) const

Checks whether the given node has all its successors scheduled.

Ignores intra operation edges, thus if the successor belongs to the same operation, it need not be scheduled for the node to be considered ready.

Returns
True in case all successors are scheduled.

Definition at line 3228 of file DataDependenceGraph.cc.

3228 {
3229
3230 // use the internal data structures to make this fast.
3231 // edgeset has too much set overhead,
3232 // inedge(n,i) is O(n^2) , this is linear with no overhead
3234 std::pair<OutEdgeIter, OutEdgeIter> edges =
3235 boost::out_edges(nd, graph_);
3236
3237 for (OutEdgeIter ei = edges.first; ei != edges.second; ei++) {
3238 EdgeDescriptor ed = *ei;
3240 if (edge.isBackEdge()) {
3241 continue;
3242 }
3243 const MoveNode& m = *graph_[boost::target(ed, graph_)];
3244
3245 const bool operandMoveOfSameOperation =
3246 (node.isDestinationOperation() && m.isSourceOperation() &&
3247 &node.destinationOperation() == &m.sourceOperation());
3248 const bool resultMoveOfSameOperation =
3249 (node.isSourceOperation() && m.isSourceOperation() &&
3250 &node.sourceOperation() == &m.sourceOperation());
3251 const bool operandsOfSameOperation =
3252 (node.isDestinationOperation() && m.isDestinationOperation() &&
3253 &node.destinationOperation() == &m.destinationOperation());
3254 if (operandMoveOfSameOperation || resultMoveOfSameOperation ||
3255 operandsOfSameOperation) {
3256 continue;
3257 }
3258 if (!m.isPlaced()) {
3259 return false;
3260 }
3261 }
3262 return true;
3263}

References BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), MoveNode::destinationOperation(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, GraphEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isPlaced(), MoveNode::isSourceOperation(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and MoveNode::sourceOperation().

Here is the call graph for this function:

◆ trueDependenceGraph()

DataDependenceGraph * DataDependenceGraph::trueDependenceGraph ( bool  removeMemAntideps = true,
bool  ignoreMemDeps = false 
)

Returns a version of the graph with only true dependence edges.

Definition at line 3417 of file DataDependenceGraph.cc.

3418 {
3419 DataDependenceGraph* subGraph =
3422 NULL, false, false);
3423 NodeSet nodes;
3424 for (int i = 0; i < nodeCount(); ++i) {
3425 nodes.insert(&node(i));
3426 }
3427 if (machine_ != NULL)
3428 subGraph->setMachine(*machine_);
3429
3430 constructSubGraph(*subGraph, nodes);
3431
3432 for (int i = 0; i < nodeCount(); i++) {
3433 MoveNode& tail = node(i);
3434 for (int e = 0; e < subGraph->outDegree(tail);) {
3435 DataDependenceEdge& edge = subGraph->outEdge(tail,e);
3436 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
3438 e++;
3439 continue;
3440 }
3441 // consider the memory dependencies
3442 if (edge.edgeReason() == DataDependenceEdge::EDGE_MEMORY &&
3443 (ignoreMemDeps || (edge.isFalseDep() && removeMemAntideps))) {
3444 subGraph->dropEdge(edge);
3445 } else {
3446 e++;
3447 }
3448 }
3449 }
3450 return subGraph;
3451}
virtual void dropEdge(Edge &edge)
bool isNotAvoidable(const DataDependenceEdge &edge) const

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), BoostGraph< GraphNode, GraphEdge >::dropEdge(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_REGISTER, isNotAvoidable(), machine_, BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), BoostGraph< GraphNode, GraphEdge >::outDegree(), BoostGraph< GraphNode, GraphEdge >::outEdge(), registerAntidependenceLevel_, and setMachine().

Referenced by ResourceConstraintAnalyzer::analyzeRegisterAntideps().

Here is the call graph for this function:

◆ undo()

void DataDependenceGraph::undo ( UndoData undoData)

Definition at line 5898 of file DataDependenceGraph.cc.

5898 {
5899 for (auto i : undoData.changedDataEdges) {
5900 i.first->setData(i.second);
5901 }
5902
5903 for (auto i: undoData.removedEdges) {
5904 connectNodes(i.nTail, i.nHead, i.edge);
5905 }
5906
5907 for (auto i: undoData.newEdges) {
5908 removeEdge(*i);
5909 }
5910}

References DataDependenceGraph::UndoData::changedDataEdges, BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceGraph::UndoData::newEdges, DataDependenceGraph::UndoData::removedEdges, and BoostGraph< MoveNode, DataDependenceEdge >::removeEdge().

Referenced by BFRenameLiveRange::undoOnlyMe().

Here is the call graph for this function:

◆ unMergeUser()

void DataDependenceGraph::unMergeUser ( MoveNode sourceNode,
MoveNode mergedNode,
bool  loopBypass = false 
)

Reverses work done by mergeAndKeep routine

changes node to read it's data from register and returns the original edges.

Parameters
sourceNodenode which writes to the register mergedNode should read.
mergedNodenode being changed

Definition at line 2240 of file DataDependenceGraph.cc.

2240 {
2241
2242
2243 // name of the bypass reg.
2244 TTAProgram::Terminal& dest = sourceNode.move().destination();
2245 assert(dest.isGPR());
2247
2248 // if this is not rootgraph, do it there. allows this to work even if
2249 // source node being deleted from this this sub-ddg.
2250 if (rootGraph() != this) {
2251 static_cast<DataDependenceGraph*>(rootGraph())->
2252 unMergeUser(sourceNode, mergedNode, loopBypass);
2253 if (loopBypass) {
2254 fixAntidepsAfterLoopUnmergeUser(sourceNode, mergedNode, regName);
2255 }
2256 return;
2257 }
2258
2259 // unset programoperation from bypassed
2260 if (mergedNode.isSourceOperation()) {
2261 ProgramOperation& srcOp = mergedNode.sourceOperation();
2262 srcOp.removeOutputNode(mergedNode);
2263 mergedNode.unsetSourceOperation();
2264
2265 // unset fu annotations
2269 }
2270
2271 // All incoming RAW and operation dependencies were created by
2272 // the bypassing, originally there was just one RAW edge which was removed.
2273 // so remove the incoming edges merge routine copied to here.
2274 // these can be operation edges or ordinary register RaWs.
2275 // these should only go to source node.
2276 for (int i = 0; i < inDegree(mergedNode); i++) {
2277 DataDependenceEdge& edge = inEdge(mergedNode,i);
2278 // removes operation edges and
2279 if (edge.edgeReason() == DataDependenceEdge::EDGE_OPERATION ||
2280 (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2281 edge.dependenceType() == DataDependenceEdge::DEP_RAW &&
2282 !edge.headPseudo() && !edge.guardUse())) {
2283 removeEdge(edge, NULL, &mergedNode);
2284 i--; // do not skip next edge which now has same index
2285 }
2286 }
2287
2288 // do the actual unmerge by returning source to original register.
2289 mergedNode.move().setSource(sourceNode.move().destination().copy());
2290
2291 bool nodeRegToItselfCopy = false;
2292 if (mergedNode.move().source().equals(mergedNode.move().destination())) {
2293 nodeRegToItselfCopy = true;
2294 }
2295
2296 // create register edge between nodes.
2297 // this was removed by the merge.
2301 false, false, false, false, loopBypass);
2302 connectNodes(sourceNode, mergedNode, *dde);
2303
2304 // remove war antidependence edges that should
2305 // come from source. these should only come from the
2306 if (sourceNode.isSourceVariable()) {
2307 for( int i = 0; i < outDegree(mergedNode); i++) {
2308 DataDependenceEdge& edge = outEdge(mergedNode,i);
2309 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2310 edge.dependenceType() == DataDependenceEdge::DEP_WAR &&
2311 edge.data() != regName && !edge.tailPseudo() &&
2312 !edge.guardUse()) {
2313 removeEdge(edge, &mergedNode, NULL);
2314 i--; // do not skip next edge which now has same index
2315 }
2316 }
2317 }
2318
2319 // All all outgoing WAR's to merged node. The war's go to
2320 // all same places where WAW's fo from source node.
2321 for (int i = 0; i < outDegree(sourceNode); i++) {
2322 DataDependenceEdge& edge = outEdge(sourceNode,i);
2323 if (edge.edgeReason() == DataDependenceEdge::EDGE_REGISTER &&
2324 edge.dependenceType() == DataDependenceEdge::DEP_WAW &&
2325 edge.data() == regName) {
2326 MoveNode& dest = headNode(edge);
2327 // skip nodes with exclusive guard.
2328 if (!exclusingGuards(dest, mergedNode)) {
2331 DataDependenceEdge::DEP_WAR, regName, false, false,
2332 false, edge.headPseudo(), edge.loopDepth() - loopBypass +
2333 nodeRegToItselfCopy);
2334 connectNodes(mergedNode, dest, *newEdge);
2335 }
2336 }
2337 }
2338}
void fixAntidepsAfterLoopUnmergeUser(MoveNode &sourceNode, MoveNode &mergedNode, const TCEString &reg)
void unMergeUser(MoveNode &resultNode, MoveNode &mergedNode, bool loopBypass=false)
void unsetSourceOperation()
Definition MoveNode.cc:760
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)

References TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_SRC, assert, BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), TTAProgram::Terminal::copy(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, TTAProgram::Terminal::equals(), exclusingGuards(), fixAntidepsAfterLoopUnmergeUser(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), TTAProgram::Terminal::isGPR(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), DisassemblyRegister::registerName(), TTAProgram::AnnotatedInstructionElement::removeAnnotations(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), ProgramOperation::removeOutputNode(), BoostGraph< MoveNode, DataDependenceEdge >::rootGraph(), TTAProgram::Move::setSource(), TTAProgram::Move::source(), MoveNode::sourceOperation(), unMergeUser(), and MoveNode::unsetSourceOperation().

Referenced by CycleLookBackSoftwareBypasser::bypassNode(), CycleLookBackSoftwareBypasser::removeBypass(), BUBasicBlockScheduler::undoBypass(), unMergeUser(), and BUBasicBlockScheduler::unscheduleAllNodes().

Here is the call graph for this function:

◆ unscheduledMoves()

DataDependenceGraph::NodeSet DataDependenceGraph::unscheduledMoves ( ) const

Returns all unscheduled moves.

Parameters
cycleThe cycle.
Returns
Unscheduled moves.

Definition at line 1355 of file DataDependenceGraph.cc.

1355 {
1356
1357 NodeSet moves;
1358 int nodeCounter = nodeCount();
1359 for (int i = 0; i < nodeCounter; ++i) {
1360 Node& n = node(i);
1361 if (!n.isPlaced())
1362 moves.insert(&n);
1363 }
1364
1365 return moves;
1366}

References MoveNode::isPlaced(), BoostGraph< MoveNode, DataDependenceEdge >::node(), and BoostGraph< MoveNode, DataDependenceEdge >::nodeCount().

Referenced by BUMoveNodeSelector::candidates(), CriticalPathBBMoveNodeSelector::candidates(), CriticalPathBBMoveNodeSelector::isReadyToBeScheduled(), and BasicBlockScheduler::scheduleMove().

Here is the call graph for this function:

◆ updateRegUse()

void DataDependenceGraph::updateRegUse ( const MoveNodeUse mnd,
const TCEString reg,
TTAProgram::BasicBlock bb 
)

Creates dependencies from incoming definitions in other BB's to a reg use.

Parameters
mnddata about the register usage.

Definition at line 5367 of file DataDependenceGraph.cc.

5368 {
5369
5370 // create RAW's from definitions in previous BBs.
5371 std::set<MoveNodeUse>& defReaches =
5373 for (std::set<MoveNodeUse>::iterator i = defReaches.begin();
5374 i != defReaches.end(); i++) {
5375
5376 const MoveNodeUse& source = *i;
5377 if (hasNode(*source.mn())) {
5378 DataDependenceEdge* dde =
5379 // create dependency edge
5382 DataDependenceEdge::EDGE_REGISTER,
5383 DataDependenceEdge::DEP_RAW, reg, mnd.guard(), false,
5384 source.pseudo(), mnd.pseudo(), source.loop());
5385
5386 // and connect.
5387 connectOrDeleteEdge(*source.mn(), *mnd.mn(), dde);
5388 }
5389 }
5390}
find Finds info of the inner loops in the false
bool ra() const
LiveRangeData * liveRangeData_
MoveNodeUseMapSet regDefReaches_

References connectOrDeleteEdge(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, MoveNodeUse::guard(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), TTAProgram::BasicBlock::liveRangeData_, MoveNodeUse::loop(), MoveNodeUse::mn(), MoveNodeUse::pseudo(), MoveNodeUse::ra(), and LiveRangeData::regDefReaches_.

Referenced by DataDependenceGraphBuilder::constructIndividualFromInlineAsmBB(), DataDependenceGraphBuilder::processRegUse(), and DataDependenceGraphBuilder::updateBB().

Here is the call graph for this function:

◆ updateRegWrite()

DataDependenceGraph::EdgeSet DataDependenceGraph::updateRegWrite ( const MoveNodeUse mnd,
const TCEString reg,
TTAProgram::BasicBlock bb 
)

Creates dependencies to a register write from MN's in other BBs.

Parameters
mndmovenode which writes to a register
regregister wrere the movenode writes to
createAllAntidepswhether to create antideps from all BB's or just from same bb in case of single-bb loop.

Definition at line 5401 of file DataDependenceGraph.cc.

5402 {
5403 // WaWs
5404
5406
5407 std::set<MoveNodeUse>& defReaches =
5409 for (std::set<MoveNodeUse>::iterator i = defReaches.begin();
5410 i != defReaches.end(); i++) {
5411
5412 const MoveNodeUse& source = *i;
5413 if (hasNode(*source.mn()) && source.mn()->isMove() &&
5415 &getBasicBlockNode(*source.mn()) ==
5416 &getBasicBlockNode(*mnd.mn()))) {
5417 // create dependency edge
5418 DataDependenceEdge* dde =
5421 DataDependenceEdge::EDGE_REGISTER,
5422 DataDependenceEdge::DEP_WAW, reg, false, false,
5423 source.pseudo(), mnd.pseudo(), source.loop());
5424 // and connect.
5425 if (connectOrDeleteEdge(*source.mn(), *mnd.mn(), dde)) {
5426 addedEdges.insert(dde);
5427 }
5428 }
5429 }
5430
5431 // WaRs
5432 std::set<MoveNodeUse>& useReaches =
5434 for (std::set<MoveNodeUse>::iterator i = useReaches.begin();
5435 i != useReaches.end(); i++) {
5436
5437 const MoveNodeUse& source = *i;
5438 if (hasNode(*source.mn()) && source.mn()->isMove() &&
5440 &getBasicBlockNode(*source.mn()) ==
5441 &getBasicBlockNode(*mnd.mn()))) {
5442 // create dependency edge
5443 DataDependenceEdge* dde =
5446 DataDependenceEdge::EDGE_REGISTER,
5447 DataDependenceEdge::DEP_WAR, reg, source.guard(), false,
5448 source.pseudo(), mnd.pseudo(), source.loop());
5449 // and connect.
5450 if (connectOrDeleteEdge(*source.mn(), *mnd.mn(), dde)) {
5451 addedEdges.insert(dde);
5452 }
5453 }
5454 }
5455 return addedEdges;
5456}
MoveNodeUseMapSet regUseReaches_

References connectOrDeleteEdge(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, getBasicBlockNode(), MoveNodeUse::guard(), hasAllRegisterAntidependencies(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), MoveNode::isMove(), TTAProgram::BasicBlock::liveRangeData_, MoveNodeUse::loop(), MoveNodeUse::mn(), MoveNodeUse::pseudo(), MoveNodeUse::ra(), LiveRangeData::regDefReaches_, and LiveRangeData::regUseReaches_.

Referenced by DataDependenceGraphBuilder::processRegWrite(), and DataDependenceGraphBuilder::updateBB().

Here is the call graph for this function:

◆ writesJumpGuard()

bool DataDependenceGraph::writesJumpGuard ( const MoveNode moveNode)

Returns true if the node writes a value to a predicate register which is used as a guard of a jump.

Definition at line 4593 of file DataDependenceGraph.cc.

4593 {
4594 NodeSet succs = successors(moveNode);
4595 for (auto n: succs) {
4596 if (n->move().isJump()) {
4597 if (onlyGuardDefOfMove(*n) == &moveNode) {
4598 return true;
4599 }
4600 }
4601 }
4602 return false;
4603}

References onlyGuardDefOfMove(), and BoostGraph< MoveNode, DataDependenceEdge >::successors().

Here is the call graph for this function:

◆ writeToXMLFile()

void DataDependenceGraph::writeToXMLFile ( std::string  fileName) const

Writes the graph into an XML file.

Definition at line 1747 of file DataDependenceGraph.cc.

1747 {
1748
1749 XMLSerializer serializer;
1750 ObjectState topOS = ObjectState("dependenceinfo");
1751 ObjectState* labelOS = new ObjectState("label", &topOS);
1752 ObjectState* nodesOS = new ObjectState("nodes", &topOS);
1753 ObjectState* edgesOS = new ObjectState("edges", &topOS);
1754
1755 // Name of the unit
1756 labelOS->setValue(name());
1757
1758 // Populate the nodes element
1759 for (int i = 0; i < nodeCount(); ++i) {
1760 ObjectState* nodeOS = new ObjectState("node", nodesOS);
1761 ObjectState* idOS = new ObjectState("id", nodeOS);
1762 ObjectState* labelOS = new ObjectState("label", nodeOS);
1763
1764 Node& n = node(i);
1765
1766 idOS->setValue(n.nodeID());
1767 labelOS->setValue(n.toString());
1768
1769 if (n.isPlaced()) {
1770 ObjectState* cycleOS = new ObjectState("cycle", nodeOS);
1771 ObjectState* busOS = new ObjectState("slot", nodeOS);
1772
1773 cycleOS->setValue(Conversion::toString(n.cycle()));
1774 busOS->setValue(n.move().bus().name());
1775 }
1776 }
1777
1778 // Populate the edges element
1779 typedef std::pair<EdgeIter, EdgeIter> EdgeIterPair;
1780 EdgeIterPair edges = boost::edges(graph_);
1781 for (EdgeIter i = edges.first; i != edges.second; i++) {
1782 Edge& e = *graph_[*i];
1783 Node& tail = *graph_[boost::source(*i, graph_)];
1784 Node& head = *graph_[boost::target(*i, graph_)];
1785 edgesOS->addChild(e.saveState(tail, head));
1786 }
1787
1788 // Implicit operand to trigger edges
1789 for (int i = 0; i < nodeCount(); ++i) {
1790 Node& n = node(i);
1791 if (n.isPlaced() && n.isMove() && n.move().isTriggering() &&
1792 n.isDestinationOperation()) {
1793 ProgramOperation &dst = n.destinationOperation();
1794 for (int j = 0; j < dst.inputMoveCount(); ++j) {
1795 if (dst.inputMove(j).nodeID() != n.nodeID()) {
1796
1797 // Create a dummy edge and dump it
1800 edgesOS->addChild(e.saveState(dst.inputMove(j), n));
1801 }
1802 }
1803 }
1804 }
1805
1806 serializer.setDestinationFile(fileName);
1807 serializer.writeState(&topOS);
1808}
void setValue(const std::string &value)
void addChild(ObjectState *child)
virtual void writeState(const ObjectState *rootState)
void setDestinationFile(const std::string &fileName)

References ObjectState::addChild(), TTAProgram::Move::bus(), MoveNode::cycle(), DataDependenceEdge::DEP_TRIGGER, MoveNode::destinationOperation(), DataDependenceEdge::EDGE_OPERATION, BoostGraph< MoveNode, DataDependenceEdge >::graph_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), MoveNode::isMove(), MoveNode::isPlaced(), TTAProgram::Move::isTriggering(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::name(), TTAMachine::Component::name(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), GraphNode::nodeID(), DataDependenceEdge::saveState(), XMLSerializer::setDestinationFile(), ObjectState::setValue(), MoveNode::toString(), Conversion::toString(), and XMLSerializer::writeState().

Referenced by BasicBlockScheduler::ddgSnapshot(), BasicBlockPass::ddgSnapshot(), BF2Scheduler::handleLoopDDG(), BBSchedulerController::handleProcedure(), and BF2Scheduler::scheduleDDG().

Here is the call graph for this function:

Member Data Documentation

◆ allParamRegs_

std::set<TCEString> DataDependenceGraph::allParamRegs_
private

◆ cycleGrouping_

bool DataDependenceGraph::cycleGrouping_
private

Dot printing related variables. Group the printed MoveNodes according to their cycles.

Definition at line 442 of file DataDependenceGraph.hh.

Referenced by dotString(), and setCycleGrouping().

◆ delaySlots_

int DataDependenceGraph::delaySlots_
private

◆ dotProgramOperationNodes_

bool DataDependenceGraph::dotProgramOperationNodes_
private

The moves belonging to the same program operation are merged to a single node. Reduces the complexity of the graph.

Definition at line 445 of file DataDependenceGraph.hh.

Referenced by dotString(), and setProgramOperationNodes().

◆ edgeWeightHeuristics_

EdgeWeightHeuristics DataDependenceGraph::edgeWeightHeuristics_
private

The heuristics to use to weight edges in the longest path computation.

Definition at line 458 of file DataDependenceGraph.hh.

Referenced by edgeWeight(), and setEdgeWeightHeuristics().

◆ machine_

const TTAMachine::Machine* DataDependenceGraph::machine_
private

◆ moveNodeBlocks_

std::map<const MoveNode*, BasicBlockNode*> DataDependenceGraph::moveNodeBlocks_
private

◆ nodesOfMoves_

std::map<const TTAProgram::Move*, MoveNode*> DataDependenceGraph::nodesOfMoves_
private

Definition at line 434 of file DataDependenceGraph.hh.

Referenced by addNode(), nodeOfMove(), and removeNode().

◆ operationLatencies_

std::map<TCEString, int> DataDependenceGraph::operationLatencies_
private

Definition at line 450 of file DataDependenceGraph.hh.

Referenced by getOperationLatency(), and setMachine().

◆ ownedBBN_

BasicBlockNode* DataDependenceGraph::ownedBBN_
private

Definition at line 453 of file DataDependenceGraph.hh.

Referenced by ~DataDependenceGraph().

◆ procedureDDG_

bool DataDependenceGraph::procedureDDG_
private

Definition at line 454 of file DataDependenceGraph.hh.

Referenced by dotString(), and isRootGraphProcedureDDG().

◆ programOperations_

POList DataDependenceGraph::programOperations_
private

◆ registerAntidependenceLevel_

AntidependenceLevel DataDependenceGraph::registerAntidependenceLevel_
private

◆ rrCost_

int DataDependenceGraph::rrCost_
private

Definition at line 451 of file DataDependenceGraph.hh.

Referenced by edgeWeight(), and setMachine().


The documentation for this class was generated from the following files: