OpenASIP  2.0
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 MoveNode ::Comparator > NodeSet
 
typedef std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
 
typedef MoveNode Node
 The (base) node type managed by this graph. More...
 
typedef DataDependenceEdge Edge
 The (base) edge type managed by this graph. More...
 
- Public Types inherited from GraphBase< MoveNode, DataDependenceEdge >
typedef std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
 
typedef std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
 
typedef MoveNode Node
 Node type of this graph (possibly, a base class). More...
 
typedef DataDependenceEdge Edge
 Edge type of this graph (possibly, a base class). More...
 

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. More...
 
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 More...
 
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< MoveNode, DataDependenceEdge >
 GraphBase ()
 
virtual ~GraphBase ()
 
virtual TCEString dotString () const
 
virtual void writeToDotFile (const TCEString &fileName) const
 

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. More...
 
bool dotProgramOperationNodes_
 The moves belonging to the same program operation are merged to a single node. Reduces the complexity of the graph. More...
 
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. More...
 

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. More...
 
typedef boost::graph_traits< GraphGraphTraits
 Traits characterising the internal graph type. More...
 
typedef GraphTraits::out_edge_iterator OutEdgeIter
 Output edge iterator type. More...
 
typedef GraphTraits::in_edge_iterator InEdgeIter
 Input edge iterator type. More...
 
typedef GraphTraits::edge_iterator EdgeIter
 Iterator type for the list of all edges in the graph. More...
 
typedef GraphTraits::vertex_iterator NodeIter
 Iterator type for the list of all nodes in the graph. More...
 
typedef GraphTraits::edge_descriptor EdgeDescriptor
 Type with which edges of the graph are seen internally. More...
 
typedef GraphTraits::vertex_descriptor NodeDescriptor
 Type with which nodes of the graph are seen internally. More...
 
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 Attributes inherited from BoostGraph< MoveNode, DataDependenceEdge >
std::map< const MoveNode *, int, typename MoveNode ::Comparator > sourceDistances_
 
std::map< const MoveNode *, int, typename MoveNode ::Comparator > sinkDistances_
 
std::map< const MoveNode *, int, typename MoveNode ::Comparator > loopingSourceDistances_
 
std::map< const MoveNode *, int, typename MoveNode ::Comparator > loopingSinkDistances_
 
int height_
 
Graph graph_
 The internal graph structure. More...
 
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.

78  {
83  };

◆ DumpFileFormat

Enumerator
DUMP_DOT 
DUMP_XML 

Definition at line 85 of file DataDependenceGraph.hh.

85  {
86  DUMP_DOT,
87  DUMP_XML
88  };

◆ 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  };

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 }

Referenced by createSubgraph(), criticalPathGraph(), memoryDependenceGraph(), and trueDependenceGraph().

◆ ~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 }

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 }

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 }

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_)
307  ->addProgramOperation(po);
308  }
309 }

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

Referenced by 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 }

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  {
3358  if (hasEqualEdge(tailNode, headNode, *edge)) {
3359  delete edge;
3360  return false;
3361  } else {
3363  return true;
3364  }
3365 }

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

Referenced by DataDependenceGraphBuilder::checkAndCreateMemDep(), 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  }
3836  DataDependenceEdge* newEdge = new DataDependenceEdge(
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  }
3852  DataDependenceEdge* newEdge = new DataDependenceEdge(
3853  *edge, (moveOverLoopEdge && head != &src && head != &dst));
3854  connectNodes(dst, *head, *newEdge);
3855  }
3856 }

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

Referenced by MoveNodeDuplicator::duplicateMoveNode().

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
2463  new DataDependenceEdge(
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
2493  new DataDependenceEdge(
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 }

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 CycleLookBackSoftwareBypasser::bypassNode(), BUBasicBlockScheduler::bypassNode(), destRenamed(), mergeAndKeepSource(), BFDREEarly::operator()(), BFDRELate::operator()(), BFPostpassDRE::operator()(), BFPostpassLoopDRE::operator()(), BFDRELoop::operator()(), renamedSimpleLiveRange(), BUBasicBlockScheduler::tryToOptimizeWaw(), BasicBlockScheduler::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
2566  new DataDependenceEdge(
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
2606  new DataDependenceEdge(
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
2633  new DataDependenceEdge(
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;
2659  if ((iEdge.dependenceType() == DataDependenceEdge::DEP_WAR ||
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
2670  new DataDependenceEdge(
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
2728  new DataDependenceEdge(
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;
2752  if ((iEdge.dependenceType() == DataDependenceEdge::DEP_WAR ||
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
2763  new DataDependenceEdge(
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 }

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(), DataDependenceEdge::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) {
5332  DataDependenceEdge* newEdge = new DataDependenceEdge(edge);
5333  connectNodes(tail, nodeCopy, *newEdge);
5334  }
5335  }
5336 }

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) {
5355  DataDependenceEdge* newEdge = new DataDependenceEdge(edge);
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;
3882  edge->guardUse()) {
3883  DataDependenceEdge* newEdge = new DataDependenceEdge(*edge);
3884  MoveNode& tail = *graph_[boost::source(ed, graph_)];
3885  connectNodes(tail, dst, *newEdge);
3886  }
3887  }
3888 }

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

Referenced by BUBasicBlockScheduler::tryToOptimizeWaw(), and BasicBlockScheduler::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;
5787  !edge->guardUse()) {
5788  DataDependenceEdge* newEdge = new DataDependenceEdge(*edge);
5789  MoveNode& tail = *graph_[boost::source(ed, graph_)];
5790  connectNodes(tail, dst, *newEdge);
5791  }
5792  }
5793 }

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

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;
3914  edge->guardUse()) {
3915  DataDependenceEdge* newEdge = new DataDependenceEdge(*edge);
3916  MoveNode& head = *graph_[boost::target(ed, graph_)];
3917  connectNodes(dst, head, *newEdge);
3918  }
3919  }
3920 }

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

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

Here is the call graph for this function:

◆ createRegisterAntiDependenciesBetweenNodes()

void DataDependenceGraph::createRegisterAntiDependenciesBetweenNodes ( 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)) {
4436  new DataDependenceEdge(
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)) {
4449  new DataDependenceEdge(
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 }

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 =
3380  new DataDependenceGraph(
3381  allParamRegs_, "", registerAntidependenceLevel_, NULL, false,
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 }

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), DataDependenceGraph(), 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(), 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 }

References createSubgraph(), TTAProgram::Instruction::isInProcedure(), MoveNode::isMove(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Move::parent(), and TTAProgram::Instruction::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 }

