OpenASIP 2.2
Loading...
Searching...
No Matches
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"
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 */
78bool
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 */
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 */
126std::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}
virtual Node & headNode(const Edge &edge) const
int nodeCount() const
Node & node(const int index) const
virtual EdgeSet outEdges(const Node &node) const
DependenceType dependenceType() const
EdgeReason edgeReason() const
const TCEString data() const
std::set< GraphEdge *, typename GraphEdge::Comparator > EdgeSet
Definition Graph.hh:54
bool loop() const
int cycle() const
Definition MoveNode.cc:421
bool isScheduled() const
Definition MoveNode.cc:409
static bool appendUseMapSets(const MoveNodeUseMapSet &srcMap, MoveNodeUseMapSet &dstMap, bool addLoopProperty)
void merge(LiveRangeData &succ)
MoveNodeUseMapSet regFirstUses_
MoveNodeUseMapSet regLastUses_
std::set< MoveNodeUse > MoveNodeUseSet
std::set< TCEString > registersUsedAfter_
MoveNodeUseMapSet regFirstDefines_
std::set< TCEString > registersAlive(int cycle, int delaySlots, class DataDependenceGraph &ddg)
std::map< TCEString, MoveNodeUseSet > MoveNodeUseMapSet
MoveNodeUseMapPair regKills_
static void appendMoveNodeUse(const MoveNodeUseSet &src, MoveNodeUseSet &dst, bool setLoopProperty)
MoveNodeUseMapSet regDefines_
MoveNodeUseMapSet regDefReaches_