Go to the documentation of this file.
63 cyclesToLookBack_(5), cyclesToLookBackNoDRE_(1),
64 killDeadResults_(true), bypassFromRegs_(true), bypassToRegs_(true),
100 int& lastOperandCycle,
109 int originalCycle = moveNode.
cycle();
110 int latestCycle = originalCycle;
113 DataDependenceGraph::EdgeSet::iterator edgeIter = edges.begin();
117 while (edgeIter != edges.end()) {
128 if (bypassEdge == NULL) {
138 if (bypassEdge == NULL || bypassEdge->
isBackEdge()) {
158 cyclesToLookBack != INT_MAX &&
163 regRawSuccessorCount(source,
false))) {
169 if (cyclesToLookBack != INT_MAX &&
170 source.
cycle() + cyclesToLookBack < moveNode.
cycle()) {
182 latestCycle = source.
cycle();
191 for (DataDependenceGraph::NodeSet::iterator i = warSuccs.begin();
192 i != warSuccs.end();i++) {
195 if (mn.
cycle() < latestCycle) {
196 latestCycle = std::min(latestCycle, mn.
cycle());
202 for (edgeIter = edges.begin(); edgeIter != edges.end(); edgeIter++) {
204 if (&edge != bypassEdge) {
210 if (tail.
cycle() > latestCycle) {
214 if (tail.
cycle() > latestCycle-1) {
223 std::pair<MoveNode*, MoveNode*>(&moveNode, &source));
227 rm.
assign(originalCycle, moveNode);
241 ddgCycle = std::max(ddgCycle, moveNode.
guardLatency() - 1);
243 if (ddgCycle != INT_MAX) {
245 ddgCycle = originalCycle;
248 int sourceCycle = source.
cycle();
249 bool sourceRemoved =
false;
264 sourceRemoved =
true;
274 if (cycle != -1 && cycle <= latestCycle) {
275 rm.
assign(cycle, moveNode);
279 "Move assignment failed");
281 lastOperandCycle = std::max(lastOperandCycle, cycle);
293 if (!rm.
canAssign(originalCycle, moveNode)) {
300 rm.
assign(sourceCycle, source);
307 ddgCycle = std::max(ddgCycle, moveNode.
guardLatency()-1);
310 if (ec != -1 && ec < originalCycle) {
318 rm.
assign(originalCycle, moveNode);
327 rm.
assign(sourceCycle, source);
357 bool bypassTrigger) {
366 int bypassCounter = 0;
369 int lastOperandCycle = 0;
371 for (
int i = 0; i < candidates.
nodeCount(); i++) {
386 int rv =
bypassNode(moveNode, lastOperandCycle, ddg, rm);
396 bool triggerWasBypassed =
false;
399 int rv =
bypassNode(*trigger, lastOperandCycle, ddg, rm);
405 triggerWasBypassed =
true;
421 for (
int i = 0; i < candidates.
nodeCount(); i++) {
429 (trigger == &moveNode && triggerWasBypassed)) {
431 std::max(lastOperandCycle, moveNode.
cycle());
434 int oldCycle = moveNode.
cycle();
437 if (earliestCycleDDG >= oldCycle) {
441 int earliestCycle = earliestCycleDDG;
445 std::max(earliestCycleDDG, moveNode.
guardLatency() - 1);
448 if ((oldCycle > earliestCycle && earliestCycle != -1) ||
449 (trigger == &moveNode && earliestCycle != -1)){
451 rm.
assign(earliestCycle, moveNode);
461 rm.
assign(oldCycle, moveNode);
468 std::max(lastOperandCycle, moveNode.
cycle());
471 __FILE__, __LINE__,
__func__,
"Move assignment failed");
479 if (trigger != NULL) {
481 if (trigger->
cycle() < lastOperandCycle) {
485 if (newCycle == -1 || newCycle > latestDDG) {
490 rm.
assign(newCycle, *trigger);
493 __FILE__, __LINE__,
__func__,
"Trigger assignment failed");
501 return bypassCounter;
529 for (
int i = 0; i < candidates.
nodeCount(); i++) {
536 for (
int k = 0; k < candidates.
nodeCount(); k++) {
559 assert(tempSource != NULL);
569 std::map<MoveNode*, int>::iterator cycleIter =
576 rm.
assign(cycleIter->second, *tempSource);
589 assert(tempSource != NULL);
604 std::set<std::pair<TTAProgram::Move*, int> >& removedMoves) {
606 for (
int i = 0; i < candidates.
nodeCount(); i++) {
618 int resultsRemoved = 0;
619 for (
int i = 0; i < candidates.
nodeCount(); i++) {
637 std::map<MoveNode*, int>::iterator srcIter =
646 successors.erase(&resultMove);
654 for (std::map<MoveNode*, MoveNode*, MoveNode::Comparator>::
657 if (j->second == &resultMove) {
666 std::make_pair(&resultMove.
move(), (*srcIter).second));
675 for (DataDependenceGraph::NodeSet::iterator iter =
677 iter != successors.end(); iter++) {
692 for (DataDependenceGraph::NodeSet::iterator iter =
694 iter != successors.end(); iter++) {
713 successors.erase(&moveNode);
719 copyDepsOver(moveNode,
true,
true);
727 for (DataDependenceGraph::NodeSet::iterator iter =
729 iter != successors.end(); iter++) {
742 return resultsRemoved;
770 bool removeDeletedResults) {
773 if (removeDeletedResults) {
775 for (DataDependenceGraph::NodeSet::iterator i =
removedNodes_.begin();
789 std::cerr <<
"Bypasser statistics: " << std::endl
static int deadResultCount_
bool isTriggering() const
virtual void clearCaches(DataDependenceGraph &ddg, bool removeDeadResults)
bool isDestinationVariable() const
virtual Node & tailNode(const Edge &edge) const
MoveNode & node(int index) const
static int triggerAbortCount_
bool resultUsed(MoveNode &resultNode)
bool isDestinationOperation() const
virtual void unassign(MoveNode &node)=0
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
bool isUnconditional() const
std::map< MoveNode *, const TTAMachine::Bus * > sourceBuses_
virtual bool killDeadResults() const
Terminal & destination() const
std::map< MoveNode *, int > sourceCycles_
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > storedSources_
Stores sources and bypassed moves in case they have to be unassigned (case when operands are schedule...
const TTAMachine::Bus & bus() const
bool isSourceConstant() const
int bypassNode(MoveNode &nodeToBypass, int &lastOperandCycle, DataDependenceGraph &ddg, ResourceManager &rm)
virtual void removeBypass(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm)
DependenceType dependenceType() const
virtual void dropNode(Node &node)
bool mergeAndKeepUser(MoveNode &resultNode, MoveNode &userNode, bool force=false)
int cyclesToLookBackNoDRE_
count of cycles before the operand write to look for the producer of the read value when cannot kill ...
bool alwaysWriteResults() const
#define assert(condition)
NodeSet regWarSuccessors(const MoveNode &node) const
virtual bool isImmediateRegister() const
NodeSet regWawSuccessors(const MoveNode &node) const
bool isControlFlowMove() const
std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
virtual void removeNode(Node &node)
MoveNodeSelector * selector_
DataDependenceGraph::NodeSet removedNodes_
static CmdLineOptions * cmdLineOptions()
void setSelector(MoveNodeSelector *selector)
virtual ~CycleLookBackSoftwareBypasser()
std::string errorMessageStack(bool messagesOnly=false) const
bool isSourceOperation() const
virtual bool canAssign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const =0
void unMergeUser(MoveNode &resultNode, MoveNode &mergedNode, bool loopBypass=false)
virtual void mightBeReady(MoveNode &node)=0
bool hasNode(const Node &) const
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual EdgeSet inEdges(const Node &node) 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
TTAProgram::Move & move()
CycleLookBackSoftwareBypasser()
virtual Machine * machine() const
virtual void assign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)=0
bool guardsAllowBypass(const MoveNode &defNode, const MoveNode &useNode, bool loopBypass=false)
virtual int removeDeadResults(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, std::set< std::pair< TTAProgram::Move *, int > > &removedMoves)
virtual bool equals(const Terminal &other) const =0
Terminal & source() const
@ ANN_CONNECTIVITY_MOVE
A reg to reg move that was added because of missing connectivity between the original target and dest...
std::map< MoveNode *, MoveNode *, MoveNode::Comparator > removedStoredSources_
virtual int noDreBypassDistance() const
virtual int bypassDistance() const
EdgeSet copyDepsOver(MoveNode &node, bool anti, bool raw)
virtual int earliestCycle(MoveNode &node, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const =0
int regRawSuccessorCount(const MoveNode &mn, bool onlyScheduled)
void setBus(const TTAMachine::Bus &bus)
int cyclesToLookBack_
count of cycles before the operand write to look for the producer of the read value
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
EdgeReason edgeReason() const
void setSource(Terminal *src)
virtual int bypass(MoveNodeGroup &candidates, DataDependenceGraph &ddg, ResourceManager &rm, bool bypassTrigger)
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