References createSubgraph(), TTAProgram::Move::isInInstruction(), TTAProgram::Instruction::isInProcedure(), MoveNode::isMove(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), TTAProgram::Move::parent(), and TTAProgram::Instruction::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 =
3460  new DataDependenceGraph(
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 }

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), DataDependenceGraph(), 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  {
2883  removeNode(node);
2884  delete &node;
2885 }

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++) {
5142  DataDependenceEdge& edge = outEdge(mn,i);
5143 
5145  continue;
5146  }
5147 
5149  !edge.tailPseudo()) {
5150  // update the data!
5151  edge.setData(newReg);
5152 
5153  } else {
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 }

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::MoveGuard::guard(), TTAProgram::Move::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(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::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.

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 }

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 }

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) {
400  DataDependenceEdge& edge = **i;
401 
402  if (ignoreGuards && edge.guardUse()) {
403  continue;
404  }
405 
406  if (ignoreFuDeps &&
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.
442  moveNode.isSourceOperation() && tail.inSameOperation(moveNode)) {
443  effTailCycle += getOperationLatency(edge.data());
445 
446  // ignore reg antidep? then skip over this edge.
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  }
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 }

References __func__, assert, MoveNode::cycle(), DataDependenceEdge::data(), delaySlots_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), MoveNode::destinationOperation(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_FUSTATE, DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), getOperationLatency(), MoveNode::guardLatency(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::hasNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inEdges(), MoveNode::inSameOperation(), DataDependenceEdge::isBackEdge(), MoveNode::isDestinationOperation(), MoveNode::isPlaced(), MoveNode::isSourceOperation(), DataDependenceEdge::loopDepth(), 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(), ResourceConstraintAnalyzer::findResourceConstrainedParent(), ResourceConstraintAnalyzer::memoryBoundScheduleResourceUsage(), BFPushMoveUp::operator()(), BFPushAntidepDown::operator()(), BFPushMoveUp2::operator()(), BFScheduleExact::operator()(), BFScheduleBU::operator()(), BasicBlockScheduler::scheduleMove(), BUBasicBlockScheduler::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;
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  }
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()) {
343  latency += (head->guardLatency()-1);
344  } else {
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 DataDependenceEdge::data(), delaySlots_, DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::edgeReason(), getOperationLatency(), MoveNode::guardLatency(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), MoveNode::inSameOperation(), MoveNode::isSourceOperation(), DataDependenceEdge::loopDepth(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), DataDependenceEdge::tailPseudo(), and DataDependenceEdge::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 }

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 =
4496  guardRawPredecessors(mn1);
4497 
4498  NodeSet incomingGuards2 =
4499  guardRawPredecessors(mn2);
4500 
4501  return !incomingGuards1.empty() &&
4502  incomingGuards1 == incomingGuards2;
4503 }

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

Referenced by DataDependenceGraphBuilder::checkAndCreateMemDep(), copyDepsOver(), RegisterCopyAdder::createAntidepsForReg(), createRegisterAntiDependenciesBetweenNodes(), DataDependenceGraphBuilder::createRegisterAntideps(), DataDependenceGraphBuilder::createSideEffectEdges(), ExecutionPipelineResource::exclusiveMoves(), mergeAndKeepAllowed(), mergeAndKeepUser(), DataDependenceGraphBuilder::processRegUse(), DataDependenceGraphBuilder::processRegWrite(), BUBasicBlockScheduler::tryToOptimizeWaw(), BasicBlockScheduler::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
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 }

References DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), DataDependenceEdge::headPseudo(), 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 
4900  if (!queueRawPredecessors(
4901  queuedReads, liveRange->reads, queuedWrites,
4902  liveRange->writes, false)) {
4903  liveRange->clear();
4904  return liveRange;
4905  }
4906 
4907  if (!queueRawPredecessors(
4908  queuedGuards, liveRange->guards, queuedWrites,
4909  liveRange->writes, true)) {
4910  liveRange->clear();
4911  return liveRange;
4912  }
4913  }
4914  return liveRange;
4915 }

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 }

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 }

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 }

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 }

References allParamRegs_, assert, MoveNode::cycle(), delaySlots_, TTAProgram::Move::destination(), TTAProgram::MoveGuard::guard(), TTAProgram::Move::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(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::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 
1329  TTAProgram::Terminal& dest = n.move().destination();
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 }

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 
1259  TTAProgram::Terminal& dest = n.move().destination();
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 BFRegCopy::createAntidepsForReg(), RegisterCopyAdder::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);
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::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), 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) {
3774  new DataDependenceEdge(
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) {
3785  new DataDependenceEdge(
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) {
3796  new DataDependenceEdge(
3798  DataDependenceEdge::DEP_WAR, reg2, true, false, false,
3799  false, loopEdges);
3800  connectOrDeleteEdge(nodeOfMove(*move1), mn2, edge);
3801  }
3802  }
3803 }

References BasicBlockNode::basicBlock(), connectOrDeleteEdge(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, TTAProgram::MoveGuard::guard(), TTAProgram::Move::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(), 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 =
3306  operationLatencies_.find(name);
3307  if (iter != operationLatencies_.end()) {
3308  return iter->second;
3309  } else {
3310  return 1;
3311  }
3312 }

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
5807  edge.data() == regName) {
5810  continue;
5811  }
5812  }
5813  assert(!edge.guardUse());
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 =
5823  new DataDependenceEdge(
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
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 }

References assert, BoostGraph< GraphNode, GraphEdge >::connectNodes(), DataDependenceEdge::data(), DataDependenceEdge::DEP_UNKNOWN, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), 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 DataDependenceEdge::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++) {
749  DataDependenceEdge &edge = **i;
750  if (edge.guardUse() &&
752  guardDefMoves.insert(&tailNode(edge));
753  }
754  }
755  return guardDefMoves;
756 }

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

Referenced by 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() +
5016  '.' + Conversion::toString(rg->registerIndex());
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 }

References assert, DataDependenceGraph::UndoData::changedDataEdges, DataDependenceEdge::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::MoveGuard::guard(), TTAProgram::Move::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(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::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() &&
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.
5874  DataDependenceEdge::DEP_RAW, regName,
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);
5886  edge.data() == regName) {
5887  MoveNode& head = headNode(edge);
5888  // skip nodes with exclusive guard.
5889  DataDependenceEdge* newEdge = new DataDependenceEdge(
5891  DataDependenceEdge::DEP_WAR, regName, true, false,
5892  false, edge.headPseudo(), edge.loopDepth());
5893  connectNodes(dst, head, *newEdge);
5894  }
5895  }
5896 }

References assert, BoostGraph< MoveNode, DataDependenceEdge >::connectNodes(), DataDependenceEdge::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), TTAProgram::Terminal::isGPR(), DataDependenceEdge::loopDepth(), 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()(), BFEarlyGuardBypass::undoOnlyMe(), and BFLateBypassGuard::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 }

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

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

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;
5528  DataDependenceEdge& edge = *graph_[ed];
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 }

References AssocTools::containsKey(), DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::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 }

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 }

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++ ) {
1922  DataDependenceEdge* edge = *i;
1924  edge->isBackEdge()) {
1925  return true;
1926  }
1927  }
1928  return false;
1929 }

References BoostGraph< MoveNode, DataDependenceEdge >::connectingEdges(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), and DataDependenceEdge::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  */
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 
5585  ((tail.move().isUnconditional() && !head.move().isUnconditional()) ||
5586  (!tail.move().isUnconditional() && head.move().isUnconditional())))
5587  return true;
5588 
5589 
5590  return false;
5591 }

References BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::MoveGuard::guard(), TTAProgram::Move::guard(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), TTAMachine::Guard::isEqual(), DataDependenceEdge::isFalseDep(), 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 BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_, and procedureDDG_.

Referenced by resultUsed().

◆ 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(), BUBasicBlockScheduler::handleLoopDDG(), BasicBlockScheduler::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::MoveGuard::guard(), TTAProgram::Move::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(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::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 }

References MoveNode::cycle(), TTAProgram::MoveGuard::guard(), TTAProgram::Move::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 
1294  TTAProgram::Terminal& dest = n.move().destination();
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 BFRegCopy::createAntidepsForReg(), RegisterCopyAdder::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 BFRegCopy::createAntidepsForReg(), RegisterCopyAdder::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 
1218  TTAProgram::Terminal& dest = n.move().destination();
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 BFRegCopy::createAntidepsForReg(), RegisterCopyAdder::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) {
557  DataDependenceEdge& edge = **i;
558 
559  if (ignoreGuards && edge.guardUse()) {
560  continue;
561  }
562  if (ignoreFuDeps &&
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 {
590 
591  // ignore deg antidep? then skip over this edge.
593  && !edge.tailPseudo() && ignoreRegAntideps) {
594  continue;
595  }
596 
597  // latency does not matter with WAW. always +1.
598  effHeadCycle -= 1;
599  } else {
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 
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 
683  maxCycle = std::min(maxCycle, inputMove.cycle()-1);
684  }
685  }
686  }
687  }
688 
689  return maxCycle;
690 }

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

Referenced by CycleLookBackSoftwareBypasser::bypass(), BFSchedulePreLoopShared::operator()(), BFPushAntidepsDown::operator()(), BFRemoveGuardsFromSuccs::operator()(), BFPushMoveUp::operator()(), BFShareOperands::operator()(), BFPushAntidepDown::operator()(), BFPushMoveUp2::operator()(), BFScheduleExact::operator()(), BasicBlockScheduler::scheduleMove(), BUBasicBlockScheduler::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 =
3484  new DataDependenceGraph(
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;
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;
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(), DataDependenceGraph(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::edgeReason(), 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);
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 }

References __func__, DataDependenceEdge::DEP_WAR, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), exclusingGuards(), BoostGraph< MoveNode, DataDependenceEdge >::hasEdge(), BoostGraph< MoveNode, DataDependenceEdge >::hasPath(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), MoveNode::isMove(), BoostGraph< MoveNode, DataDependenceEdge >::outDegree(), BoostGraph< MoveNode, DataDependenceEdge >::outEdge(), DataDependenceEdge::tailPseudo(), MoveNode::toString(), and GraphBase< MoveNode, DataDependenceEdge >::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?
1976  ProgramOperationPtr dstOp = userNode.destinationOperationPtr();
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++) {
2010  DataDependenceEdge& edge = rootGraphOutEdge(userNode,i);
2011 
2012  // skip antidependencies due bypassed register.. these are no more
2014  edge.data() == regName) {
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
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  }
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 }

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::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), MoveNode::destinationOperationPtr(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::Terminal::equals(), DataDependenceEdge::guardUse(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::ProgramAnnotation::id(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), DataDependenceEdge::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
2149  edge.data() == regName) {
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);
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++) {
2193  DataDependenceEdge& edge = rootGraphOutEdge(userNode,i);
2194 
2195  // create new WaW in place of old 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 }

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::data(), DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::Terminal::equals(), exclusingGuards(), DataDependenceEdge::guardUse(), BoostGraph< GraphNode, GraphEdge >::headNode(), TTAProgram::ProgramAnnotation::id(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), DataDependenceEdge::isBackEdge(), DataDependenceEdge::isFalseDep(), 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(), BoostGraph< GraphNode, GraphEdge >::tailNode(), and DataDependenceEdge::tailPseudo().

Referenced by RegisterCopyAdder::addConnectionRegisterCopies(), CycleLookBackSoftwareBypasser::bypassNode(), and BUBasicBlockScheduler::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 }

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

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

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++) {
259  DataDependenceEdge &edge = inEdge(mn, i);
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, DataDependenceEdge::edgeReason(), 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++) {
280  DataDependenceEdge &edge = outEdge(mn, i);
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, DataDependenceEdge::edgeReason(), 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 MoveNode::isSourceReg(), 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;
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::guardUse(), DataDependenceEdge::headPseudo(), DataDependenceEdge::isBackEdge(), and DataDependenceEdge::tailPseudo().

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;
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::headPseudo(), DataDependenceEdge::isBackEdge(), and DataDependenceEdge::tailPseudo().

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;
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::guardUse(), DataDependenceEdge::headPseudo(), DataDependenceEdge::isBackEdge(), and DataDependenceEdge::tailPseudo().

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(
5915  descriptor(node), graph_);
5916 
5917  EdgeSet result;
5918 
5919  for (InEdgeIter ei = edges.first; ei != edges.second; ++ei) {
5920  DataDependenceEdge* edge = graph_[(*ei)];
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_, DataDependenceEdge::edgeReason(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BFPushMoveUp2::isLoopBypass(), and ExecutionPipelineBroker::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;
3276  DataDependenceEdge& edge = *graph_[ed];
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_, DataDependenceEdge::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;
3190  DataDependenceEdge& edge = *graph_[ed];
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() &&
3200  (m.isSourceOperation() &&
3201  &node.sourceOperation() == &m.sourceOperation())) {
3202  continue;
3203  }
3204  }
3205 
3206  if (dstOp && m.isDestinationOperation() &&
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_, DataDependenceEdge::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(
5932  descriptor(node), graph_);
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_, DataDependenceEdge::isRegisterOrRA(), 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 BUBasicBlockScheduler::tryToOptimizeWaw(), and BasicBlockScheduler::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;
5474  DataDependenceEdge& edge = *graph_[ed];
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::guardUse(), and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BasicBlockScheduler::scheduleMove(), BUBasicBlockScheduler::scheduleMove(), BUBasicBlockScheduler::tryToOptimizeWaw(), BasicBlockScheduler::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()) {
2857  srcOp.removeOutputNode(node);
2859  }
2860 
2861  if (node.isDestinationOperation()) {
2862  for (int i = node.destinationOperationCount() - 1; i >= 0; i--) {
2864  dstOp.removeInputNode(node);
2865  }
2867  }
2868  }
2869 
2870 // copyAntidepsOver(node);
2871 
2872  // remove node from graph
2874 }

References MoveNode::clearDestinationOperation(), MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), MoveNode::isDestinationOperation(), MoveNode::isMove(), MoveNode::isSourceOperation(), MoveNode::move(), BoostGraph< MoveNode, DataDependenceEdge >::node(), nodesOfMoves_, ProgramOperation::removeInputNode(), BoostGraph< GraphNode, GraphEdge >::removeNode(), ProgramOperation::removeOutputNode(), MoveNode::sourceOperation(), and MoveNode::unsetSourceOperation().

