OpenASIP  2.0
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"
42 #include "DataDependenceGraph.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 
51 using namespace TTAProgram;
52 using 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  */
61 bool
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  */
89 bool
91  DataDependenceGraph& ddg, const ProgramOperation& pop,
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 =
104  findTwoPartAddressOperands(pop);
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 
237 }
SimValue::intValue
int intValue() const
Definition: SimValue.cc:895
TTAProgram
Definition: Estimator.hh:65
MoveNodeUse::BBRelation
BBRelation
Definition: MoveNodeUse.hh:23
StackAliasAnalyzer::~StackAliasAnalyzer
~StackAliasAnalyzer()
Definition: StackAliasAnalyzer.cc:234
StackAliasAnalyzer.hh
MoveNode::isSourceReg
bool isSourceReg(const std::string &reg) const
Definition: MoveNode.cc:798
DataDependenceGraph.hh
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
Terminal.hh
DataDependenceGraph::onlyRegisterRawSource
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
Definition: DataDependenceGraph.cc:4083
MemoryAliasAnalyzer::TwoPartAddressOperandDetection::offsetOperation
OffsetOperation offsetOperation
Definition: MemoryAliasAnalyzer.hh:86
MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand2
int operand2
Definition: MemoryAliasAnalyzer.hh:88
MemoryAliasAnalyzer::AliasingResult
AliasingResult
Definition: MemoryAliasAnalyzer.hh:50
MoveNode::isMove
bool isMove() const
MoveNodeSet::at
MoveNode & at(int index)
OperationDAG.hh
Operation.hh
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
TTAProgram::Terminal::value
virtual SimValue value() const
Definition: Terminal.cc:178
MoveNodeSet
Definition: MoveNodeSet.hh:41
MoveNodeUse::LOOP
@ LOOP
Definition: MoveNodeUse.hh:26
StackAliasAnalyzer::isAddressTraceable
virtual bool isAddressTraceable(DataDependenceGraph &ddg, const ProgramOperation &pop)
Definition: StackAliasAnalyzer.cc:62
ProgramOperation.hh
Operand.hh
MoveNodeSet::count
int count() const
MoveNode::isSourceVariable
bool isSourceVariable() const
Definition: MoveNode.cc:196
MoveNode::move
TTAProgram::Move & move()
StackAliasAnalyzer::StackAliasAnalyzer
StackAliasAnalyzer(const TCEString &sp)
Definition: StackAliasAnalyzer.cc:236
RegisterFile.hh
MoveNodeSet.hh
TCEString
Definition: TCEString.hh:53
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
StackAliasAnalyzer::getStackOffset
static bool getStackOffset(DataDependenceGraph &ddg, const ProgramOperation &pop, long &offset, long &loopIncrement, const TCEString &sp_)
Definition: StackAliasAnalyzer.cc:90
TerminalNode.hh
ProgramOperation::inputNode
MoveNodeSet & inputNode(int in) const
Definition: ProgramOperation.cc:513
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
ProgramOperation::poId
unsigned int poId() const
Definition: ProgramOperation.cc:765
OperationNode.hh
MemoryAliasAnalyzer::TwoPartAddressOperandDetection
Definition: MemoryAliasAnalyzer.hh:84
Move.hh
TTAMachine
Definition: Assembler.hh:48
MoveNode.hh
MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand1
int operand1
Definition: MemoryAliasAnalyzer.hh:87
StackAliasAnalyzer::analyze
virtual AliasingResult analyze(DataDependenceGraph &ddg, const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbInfo)
Definition: StackAliasAnalyzer.cc:182