OpenASIP  2.0
BFSwapOperands.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2014 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * @file BFSwapOperands.cc
27  *
28  * Definition of BFSwapOperands class
29  *
30  * Swaps the operands of a commutative operation.
31  *
32  * @author Heikki Kultala 2014-2020(heikki.kultala-no.spam-tuni.fi)
33  * @note rating: red
34  */
35 
36 #include "BFSwapOperands.hh"
37 #include "ProgramOperation.hh"
38 #include "BasicBlockScheduler.hh"
39 #include "Operation.hh"
40 #include "MoveNodeSet.hh"
41 #include "Move.hh"
42 #include "BF2Scheduler.hh"
43 #include "Terminal.hh"
44 
46  MoveNode& mn1, MoveNode& mn2):
47  BFOptimization(sched), switched_(&mn1, &mn2), poPtr_(po),
48  idx1_(mn1.move().destination().operationIndex()),
49  idx2_(mn2.move().destination().operationIndex()) {}
50 
51 
52 /**
53  * Tries to switch operand and trigger so that it makees immediates triggers,
54  * but minimizes the critical path if both operands come from variables.
55  */
57  BFOptimization(sched), switched_(NULL,NULL), poPtr_(),
58  idx1_(0), idx2_(0) {
59 
60  if (trigger.destinationOperationCount() != 1) {
61 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
62  std::cerr << "not exactly one destop:" << trigger.toString()
63  << std::endl;
64 #endif
65  return;
66  }
67 
68  // keep immediates as triggers
69  if (trigger.move().source().isImmediate()) {
70  return;
71  }
72 
73  int index = trigger.move().destination().operationIndex();
75  const Operation &op = poPtr->operation();
76 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
77  std::cerr << "trying to swap operand of po: "
78  << poPtr->toString() << std::endl;
79 #endif
80 
81  for (int i = 1; i <= op.numberOfInputs(); i++) {
82  if (i == index) {
83 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
84  std::cerr << "\tNot swapping with itself" << std::endl;
85 #endif
86  continue;
87  }
88  if (!op.canSwap(i, index)) {
89 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
90  std::cerr << "\tnot commutative" << std::endl;
91 #endif
92  continue;
93  }
94 
95  MoveNodeSet& otherInputs = poPtr->inputNode(i);
96  if (otherInputs.count() != 1) {
97 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
98  std::cerr << "\tother input count not 1" << std::endl;
99 #endif
100  continue;
101  }
102 
103  MoveNode& other = otherInputs.at(0);
104  if (other.isScheduled()) {
105  continue;
106  }
107 
108  if (sched_.isPreLoopSharedOperand(other)) {
109 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
110  std::cerr << "\tCannot swap operand with pre-loop-shared" << std::endl;
111 #endif
112  continue;
113  }
114 
115 
116  // make longer path OR immediate into trigger
117  // currently only immediate.
118  if (other.move().source().isImmediate()) {
119 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
120  std::cerr << "\tshould swap indeces: " << i << " and " << index
121  << std::endl;
122 #endif
123  idx1_ = index;
124  idx2_ = i;
125  poPtr_ = poPtr;
126  switched_.first = &trigger;
127  switched_.second = &other;
128  return;
129  }
130 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
131  std::cerr << "\tother input is: " << other.toString() << std::endl;
132 #endif
133  }
134  return;
135 }
136 
138  if (poPtr_ == NULL) {
139  return false;
140  }
141  const Operation &op = poPtr_->operation();
142  if (!op.canSwap(idx1_, idx2_)) {
143 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
144  std::cerr << "Cannot swap: " << idx1_ << " and " << idx2_ << std::endl;
145 #endif
146  return false;
147  }
148 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
149  std::cerr << "Swapping inputs: " << poPtr_->toString() << std::endl;
150 #endif
151  poPtr_->switchInputs(idx1_, idx2_);
152 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
153  std::cerr << "Swapped inputs: " << poPtr_->toString() << std::endl;
154 #endif
155  return true;
156 }
157 
159 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
160  std::cerr << "undoing swap: " << poPtr_->toString() << std::endl;
161 #endif
162  poPtr_->switchInputs(idx1_, idx2_);
163 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
164  std::cerr << "undid swap: " << poPtr_->toString() << std::endl;
165 #endif
166 }
BFSwapOperands::BFSwapOperands
BFSwapOperands(BF2Scheduler &sched, MoveNode &mn)
Definition: BFSwapOperands.cc:56
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
BFSwapOperands::poPtr_
ProgramOperationPtr poPtr_
Definition: BFSwapOperands.hh:53
BFSwapOperands::idx1_
int idx1_
Definition: BFSwapOperands.hh:54
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
MoveNode
Definition: MoveNode.hh:65
BFOptimization
Definition: BFOptimization.hh:73
Terminal.hh
BasicBlockScheduler.hh
BFOptimization::sched_
BF2Scheduler & sched_
Definition: BFOptimization.hh:103
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
Operation::canSwap
virtual bool canSwap(int id1, int id2) const
Definition: Operation.cc:470
BFSwapOperands.hh
BF2Scheduler::isPreLoopSharedOperand
TTAMachine::FUPort * isPreLoopSharedOperand(MoveNode &mn) const
Definition: BF2Scheduler.cc:1625
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
BF2Scheduler.hh
MoveNodeSet::at
MoveNode & at(int index)
BFSwapOperands::idx2_
int idx2_
Definition: BFSwapOperands.hh:55
BFSwapOperands::switched_
std::pair< MoveNode *, MoveNode * > switched_
Definition: BFSwapOperands.hh:52
BFSwapOperands::operator()
virtual bool operator()()
Definition: BFSwapOperands.cc:137
BF2Scheduler
Definition: BF2Scheduler.hh:74
Operation.hh
MoveNode::destinationOperationCount
unsigned int destinationOperationCount() const
MoveNodeSet
Definition: MoveNodeSet.hh:41
Operation
Definition: Operation.hh:59
ProgramOperation.hh
MoveNodeSet::count
int count() const
MoveNode::destinationOperationPtr
ProgramOperationPtr destinationOperationPtr(unsigned int index=0) const
MoveNode::move
TTAProgram::Move & move()
BFSwapOperands::undoOnlyMe
virtual void undoOnlyMe()
Definition: BFSwapOperands.cc:158
MoveNodeSet.hh
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
Move.hh
TTAProgram::Terminal::isImmediate
virtual bool isImmediate() const
Definition: Terminal.cc:63