Referenced by deleteNode(), MoveNodeDuplicator::disposeMoveNode(), ControlFlowGraph::removeJumpToTarget(), ControlFlowGraph::removeUnreachableNodes(), and BFRegCopy::undoDDG().

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;
5504  DataDependenceEdge& edge = *graph_[ed];
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::descriptor(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::graph_, DataDependenceEdge::guardUse(), and BoostGraph< MoveNode, DataDependenceEdge >::node().

Referenced by BUBasicBlockScheduler::tryToOptimizeWaw(), and BasicBlockScheduler::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) {
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::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), BoostGraph< MoveNode, DataDependenceEdge >::removeEdge(), MoveNode::toString(), and GraphBase< MoveNode, DataDependenceEdge >::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 
5220  DataDependenceEdge* warEdge = new DataDependenceEdge(
5223  newReg, false, false, false, false, 0);
5224 
5225  DataDependenceEdge* wawEdge = new DataDependenceEdge(
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 }

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 }

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

◆ 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.
2384  edgeIter++;
2385  continue;
2386  }
2387 
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?
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, DataDependenceEdge::dependenceType(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::headPseudo(), 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 =
4527  guardRawPredecessors(mn1);
4528 
4529  NodeSet incomingGuards2 =
4530  guardRawPredecessors(mn2);
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 }

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::MoveGuard::guard(), TTAProgram::Move::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(), TTAProgram::Terminal::registerFile(), TTAMachine::RegisterGuard::registerFile(), TTAProgram::Move::source(), BoostGraph< MoveNode, DataDependenceEdge >::tailNode(), MoveNode::toString(), Operation::writesMemory(), and GraphBase< MoveNode, DataDependenceEdge >::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(), BUBasicBlockScheduler::handleLoopDDG(), BasicBlockScheduler::handleLoopDDG(), BF2Scheduler::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  }
5730  edgeWeightHeuristics_ = ewh;
5731 }

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 
3134  if (&machine == &UniversalMachine::instance()) {
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();
3163  loopingSourceDistances_.clear();
3164 }

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_, TTAMachine::HWOperation::name(), BoostGraph< MoveNode, DataDependenceEdge >::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(), BUMoveNodeSelector::BUMoveNodeSelector(), createSubgraph(), 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_, and BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_.

Referenced by addNode().

◆ 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;
3239  DataDependenceEdge& edge = *graph_[ed];
3240  if (edge.isBackEdge()) {
3241  continue;
3242  }
3243  const MoveNode& m = *graph_[boost::target(ed, graph_)];
3244 
3245  const bool operandMoveOfSameOperation =
3248  const bool resultMoveOfSameOperation =
3250  &node.sourceOperation() == &m.sourceOperation());
3251  const bool operandsOfSameOperation =
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_, DataDependenceEdge::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 =
3420  new DataDependenceGraph(
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);
3437  isNotAvoidable(edge)) {
3438  e++;
3439  continue;
3440  }
3441  // consider the memory dependencies
3443  (ignoreMemDeps || (edge.isFalseDep() && removeMemAntideps))) {
3444  subGraph->dropEdge(edge);
3445  } else {
3446  e++;
3447  }
3448  }
3449  }
3450  return subGraph;
3451 }

