OpenASIP 2.2
Loading...
Searching...
No Matches
StackAliasAnalyzer.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 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 * @file StackAliasAnalyzer.cc
26 *
27 * Implementation of StackAliasAnalyzer class.
28 *
29 * This class does simple alias analysis between memove addresses
30 * that point to the stack.
31 *
32 * @author Heikki Kultala 2009 (heikki.kultala-no.spam-tut.fi)
33 * @note rating: red
34 */
35
36#include "StackAliasAnalyzer.hh"
37
38#include "MoveNode.hh"
39#include "MoveNodeSet.hh"
40#include "Move.hh"
41#include "ProgramOperation.hh"
43#include "RegisterFile.hh"
44#include "OperationDAG.hh"
45#include "OperationNode.hh"
46#include "TerminalNode.hh"
47#include "Operand.hh"
48#include "Terminal.hh"
49#include "Operation.hh"
50
51using namespace TTAProgram;
52using namespace TTAMachine;
53
54/**
55 * Checks if the node contains an adress that is an stack offset.
56 *
57 * @param ddg DDG where to analyze from
58 * @param mn the node being checked
59 * @return true if is a traceable stack offset, false if not.
60 */
61bool
63 DataDependenceGraph& ddg, const ProgramOperation& pop) {
64 auto i = offsetData_.find(pop.poId());
65 if (i != offsetData_.end()) {
66 return i->second.first != INT_MAX;
67 } else {
68 long tmp, tmp2;
69 bool analyzable = getStackOffset(ddg, pop, tmp, tmp2, sp_);
70 if (analyzable) {
71 offsetData_[pop.poId()] = std::make_pair(tmp,tmp2);
72 return true;
73 } else {
74 offsetData_[pop.poId()] = std::make_pair(INT_MAX,tmp2);
75 return false;
76 }
77 }
78 return false;
79}
80
81/**
82 * Gets stack offset of a move which is transporting an address.
83 *
84 * @param ddg DDG where to track the address from.
85 * @param node Node which transfers the address.
86 * @param stackOffset place where to return the stack offset.
87 * @return true if can calculate stack offset, false if not stack offset.
88 */
89bool
92 long& stackOffset, long& loopIncrement, const TCEString& sp) {
93
94 stackOffset = 0;
95 loopIncrement = 0;
96
97 // TODO: support for base+offset ops here.
98
99 const MoveNode* mn = addressOperandMove(pop);
100 if (mn == NULL) {
101
102 int offsetMul = 0;
103 TwoPartAddressOperandDetection addressParts =
105 switch(addressParts.offsetOperation) {
106 case TwoPartAddressOperandDetection::ADD:
107 offsetMul = 1;
108 break;
109 case TwoPartAddressOperandDetection::SUB:
110 offsetMul = -1;
111 break;
112 case TwoPartAddressOperandDetection::NOT_FOUND:
113 return false;
114 }
115
116 MoveNodeSet& addr1Set = pop.inputNode(addressParts.operand1);
117 MoveNodeSet& addr2Set = pop.inputNode(addressParts.operand2);
118 if (addr1Set.count() != 1) {
119 return false;
120 }
121 if (addr2Set.count() != 1) {
122 return false;
123 }
124 MoveNode& addr1 = addr1Set.at(0);
125 MoveNode& addr2 = addr2Set.at(0);
126
127 if (addr1.isSourceConstant()) {
128 int offsetVal = addr1.move().source().value().intValue();
129 stackOffset += (offsetMul * offsetVal);
130 mn = &addr2;
131 }
132
133 if (addr2.isSourceConstant()) {
134 int offsetVal = addr2.move().source().value().intValue();
135 stackOffset += (offsetMul * offsetVal);
136 mn = &addr1;
137 }
138 }
139
140 while(mn != NULL && mn->isMove()) {
141 if (mn->isSourceVariable()) {
142 if (mn->isSourceReg(sp)) {
143 return true;
144 }
145
146 MoveNode* prevSrc = ddg.onlyRegisterRawSource(*mn,2,2);
147 MoveNode* loopSrc = ddg.onlyRegisterRawSource(*mn,2,1);
148 // borken ddg??
149 if (prevSrc == NULL) {
150 break;
151 }
152 if (loopSrc) {
153 if (!findIncrement(*loopSrc, loopIncrement)) {
154 return false;
155 }
156 }
157 mn = prevSrc;
158 } else {
159 if (mn->isSourceOperation()) {
160 const MoveNode* incrementInput = findIncrement(*mn, stackOffset);
161 mn = incrementInput;
162 } else {
163 return false;
164 }
165 }
166 }
167 return false;
168}
169
170/**
171 * Analyzes aliasing of two memory adderesses.
172 *
173 * Checks if they are stack offsets and compares the offsets.
174 *
175 * @param ddg ddg where they belong.
176 * @param node1 first node to compare
177 * @param another anpther node to compare
178 * @return ALIAS_TRUE if they alias, ALIAS_FALSE if they don't or
179 * ALIAS_UNKNOWN if cannot analyze.
180 */
183 DataDependenceGraph& ddg, const ProgramOperation& pop1,
184 const ProgramOperation& pop2, MoveNodeUse::BBRelation bbRel) {
185
186 long addr1, addr2;
187 long incr1, incr2;
188 auto i = offsetData_.find(pop1.poId());
189 if (i != offsetData_.end()) {
190 if (i->second.first != INT_MAX) {
191 addr1 = i->second.first;
192 incr1 = i->second.second;
193 } else {
194 return ALIAS_UNKNOWN;
195 }
196 } else {
197 if (!(getStackOffset(ddg, pop1, addr1, incr1, sp_))) {
198 offsetData_[pop1.poId()] = std::make_pair(INT_MAX, incr1);
199 return ALIAS_UNKNOWN;
200 } else {
201 offsetData_[pop1.poId()] = std::make_pair(addr1, incr1);
202 }
203 }
204
205 i = offsetData_.find(pop2.poId());
206 if (i != offsetData_.end()) {
207 if (i->second.first != INT_MAX) {
208 addr2 = i->second.first;
209 incr2 = i->second.second;
210 } else {
211 return ALIAS_UNKNOWN;
212 }
213 } else {
214 if (!(getStackOffset(ddg, pop2, addr2, incr2, sp_))) {
215 offsetData_[pop2.poId()] = std::make_pair(INT_MAX, incr2);
216 return ALIAS_UNKNOWN;
217 } else {
218 offsetData_[pop2.poId()] = std::make_pair(addr2, incr2);
219 }
220
221 }
222
223 if (incr1 != incr2) {
224 return ALIAS_UNKNOWN;
225 }
226
227 if (bbRel != MoveNodeUse::LOOP) {
228 return compareIndeces(addr1, addr2, pop1, pop2);
229 } else {
230 return compareIndeces(addr1 + incr1, addr2, pop1, pop2);
231 }
232}
233
235
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
static const MoveNode * findIncrement(const MoveNode &mn, long &increment)
AliasingResult compareIndeces(int index1, int index2, const ProgramOperation &pop1, const ProgramOperation &pop2)
static const MoveNode * addressOperandMove(const ProgramOperation &po)
static TwoPartAddressOperandDetection findTwoPartAddressOperands(const ProgramOperation &po)
int count() const
MoveNode & at(int index)
bool isSourceReg(const std::string &reg) const
Definition MoveNode.cc:798
bool isSourceVariable() const
Definition MoveNode.cc:196
bool isMove() const
TTAProgram::Move & move()
bool isSourceOperation() const
Definition MoveNode.cc:168
bool isSourceConstant() const
Definition MoveNode.cc:238
unsigned int poId() const
MoveNodeSet & inputNode(int in) const
int intValue() const
Definition SimValue.cc:895
static bool getStackOffset(DataDependenceGraph &ddg, const ProgramOperation &pop, long &offset, long &loopIncrement, const TCEString &sp_)
StackAliasAnalyzer(const TCEString &sp)
std::map< int, std::pair< long, long > > offsetData_
virtual AliasingResult analyze(DataDependenceGraph &ddg, const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbInfo)
virtual bool isAddressTraceable(DataDependenceGraph &ddg, const ProgramOperation &pop)
Terminal & source() const
Definition Move.cc:302
virtual SimValue value() const
Definition Terminal.cc:178