OpenASIP  2.0
LiveRangeData.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2011 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 LiveRangeData.cc
27  *
28  * Implementation of LiveRangeData class.
29  *
30  * Contains live range-related data for one basic block.
31  * This is geenrated and used by ddg builder.
32  * This may also be used by later parts of the scheduler.
33  *
34  * @author Heikki Kultala 2011 (hkultala@cs.tut.fi)
35  * @note rating: red
36  */
37 
38 #include "LiveRangeData.hh"
39 #include "DataDependenceGraph.hh"
40 #include "Move.hh"
41 
42 /**
43  * merges liverangedata of successor into this.
44  *
45  * @param succ later basic block which is merged into this one.
46  */
48 
49  // copy outgoing live information as it is from successor
52 
53  // after this BB alive regs are those that are alive after the latter bb.
55 
56  // then in incoming deps, merge from both.
57 
61 
62 }
63 
64 /**
65  * This appends the data from one MoveNodeUseMapSet to another.
66  *
67  * it traverses the map, and for every string, set pair it
68  * finds or creates the corresponging set in the destination and appends
69  * the set to that set.
70  * This is used for copying alive definitions.
71  *
72  * @param srcMap source where to copy from
73  * @param dstMap destination where to copy to.
74  * @param addLoopProperty whether to add loop property to the copied
75  * bookkeeping, ie create edges with loop property.
76  * @return true if destination changed (needs updating)
77  */
78 bool
80  const MoveNodeUseMapSet& srcMap, MoveNodeUseMapSet& dstMap,
81  bool addLoopProperty) {
82  bool changed = false;
83  for (MoveNodeUseMapSet::const_iterator srcIter = srcMap.begin();
84  srcIter != srcMap.end(); srcIter++) {
85  TCEString reg = srcIter->first;
86  const MoveNodeUseSet& srcSet = srcIter->second;
87  MoveNodeUseSet& dstSet = dstMap[reg];
88  // dest set size before appending.
89  size_t size = dstSet.size();
90  appendMoveNodeUse(srcSet, dstSet, addLoopProperty);
91  // if size has changed, dest is changed.
92  if (dstSet.size() > size) {
93  changed = true;
94  }
95  }
96  return changed;
97 }
98 
99 /**
100  * Appends a MoveNodeUseSet to another. May set loop property of copied
101  * moves to true.
102  *
103  * @param src source set
104  * @param dst destination set
105  * @param setLoopProperty whether to set loop property true in copied data
106  */
108  const LiveRangeData::MoveNodeUseSet& src,
110  bool setLoopProperty) {
111 
112  for (LiveRangeData::MoveNodeUseSet::const_iterator i =
113  src.begin(); i != src.end(); i++) {
114  const MoveNodeUse& mnu = *i;
115  if (setLoopProperty || mnu.loop()) {
116  dst.insert(MoveNodeUse(mnu, MoveNodeUse::LOOP));
117  } else {
118  dst.insert(MoveNodeUse(mnu, MoveNodeUse::INTRA_BB));
119  }
120  }
121 }
122 
123 /**
124  * Returns the set of registers that are alive at the given cycle.
125  */
126 std::set<TCEString>
128  int cycle, int delaySlots, DataDependenceGraph& ddg) {
129 
130  std::set<TCEString> aliveRegs;
131 
132  // Part 1: Live ranges incoming to this BB.
133  // handles both incoming and overgoing live ranges
134  for (MoveNodeUseMapSet::iterator rdrIter = regDefReaches_.begin();
135  rdrIter != regDefReaches_.end(); rdrIter++) {
136  const TCEString& reg = rdrIter->first;
137 
138  // if use after and not killed here, alive for the whole BB.
139  if (registersUsedAfter_.find(reg) != registersUsedAfter_.end()) {
140  // nothing in this BB overwrites this.
141  if (regKills_.find(reg) == regKills_.end()) {
142  aliveRegs.insert(reg);
143  }
144  }
145 
146  // check for first uses in this BB. If before a read, is used.
147  MoveNodeUseSet& firstUses = regFirstUses_[reg];
148  for (MoveNodeUseSet::iterator iter = firstUses.begin();
149  iter != firstUses.end(); iter++) {
150  const MoveNode& mn = *(iter->mn());
151  if (mn.isScheduled()) {
152  int mnCycle = mn.cycle();
153  if (iter->pseudo()) {
154  mnCycle += delaySlots;
155  }
156  if (cycle <= mnCycle) {
157  aliveRegs.insert(reg);
158  }
159  } else { // unscheduled.. later?
160  aliveRegs.insert(reg);
161  }
162  }
163  }
164 
165  // Part 2: check deps going out from this.
166  for (std::set<TCEString>::iterator ruaIter = registersUsedAfter_.begin();
167  ruaIter != registersUsedAfter_.end(); ruaIter++) {
168  const TCEString& reg = *ruaIter;
169 
170  // check against last defines.
171  MoveNodeUseSet& lastDefs = regDefines_[reg];
172  for (MoveNodeUseSet::iterator iter = lastDefs.begin();
173  iter != lastDefs.end(); iter++) {
174  const MoveNode& mn = *iter->mn();
175  if (mn.isScheduled()) {
176  int mnCycle = mn.cycle();
177  if (iter->pseudo()) {
178  mnCycle += delaySlots;
179  }
180  if (cycle >= mnCycle) {
181  aliveRegs.insert(reg);
182  }
183  }
184  // if not scheduld, is at end?
185  }
186  }
187 
188  // part 3: Check edges inside this BB. done from DDG.
189 
190  // TODO: psedo-dep delay slots.
191  for (int i = 0; i < ddg.nodeCount(); i++) {
192  MoveNode& node = ddg.node(i);
193  // only check writes that are scheduled.
194  if (!node.isScheduled() || node.cycle() > cycle) {
195  continue; // write after the given cycle
196  }
197 
198  // Find all edges out from this
199  DataDependenceGraph::EdgeSet edges = ddg.outEdges(node);
200  for (DataDependenceGraph::EdgeSet::iterator eIter =
201  edges.begin(); eIter != edges.end(); eIter++) {
202  DataDependenceEdge& edge = **eIter;
203 
204  // we are only interested in register RAWs.
208  const TCEString& reg = edge.data();
209  MoveNode &headNode = ddg.headNode(edge);
210  // if tail pseudo, delay by delaySlots amount
211  if (edge.tailPseudo()) {
212  if (node.cycle() + delaySlots > cycle) {
213  continue;
214  }
215  }
216  // if pseudo, delay mncycle by delayslot amount
217  int delay = edge.headPseudo() ? delaySlots : 0;
218  // is the read after this
219  if (headNode.isScheduled() &&
220  headNode.cycle()+delay >= cycle) {
221  aliveRegs.insert(reg);
222  }
223  }
224  }
225  }
226  return aliveRegs;
227 }
BoostGraph::headNode
virtual Node & headNode(const Edge &edge) const
BoostGraph::node
Node & node(const int index) const
LiveRangeData::appendMoveNodeUse
static void appendMoveNodeUse(const MoveNodeUseSet &src, MoveNodeUseSet &dst, bool setLoopProperty)
Definition: LiveRangeData.cc:107
LiveRangeData::MoveNodeUseSet
std::set< MoveNodeUse > MoveNodeUseSet
Definition: LiveRangeData.hh:51
MoveNodeUse
Definition: MoveNodeUse.hh:20
LiveRangeData::merge
void merge(LiveRangeData &succ)
Definition: LiveRangeData.cc:47
LiveRangeData::regDefines_
MoveNodeUseMapSet regDefines_
Definition: LiveRangeData.hh:78
DataDependenceGraph.hh
MoveNode
Definition: MoveNode.hh:65
LiveRangeData::regKills_
MoveNodeUseMapPair regKills_
Definition: LiveRangeData.hh:85
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
LiveRangeData::MoveNodeUseMapSet
std::map< TCEString, MoveNodeUseSet > MoveNodeUseMapSet
Definition: LiveRangeData.hh:52
DataDependenceEdge::dependenceType
DependenceType dependenceType() const
Definition: DataDependenceEdge.hh:88
LiveRangeData::regDefReaches_
MoveNodeUseMapSet regDefReaches_
Definition: LiveRangeData.hh:90
DataDependenceEdge::tailPseudo
bool tailPseudo() const
Definition: DataDependenceEdge.hh:109
MoveNodeUse::loop
bool loop() const
Definition: MoveNodeUse.hh:43
LiveRangeData::registersAlive
std::set< TCEString > registersAlive(int cycle, int delaySlots, class DataDependenceGraph &ddg)
Definition: LiveRangeData.cc:127
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
BoostGraph< MoveNode, DataDependenceEdge >::EdgeSet
std::set< DataDependenceEdge *, typename DataDependenceEdge ::Comparator > EdgeSet
Definition: BoostGraph.hh:87
DataDependenceEdge::DEP_RAW
@ DEP_RAW
Definition: DataDependenceEdge.hh:47
LiveRangeData
Definition: LiveRangeData.hh:47
LiveRangeData::regFirstDefines_
MoveNodeUseMapSet regFirstDefines_
Definition: LiveRangeData.hh:87
LiveRangeData::regLastUses_
MoveNodeUseMapSet regLastUses_
Definition: LiveRangeData.hh:79
MoveNodeUse::INTRA_BB
@ INTRA_BB
Definition: MoveNodeUse.hh:24
MoveNodeUse::LOOP
@ LOOP
Definition: MoveNodeUse.hh:26
DataDependenceEdge::data
const TCEString data() const
Definition: DataDependenceEdge.hh:142
BoostGraph::outEdges
virtual EdgeSet outEdges(const Node &node) const
LiveRangeData::registersUsedAfter_
std::set< TCEString > registersUsedAfter_
Definition: LiveRangeData.hh:121
LiveRangeData.hh
TCEString
Definition: TCEString.hh:53
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
Move.hh
DataDependenceEdge::headPseudo
bool headPseudo() const
Definition: DataDependenceEdge.hh:115
LiveRangeData::appendUseMapSets
static bool appendUseMapSets(const MoveNodeUseMapSet &srcMap, MoveNodeUseMapSet &dstMap, bool addLoopProperty)
Definition: LiveRangeData.cc:79
BoostGraph::nodeCount
int nodeCount() const
DataDependenceEdge::EDGE_RA
@ EDGE_RA
Definition: DataDependenceEdge.hh:57
DataDependenceEdge::edgeReason
EdgeReason edgeReason() const
Definition: DataDependenceEdge.hh:91
LiveRangeData::regFirstUses_
MoveNodeUseMapSet regFirstUses_
Definition: LiveRangeData.hh:86