References allParamRegs_, BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph(), DataDependenceGraph(), BoostGraph< GraphNode, GraphEdge >::dropEdge(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_MEMORY, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), DataDependenceEdge::isFalseDep(), 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
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.
2300  DataDependenceEdge::DEP_RAW, regName,
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);
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);
2325  edge.data() == regName) {
2326  MoveNode& dest = headNode(edge);
2327  // skip nodes with exclusive guard.
2328  if (!exclusingGuards(dest, mergedNode)) {
2329  DataDependenceEdge* newEdge = new DataDependenceEdge(
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 }

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::data(), DataDependenceEdge::DEP_RAW, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::dependenceType(), TTAProgram::Move::destination(), BoostGraph< MoveNode, DataDependenceEdge >::edge(), DataDependenceEdge::EDGE_OPERATION, DataDependenceEdge::EDGE_REGISTER, DataDependenceEdge::edgeReason(), TTAProgram::Terminal::equals(), exclusingGuards(), fixAntidepsAfterLoopUnmergeUser(), DataDependenceEdge::guardUse(), BoostGraph< MoveNode, DataDependenceEdge >::headNode(), DataDependenceEdge::headPseudo(), BoostGraph< MoveNode, DataDependenceEdge >::inDegree(), BoostGraph< MoveNode, DataDependenceEdge >::inEdge(), TTAProgram::Terminal::isGPR(), MoveNode::isSourceOperation(), MoveNode::isSourceVariable(), DataDependenceEdge::loopDepth(), 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(), DataDependenceEdge::tailPseudo(), and MoveNode::unsetSourceOperation().

Referenced by CycleLookBackSoftwareBypasser::bypassNode(), CycleLookBackSoftwareBypasser::removeBypass(), BUBasicBlockScheduler::undoBypass(), 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 =
5372  bb.liveRangeData_->regDefReaches_[reg];
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
5380  new DataDependenceEdge(
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 }

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 
5405  DataDependenceGraph::EdgeSet addedEdges;
5406 
5407  std::set<MoveNodeUse>& defReaches =
5408  bb.liveRangeData_->regDefReaches_[reg];
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 =
5419  new DataDependenceEdge(
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 =
5433  bb.liveRangeData_->regUseReaches_[reg];
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 =
5444  new DataDependenceEdge(
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 }

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 }

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(), TTAMachine::Component::name(), BoostGraph< MoveNode, DataDependenceEdge >::name(), BoostGraph< MoveNode, DataDependenceEdge >::node(), BoostGraph< MoveNode, DataDependenceEdge >::nodeCount(), GraphNode::nodeID(), DataDependenceEdge::saveState(), XMLSerializer::setDestinationFile(), ObjectState::setValue(), Conversion::toString(), MoveNode::toString(), and XMLSerializer::writeState().

Referenced by BasicBlockPass::ddgSnapshot(), BasicBlockScheduler::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:
DataDependenceGraph::EWH_DEFAULT
@ EWH_DEFAULT
Definition: DataDependenceGraph.hh:94
TTAMachine::Guard
Definition: Guard.hh:55
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
BoostGraph< MoveNode, DataDependenceEdge >::loopingSinkDistances_
std::map< const MoveNode *, int, typename MoveNode ::Comparator > loopingSinkDistances_
Definition: BoostGraph.hh:326
SimValue::intValue
int intValue() const
Definition: SimValue.cc:895
BoostGraph< MoveNode, DataDependenceEdge >::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
DataDependenceGraph::SINGLE_BB_LOOP_ANTIDEPS
@ SINGLE_BB_LOOP_ANTIDEPS
Definition: DataDependenceGraph.hh:81
DataDependenceGraph::isLoopBypass
bool isLoopBypass(MoveNode &sourceNode, MoveNode &userNode)
Definition: DataDependenceGraph.cc:1916
BoostGraph< MoveNode, DataDependenceEdge >::outEdge
virtual Edge & outEdge(const Node &node, const int index) const
BoostGraph< MoveNode, DataDependenceEdge >::connectNodes
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
Operation::writesMemory
virtual bool writesMemory() const
Definition: Operation.cc:252
DataDependenceGraph::dotProgramOperationNodes_
bool dotProgramOperationNodes_
The moves belonging to the same program operation are merged to a single node. Reduces the complexity...
Definition: DataDependenceGraph.hh:445
TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_SRC
@ ANN_REJECTED_UNIT_SRC
Src. unit rejected.
Definition: ProgramAnnotation.hh:118
BoostGraph< MoveNode, DataDependenceEdge >::removeEdge
virtual void removeEdge(Edge &e)
DataDependenceGraph::delaySlots_
int delaySlots_
Definition: DataDependenceGraph.hh:449
DataDependenceGraph::machine
const TTAMachine::Machine & machine() const
Definition: DataDependenceGraph.hh:260
MoveNodeUse::mn
const MoveNode * mn() const
Definition: MoveNodeUse.hh:39
BoostGraph< MoveNode, DataDependenceEdge >::sourceDistances_
std::map< const MoveNode *, int, typename MoveNode ::Comparator > sourceDistances_
Definition: BoostGraph.hh:318
BoostGraph< MoveNode, DataDependenceEdge >::tailNode
virtual Node & tailNode(const Edge &edge) const
ProgramOperation::removeInputNode
void removeInputNode(MoveNode &node)
Definition: ProgramOperation.cc:289
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
BoostGraph< MoveNode, DataDependenceEdge >::hasEdge
virtual bool hasEdge(const Node &nTail, const Node &nHead) const
BoostGraph< MoveNode, DataDependenceEdge >::headNode
virtual Node & headNode(const Edge &edge) const
DataDependenceGraph::registerAntidependenceLevel_
AntidependenceLevel registerAntidependenceLevel_
Definition: DataDependenceGraph.hh:455
TTAMachine::HWOperation
Definition: HWOperation.hh:52
DataDependenceEdge::DEP_TRIGGER
@ DEP_TRIGGER
Definition: DataDependenceEdge.hh:50
TTAProgram::Move::isFunctionCall
bool isFunctionCall() const
Definition: Move.cc:219
BoostGraph< MoveNode, DataDependenceEdge >::node
Node & node(const int index) const
DataDependenceEdge::isBackEdge
bool isBackEdge() const
Definition: DataDependenceEdge.hh:118
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
BoostGraph< MoveNode, DataDependenceEdge >::hasPath
bool hasPath(MoveNode &src, const MoveNode &dest) const
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInDegree
virtual int rootGraphInDegree(const Node &node) const
DataDependenceGraph::resultUsed
bool resultUsed(MoveNode &resultNode)
Definition: DataDependenceGraph.cc:2348
BoostGraph< MoveNode, DataDependenceEdge >::moveInEdges
virtual void moveInEdges(const Node &source, const Node &destination)
TTAProgram::Terminal::registerFile
virtual const TTAMachine::RegisterFile & registerFile() const
Definition: Terminal.cc:225
MoveNode::isDestinationOperation
bool isDestinationOperation() const
TTAProgram::MoveGuard::isInverted
bool isInverted() const
Definition: MoveGuard.cc:76
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
TTAProgram::Move::sourceLineNumber
int sourceLineNumber() const
Definition: Move.cc:459
MoveNodeUse::pseudo
bool pseudo() const
Definition: MoveNodeUse.hh:42
MoveNodeUse
Definition: MoveNodeUse.hh:20
BoostGraph< MoveNode, DataDependenceEdge >::Edge
DataDependenceEdge Edge
The (base) edge type managed by this graph.
Definition: BoostGraph.hh:92
TTAMachine::Guard::isEqual
virtual bool isEqual(const Guard &guard) const =0
MachineAnalysis
Definition: MachineAnalysis.hh:40
LiveRangeData::regUseReaches_
MoveNodeUseMapSet regUseReaches_
Definition: LiveRangeData.hh:91
DataDependenceGraph::addProgramOperation
void addProgramOperation(ProgramOperationPtr po)
Definition: DataDependenceGraph.cc:298
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
BoostGraph::copyInEdge
virtual void copyInEdge(const Node &destination, Edge &edge, const Node *tail=NULL)
TTAProgram::Terminal::hintOperation
virtual Operation & hintOperation() const
Definition: Terminal.cc:341
GraphNode::nodeID
int nodeID() const
DataDependenceEdge::setData
void setData(const TCEString &newData)
Definition: DataDependenceEdge.cc:331
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
DataDependenceEdge::isFalseDep
bool isFalseDep() const
Definition: DataDependenceEdge.hh:95
MoveNode::clearDestinationOperation
void clearDestinationOperation()
Definition: MoveNode.cc:730
ObjectState
Definition: ObjectState.hh:59
MoveNode::isSourceReg
bool isSourceReg(const std::string &reg) const
Definition: MoveNode.cc:798
ProgramOperation
Definition: ProgramOperation.hh:70
DataDependenceGraph::setMachine
void setMachine(const TTAMachine::Machine &machine)
Definition: DataDependenceGraph.cc:3116
MoveNode
Definition: MoveNode.hh:65
DataDependenceGraph::rrCost_
int rrCost_
Definition: DataDependenceGraph.hh:451
DataDependenceGraph::nodesOfMoves_
std::map< const TTAProgram::Move *, MoveNode * > nodesOfMoves_
Definition: DataDependenceGraph.hh:434
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdge
virtual Edge & rootGraphOutEdge(const Node &node, const int index) const
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutDegree
virtual int rootGraphOutDegree(const Node &node) const
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
BoostGraph::addNode
virtual void addNode(Node &node)
TTAMachine::Machine::triggerInvalidatesResults
bool triggerInvalidatesResults() const
Definition: Machine.cc:964
TTAMachine::Machine::Navigator::count
int count() const
BoostGraph< MoveNode, DataDependenceEdge >::edgeCount
int edgeCount() const
BoostGraph< MoveNode, DataDependenceEdge >::loopingSourceDistances_
std::map< const MoveNode *, int, typename MoveNode ::Comparator > loopingSourceDistances_
Definition: BoostGraph.hh:324
BoostGraph< MoveNode, DataDependenceEdge >::moveOutEdge
virtual void moveOutEdge(const Node &source, const Node &destination, Edge &edge, const Node *head=NULL, bool childs=false)
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
LiveRangeData::regDefReaches_
MoveNodeUseMapSet regDefReaches_
Definition: LiveRangeData.hh:90
BoostGraph< MoveNode, DataDependenceEdge >::sinkDistances_
std::map< const MoveNode *, int, typename MoveNode ::Comparator > sinkDistances_
Definition: BoostGraph.hh:320
DataDependenceGraph::onlyRegisterRawSource
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
Definition: DataDependenceGraph.cc:4083
Conversion::toString
static std::string toString(const T &source)
DataDependenceEdge::tailPseudo
bool tailPseudo() const
Definition: DataDependenceEdge.hh:109
ProgramOperation::triggeringMove
MoveNode * triggeringMove() const
Definition: ProgramOperation.cc:643
DataDependenceGraph::lastScheduledRegisterKill
MoveNode * lastScheduledRegisterKill(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1285
DataDependenceGraph::guardDefMoves
NodeSet guardDefMoves(const MoveNode &moveNode)
Definition: DataDependenceGraph.cc:743
MoveNodeUse::loop
bool loop() const
Definition: MoveNodeUse.hh:43
BoostGraph< MoveNode, DataDependenceEdge >::edgeDescriptors_
EdgeDescMap edgeDescriptors_
Definition: BoostGraph.hh:340
DataDependenceGraph::EWH_HEURISTIC
@ EWH_HEURISTIC
Weights memory dependencies more, etc.
Definition: DataDependenceGraph.hh:91
DataDependenceGraph::guardRawPredecessors
NodeSet guardRawPredecessors(const MoveNode &node) const
Definition: DataDependenceGraph.cc:4048
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
BoostGraph< MoveNode, DataDependenceEdge >::outDegree
virtual int outDegree(const Node &node) const
BoostGraph< MoveNode, DataDependenceEdge >::moveInEdge
virtual void moveInEdge(const Node &source, const Node &destination, Edge &edge, const Node *tail=NULL, bool childs=false)
MoveNode::isPlaced
bool isPlaced() const
Definition: MoveNode.cc:352
MoveNode::setSourceOperationPtr
void setSourceOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:541
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdge
virtual Edge & rootGraphInEdge(const Node &node, const int index) const
StringTools::stringToUpper
static std::string stringToUpper(const std::string &source)
Definition: StringTools.cc:143
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
DataDependenceGraph::setNodeBB
void setNodeBB(MoveNode &mn, BasicBlockNode &bblock, DataDependenceGraph *updater)
Definition: DataDependenceGraph.cc:119
DataDependenceGraph::queueRawPredecessors
bool queueRawPredecessors(NodeSet &queue, NodeSet &finalDest, NodeSet &predQueue, NodeSet &predFinalDest, bool guard) const
Definition: DataDependenceGraph.cc:4918
DataDependenceGraph::createSubgraph
DataDependenceGraph * createSubgraph(NodeSet &nodes, bool includeLoops=false)
Definition: DataDependenceGraph.cc:3377
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphOutEdges
virtual EdgeSet rootGraphOutEdges(const Node &node) const
LiveRange::clear
void clear()
Definition: LiveRange.cc:129
DataDependenceEdge::DEP_UNKNOWN
@ DEP_UNKNOWN
Definition: DataDependenceEdge.hh:46
MoveNode::isMove
bool isMove() const
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
Definition: ProgramAnnotation.hh:112
TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_DST
@ ANN_REJECTED_UNIT_DST
Dst. unit rejected.
Definition: ProgramAnnotation.hh:119
DataDependenceGraph::programOperations_
POList programOperations_
Definition: DataDependenceGraph.hh:437
TTAProgram::ProgramAnnotation::id
ProgramAnnotation::Id id() const
Definition: ProgramAnnotation.cc:111
TTAMachine::BaseRegisterFile
Definition: BaseRegisterFile.hh:48
TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
Definition: ProgramAnnotation.hh:115
DataDependenceGraph::procedureDDG_
bool procedureDDG_
Definition: DataDependenceGraph.hh:454
GraphEdge::weight
int weight() const
Definition: GraphEdge.hh:73
MoveNodeUse::ra
bool ra() const
Definition: MoveNodeUse.hh:41
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
DataDependenceGraph::ALL_ANTIDEPS
@ ALL_ANTIDEPS
Definition: DataDependenceGraph.hh:82
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
MoveNode::guardLatency
int guardLatency() const
Definition: MoveNode.cc:779
TTAProgram::Move::isControlFlowMove
bool isControlFlowMove() const
Definition: Move.cc:233
DataDependenceGraph::largestCycle
int largestCycle() const
Definition: DataDependenceGraph.cc:1838
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
BoostGraph< MoveNode, DataDependenceEdge >::rootGraph
BoostGraph * rootGraph()
InvalidData
Definition: Exception.hh:149
DataDependenceEdge::loopDepth
int loopDepth() const
Definition: DataDependenceEdge.hh:121
BoostGraph< MoveNode, DataDependenceEdge >::EdgeSet
std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
BoostGraph::removeNode
virtual void removeNode(Node &node)
TTAProgram::BasicBlock::liveRangeData_
LiveRangeData * liveRangeData_
Definition: BasicBlock.hh:111
MoveNodeSet::at
MoveNode & at(int index)
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
DataDependenceEdge::DEP_RAW
@ DEP_RAW
Definition: DataDependenceEdge.hh:47
BoostGraph< MoveNode, DataDependenceEdge >::connectingEdge
EdgeDescriptor connectingEdge(const Node &nTail, const Node &nHead) const
DataDependenceGraph::INTRA_BB_ANTIDEPS
@ INTRA_BB_ANTIDEPS
Definition: DataDependenceGraph.hh:80
TTAMachine::RegisterGuard
Definition: Guard.hh:137
BoostGraph< MoveNode, DataDependenceEdge >::inEdge
virtual Edge & inEdge(const Node &node, const int index) const
DataDependenceGraph::DUMP_XML
@ DUMP_XML
Definition: DataDependenceGraph.hh:87
BoostGraph< MoveNode, DataDependenceEdge >::childGraphs_
std::vector< BoostGraph< MoveNode, DataDependenceEdge > * > childGraphs_
Definition: BoostGraph.hh:378
DataDependenceEdge::EDGE_FUSTATE
@ EDGE_FUSTATE
Definition: DataDependenceEdge.hh:55
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
DataDependenceEdge::EDGE_OPERATION
@ EDGE_OPERATION
Definition: DataDependenceEdge.hh:56
DataDependenceGraph::nodeOfMove
MoveNode & nodeOfMove(const TTAProgram::Move &move)
Definition: DataDependenceGraph.cc:3600
BoostGraph< MoveNode, DataDependenceEdge >::moveOutEdges
virtual void moveOutEdges(const Node &source, const Node &destination)
XMLSerializer::setDestinationFile
void setDestinationFile(const std::string &fileName)
Definition: XMLSerializer.cc:142
__func__
#define __func__
Definition: Application.hh:67
DataDependenceGraph::machine_
const TTAMachine::Machine * machine_
Definition: DataDependenceGraph.hh:448
TTAProgram::Instruction::parent
CodeSnippet & parent() const
Definition: Instruction.cc:109
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
DataDependenceGraph::removeNode
void removeNode(MoveNode &node)
Definition: DataDependenceGraph.cc:2843
BasicBlockNode
Definition: BasicBlockNode.hh:64
DataDependenceEdge::isRegisterOrRA
bool isRegisterOrRA() const
Definition: DataDependenceEdge.hh:129
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
DataDependenceGraph::onlyGuardDefOfMove
MoveNode * onlyGuardDefOfMove(MoveNode &moveNode)
Definition: DataDependenceGraph.cc:4581
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
ObjectState::addChild
void addChild(ObjectState *child)
Definition: ObjectState.cc:376
DataDependenceEdge::toString
TCEString toString() const
Definition: DataDependenceEdge.cc:201
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
TTAProgram::Terminal::value
virtual SimValue value() const
Definition: Terminal.cc:178
DataDependenceGraph::connectOrDeleteEdge
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
Definition: DataDependenceGraph.cc:3355
DataDependenceGraph::smallestCycle
int smallestCycle() const
Definition: DataDependenceGraph.cc:1818
BoostGraph< MoveNode, DataDependenceEdge >::Node
MoveNode Node
The (base) node type managed by this graph.
Definition: BoostGraph.hh:90
TTAProgram::Terminal::immediateUnit
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition: Terminal.cc:240
MoveNode::unsetSourceOperation
void unsetSourceOperation()
Definition: MoveNode.cc:760
Operation::readsMemory
virtual bool readsMemory() const
Definition: Operation.cc:242
DataDependenceGraph::programOperationCount
int programOperationCount() const
Definition: DataDependenceGraph.cc:246
LiveRange::writes
DataDependenceGraph::NodeSet writes
Definition: LiveRange.hh:39
DataDependenceGraph::DUMP_DOT
@ DUMP_DOT
Definition: DataDependenceGraph.hh:86
TTAProgram::Move
Definition: Move.hh:55
TTAMachine::ControlUnit::delaySlots
int delaySlots() const
ProgramOperation::removeGuardOutputNode
void removeGuardOutputNode(MoveNode &node)
Definition: ProgramOperation.cc:249
Exception
Definition: Exception.hh:54
DataDependenceGraph::unMergeUser
void unMergeUser(MoveNode &resultNode, MoveNode &mergedNode, bool loopBypass=false)
Definition: DataDependenceGraph.cc:2240
BoostGraph< MoveNode, DataDependenceEdge >::EdgeDescriptor
GraphTraits::edge_descriptor EdgeDescriptor
Type with which edges of the graph are seen internally.
Definition: BoostGraph.hh:262
TTAProgram::Move::isInInstruction
bool isInInstruction() const
Definition: Move.cc:144
MoveNodeUse::guard
bool guard() const
Definition: MoveNodeUse.hh:40
DataDependenceGraph::ownedBBN_
BasicBlockNode * ownedBBN_
Definition: DataDependenceGraph.hh:453
DataDependenceGraph::fixAntidepsAfterLoopUnmergeUser
void fixAntidepsAfterLoopUnmergeUser(MoveNode &sourceNode, MoveNode &mergedNode, const TCEString &reg)
Definition: DataDependenceGraph.cc:2213
MoveNode::unsetGuardOperation
void unsetGuardOperation()
Definition: MoveNode.cc:771
MoveNode::destinationOperationCount
unsigned int destinationOperationCount() const
BoostGraph< MoveNode, DataDependenceEdge >::inDegree
virtual int inDegree(const Node &node) const
MoveNodeSet
Definition: MoveNodeSet.hh:41
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:113
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
BoostGraph< MoveNode, DataDependenceEdge >::hasNode
bool hasNode(const Node &) const
DataDependenceGraph::cycleGrouping_
bool cycleGrouping_
Dot printing related variables. Group the printed MoveNodes according to their cycles.
Definition: DataDependenceGraph.hh:442
DataDependenceEdge::data
const TCEString data() const
Definition: DataDependenceEdge.hh:142
DataDependenceEdge::DEP_WAW
@ DEP_WAW
Definition: DataDependenceEdge.hh:49
BoostGraph< MoveNode, DataDependenceEdge >::NodeDescriptor
GraphTraits::vertex_descriptor NodeDescriptor
Type with which nodes of the graph are seen internally.
Definition: BoostGraph.hh:264
DataDependenceGraph::hasEqualEdge
bool hasEqualEdge(const MoveNode &tailNode, const MoveNode &headNode, const DataDependenceEdge &edge) const
Definition: DataDependenceGraph.cc:3324
LiveRange::reads
DataDependenceGraph::NodeSet reads
Definition: LiveRange.hh:40
BoostGraph< MoveNode, DataDependenceEdge >::inEdges
virtual EdgeSet inEdges(const Node &node) const
BoostGraph< MoveNode, DataDependenceEdge >::connectingEdges
EdgeSet connectingEdges(const Node &nTail, const Node &nHead) const
GraphBase< MoveNode, DataDependenceEdge >::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
TTAProgram::CodeSnippet
Definition: CodeSnippet.hh:59
ProgramOperation::outputMoveCount
int outputMoveCount() const
Definition: ProgramOperation.cc:610
DataDependenceGraph::earliestCycle
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
Definition: DataDependenceGraph.cc:388
DataDependenceGraph::movesAtCycle
NodeSet movesAtCycle(int cycle) const
Definition: DataDependenceGraph.cc:699
BoostGraph< MoveNode, DataDependenceEdge >::constructSubGraph
void constructSubGraph(BoostGraph &subGraph, NodeSet &nodes)
LiveRange::guards
DataDependenceGraph::NodeSet guards
Definition: LiveRange.hh:41
TTAProgram::Terminal::functionUnit
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition: Terminal.cc:251
MoveNodeSet::count
int count() const
DataDependenceGraph::isRootGraphProcedureDDG
bool isRootGraphProcedureDDG()
Definition: DataDependenceGraph.cc:3669
MoveNode::isSourceVariable
bool isSourceVariable() const
Definition: MoveNode.cc:196
BoostGraph< MoveNode, DataDependenceEdge >::edge
virtual Edge & edge(const int index) const
BoostGraph< MoveNode, DataDependenceEdge >::outEdges
virtual EdgeSet outEdges(const Node &node) const
DataDependenceEdge::guardUse
bool guardUse() const
Definition: DataDependenceEdge.hh:100
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
DataDependenceGraph::addNode
void addNode(MoveNode &moveNode)
Definition: DataDependenceGraph.cc:144
TTAMachine::Guard::isOpposite
virtual bool isOpposite(const Guard &guard) const =0
TTAProgram::AnnotatedInstructionElement::annotation
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:100
MoveNode::destinationOperationPtr
ProgramOperationPtr destinationOperationPtr(unsigned int index=0) const
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
TTAProgram::AnnotatedInstructionElement::addAnnotation
void addAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:63
GraphEdge::setWeight
void setWeight(int w)
Definition: GraphEdge.hh:74
MoveNode::move
TTAProgram::Move & move()
TTAProgram::Instruction::isInProcedure
bool isInProcedure() const
Definition: Instruction.cc:135
BoostGraph< MoveNode, DataDependenceEdge >::isInCriticalPath
bool isInCriticalPath(const MoveNode &node) const
Definition: BoostGraph.hh:179
POMDisassembler::disassemble
static std::string disassemble(const TTAProgram::Move &move)
Definition: POMDisassembler.cc:629
TTAProgram::Move::hasSourceLineNumber
bool hasSourceLineNumber() const
Definition: Move.cc:445
TTAProgram::Move::parent
Instruction & parent() const
Definition: Move.cc:115
BoostGraph::dropEdge
virtual void dropEdge(Edge &edge)
DataDependenceGraph::DataDependenceGraph
DataDependenceGraph(std::set< TCEString > allParamRegs, const TCEString &name="", AntidependenceLevel antidependenceLevel=ALL_ANTIDEPS, BasicBlockNode *ownedBBN=NULL, bool containsProcedure=false, bool noLoopEdges=false)
Definition: DataDependenceGraph.cc:78
DataDependenceGraph::isNotAvoidable
bool isNotAvoidable(const DataDependenceEdge &edge) const
Definition: DataDependenceGraph.cc:5553
DataDependenceEdge::EDGE_MEMORY
@ EDGE_MEMORY
Definition: DataDependenceEdge.hh:54
DataDependenceGraph::exclusingGuards
bool exclusingGuards(const MoveNode &mn1, const MoveNode &mn2) const
Definition: DataDependenceGraph.cc:4480
TTAMachine::Component::machine
virtual Machine * machine() const
GraphEdge
Definition: GraphEdge.hh:52
MoveNode::inSameOperation
bool inSameOperation(const MoveNode &other) const
Definition: MoveNode.cc:306
TCEString
Definition: TCEString.hh:53
DataDependenceGraph::firstScheduledRegisterKill
MoveNode * firstScheduledRegisterKill(const TTAMachine::BaseRegisterFile &rf, int registerIndex) const
Definition: DataDependenceGraph.cc:1320
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
MoveNode::setGuardOperationPtr
void setGuardOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:550
TTAProgram::Terminal::copy
virtual Terminal * copy() const =0
ProgramOperation::inputNode
MoveNodeSet & inputNode(int in) const
Definition: ProgramOperation.cc:513
BoostGraph< MoveNode, DataDependenceEdge >::OutEdgeIter
GraphTraits::out_edge_iterator OutEdgeIter
Output edge iterator type.
Definition: BoostGraph.hh:253
MoveNode::sourceOperationPtr
ProgramOperationPtr sourceOperationPtr() const
Definition: MoveNode.cc:458
DataDependenceGraph::EWH_REAL
@ EWH_REAL
Height returns the minimum cycle count for the schedule given enough resources.
Definition: DataDependenceGraph.hh:92
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::Terminal::equals
virtual bool equals(const Terminal &other) const =0
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
BoostGraph< MoveNode, DataDependenceEdge >::graph_
Graph graph_
The internal graph structure.
Definition: BoostGraph.hh:331
BoostGraph< MoveNode, DataDependenceEdge >
ProgramOperation::poId
unsigned int poId() const
Definition: ProgramOperation.cc:765
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
DataDependenceGraph::operationLatencies_
std::map< TCEString, int > operationLatencies_
Definition: DataDependenceGraph.hh:450
DisassemblyRegister::registerName
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
Definition: DisassemblyRegister.cc:95
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine::HWOperation::latency
int latency() const
Definition: HWOperation.cc:216
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
TTAProgram::Move::isJump
bool isJump() const
Definition: Move.cc:164
TTAProgram::AnnotatedInstructionElement::removeAnnotations
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
Definition: AnnotatedInstructionElement.cc:146
DataDependenceGraph::allParamRegs_
std::set< TCEString > allParamRegs_
Definition: DataDependenceGraph.hh:430
DataDependenceEdge::headPseudo
bool headPseudo() const
Definition: DataDependenceEdge.hh:115
TTAProgram::Terminal::isImmediate
virtual bool isImmediate() const
Definition: Terminal.cc:63
DataDependenceEdge::DEP_WAR
@ DEP_WAR
Definition: DataDependenceEdge.hh:48
BoostGraph< MoveNode, DataDependenceEdge >::height_
int height_
Definition: BoostGraph.hh:328
BoostGraph< MoveNode, DataDependenceEdge >::name
virtual const TCEString & name() const
BoostGraph< MoveNode, DataDependenceEdge >::parentGraph_
BoostGraph< MoveNode, DataDependenceEdge > * parentGraph_
Definition: BoostGraph.hh:377
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
DataDependenceGraph::copyDepsOver
EdgeSet copyDepsOver(MoveNode &node, bool anti, bool raw)
Definition: DataDependenceGraph.cc:2422
BoostGraph< MoveNode, DataDependenceEdge >::nodeCount
int nodeCount() const
XMLSerializer
Definition: XMLSerializer.hh:62
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
BoostGraph< MoveNode, DataDependenceEdge >::descriptor
EdgeDescriptor descriptor(const Edge &e) const
ProgramOperation::outputMove
MoveNode & outputMove(int index) const
Definition: ProgramOperation.cc:632
DataDependenceEdge::EDGE_RA
@ EDGE_RA
Definition: DataDependenceEdge.hh:57
LiveRange
Definition: LiveRange.hh:38
BoostGraph< MoveNode, DataDependenceEdge >::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
BoostGraph< MoveNode, DataDependenceEdge >::rootGraphInEdges
virtual EdgeSet rootGraphInEdges(const Node &node) const
ObjectState::setValue
void setValue(const std::string &value)
DataDependenceGraph::moveNodeBlocks_
std::map< const MoveNode *, BasicBlockNode * > moveNodeBlocks_
Definition: DataDependenceGraph.hh:438
DataDependenceGraph::edgeWeightHeuristics_
EdgeWeightHeuristics edgeWeightHeuristics_
The heuristics to use to weight edges in the longest path computation.
Definition: DataDependenceGraph.hh:458
DataDependenceGraph::hasAllRegisterAntidependencies
bool hasAllRegisterAntidependencies()
Definition: DataDependenceGraph.hh:379
DataDependenceGraph::removeRAWEdges
TCEString removeRAWEdges(MoveNode &sourceNode, MoveNode &userNode)
Definition: DataDependenceGraph.cc:1937
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
DataDependenceGraph::getBasicBlockNode
const BasicBlockNode & getBasicBlockNode(const MoveNode &mn) const
Definition: DataDependenceGraph.cc:186
DataDependenceGraph::getOperationLatency
int getOperationLatency(const TCEString &name) const
Definition: DataDependenceGraph.cc:3304
BoostGraph< MoveNode, DataDependenceEdge >::InEdgeIter
GraphTraits::in_edge_iterator InEdgeIter
Input edge iterator type.
Definition: BoostGraph.hh:255
TTAProgram::ProgramAnnotation::payload
const std::vector< Byte > & payload() const
Definition: ProgramAnnotation.cc:121
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
BoostGraph< MoveNode, DataDependenceEdge >::EdgeIter
GraphTraits::edge_iterator EdgeIter
Iterator type for the list of all edges in the graph.
Definition: BoostGraph.hh:257
InstanceNotFound
Definition: Exception.hh:304
TTAProgram::Move::setSource
void setSource(Terminal *src)
Definition: Move.cc:312
DataDependenceGraph::NO_ANTIDEPS
@ NO_ANTIDEPS
Definition: DataDependenceGraph.hh:79
ProgramOperation::removeOutputNode
void removeOutputNode(MoveNode &node, int outputIndex)
Definition: ProgramOperation.cc:214
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
XMLSerializer::writeState
virtual void writeState(const ObjectState *rootState)
Definition: XMLSerializer.cc:219
DataDependenceGraph::mergeAndKeepAllowed
bool mergeAndKeepAllowed(MoveNode &sourceNode, MoveNode &userNode)
Definition: DataDependenceGraph.cc:1880