OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
OffsetAliasAnalyzer Class Reference

#include <OffsetAliasAnalyzer.hh>

Inheritance diagram for OffsetAliasAnalyzer:
Inheritance graph
Collaboration diagram for OffsetAliasAnalyzer:
Collaboration graph

Classes

struct  OffsetData
 

Public Member Functions

virtual bool isAddressTraceable (DataDependenceGraph &ddg, const ProgramOperation &pop)
 
virtual AliasingResult analyze (DataDependenceGraph &ddg, const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbRelation)
 
 OffsetAliasAnalyzer (const TCEString &sp)
 
 ~OffsetAliasAnalyzer ()
 
- Public Member Functions inherited from MemoryAliasAnalyzer
virtual void initProcedure (TTAProgram::Procedure &)
 
virtual ~MemoryAliasAnalyzer ()
 

Private Member Functions

bool analyzeLoopPtrIncrease (const DataDependenceGraph &ddg, const MoveNode &mn, long &offset)
 
bool sameLoopAndPrevSources (const DataDependenceGraph &ddg, const MoveNode &anc1, const MoveNode &anc2)
 

Private Attributes

std::map< int, OffsetDataoffsetData_
 
TCEString sp_
 

Additional Inherited Members

- Public Types inherited from MemoryAliasAnalyzer
enum  AliasingResult { ALIAS_FALSE = 0 , ALIAS_TRUE = 1 , ALIAS_UNKNOWN = 2 , ALIAS_PARTIAL = 3 }
 
- Protected Member Functions inherited from MemoryAliasAnalyzer
AliasingResult compareIndeces (int index1, int index2, const ProgramOperation &pop1, const ProgramOperation &pop2)
 
- Static Protected Member Functions inherited from MemoryAliasAnalyzer
static const MoveNodeaddressOperandMove (const ProgramOperation &po)
 
static TwoPartAddressOperandDetection findTwoPartAddressOperands (const ProgramOperation &po)
 
static const MoveNodesearchLoopIndexBasedIncrement (DataDependenceGraph &ddg, const MoveNode &mn, long &loopIncrement)
 
static const MoveNodefindIncrement (const MoveNode &mn, long &increment)
 
static const MoveNodedetectConstantScale (const MoveNode &mn, int &shiftAmount)
 

Detailed Description

Definition at line 46 of file OffsetAliasAnalyzer.hh.

Constructor & Destructor Documentation

◆ OffsetAliasAnalyzer()

OffsetAliasAnalyzer::OffsetAliasAnalyzer ( const TCEString sp)

Definition at line 492 of file OffsetAliasAnalyzer.cc.

492 : sp_(sp) {
493}

◆ ~OffsetAliasAnalyzer()

OffsetAliasAnalyzer::~OffsetAliasAnalyzer ( )

Definition at line 490 of file OffsetAliasAnalyzer.cc.

490{}

Member Function Documentation

◆ analyze()

MemoryAliasAnalyzer::AliasingResult OffsetAliasAnalyzer::analyze ( DataDependenceGraph ddg,
const ProgramOperation pop1,
const ProgramOperation pop2,
MoveNodeUse::BBRelation  bbRel 
)
virtual

Analyzes aliasing of two memory adderesses.

Checks if they are stack offsets and compares the offsets.

Parameters
ddgddg where they belong.
node1first node to compare
anotheranpther node to compare
Returns
ALIAS_TRUE if they alias, ALIAS_FALSE if they don't or ALIAS_UNKNOWN if cannot analyze.

Implements MemoryAliasAnalyzer.

Definition at line 166 of file OffsetAliasAnalyzer.cc.

168 {
169 const MoveNode* anc1 = NULL;
170 const MoveNode* anc2 = NULL;
171 long offsetVal1 = 0;
172 long offsetVal2 = 0;
173
174 std::map<int,OffsetData>::const_iterator i =
175 offsetData_.find(pop1.poId());
176 if (i != offsetData_.end()) {
177 if (i->second.baseNode == NULL) {
178 return ALIAS_UNKNOWN;
179 } else {
180 anc1 = i->second.baseNode;
181 offsetVal1 = i->second.offset;
182 }
183 } else {
184
185 const MoveNode* addrMove1 = addressOperandMove(pop1);
186 if (addrMove1 == NULL) {
187
188 int offsetMul = 0;
189 TwoPartAddressOperandDetection addressParts =
191 switch(addressParts.offsetOperation) {
192 case TwoPartAddressOperandDetection::ADD:
193 offsetMul = 1;
194 break;
195 case TwoPartAddressOperandDetection::SUB:
196 offsetMul = -1;
197 break;
198 case TwoPartAddressOperandDetection::NOT_FOUND:
199 offsetData_.insert(
200 std::pair<int,OffsetData>(
201 pop1.poId(),OffsetData(NULL, INT_MAX)));
202 return ALIAS_UNKNOWN;
203 }
204
205 MoveNodeSet& addr1Set = pop1.inputNode(addressParts.operand1);
206 MoveNodeSet& addr2Set = pop1.inputNode(addressParts.operand2);
207 if (addr1Set.count() != 1) {
208 offsetData_.insert(
209 std::pair<int,OffsetData>(
210 pop1.poId(),OffsetData(NULL, INT_MAX)));
211 return ALIAS_UNKNOWN;
212 }
213 if (addr2Set.count() != 1) {
214 offsetData_.insert(
215 std::pair<int,OffsetData>(
216 pop1.poId(),OffsetData(NULL, INT_MAX)));
217 return ALIAS_UNKNOWN;
218 }
219 MoveNode& addr1 = addr1Set.at(0);
220 MoveNode& addr2 = addr2Set.at(0);
221
222 if (addr1.isSourceConstant() &&
223 addr2.move().source().isGPR()) {
224 anc1 = ddg.onlyRegisterRawAncestor(addr2, sp_);
225 offsetVal1 = addr1.move().source().value().intValue() *
226 offsetMul;
227 } else {
228 if (addr2.isSourceConstant() &&
229 addr1.move().source().isGPR()) {
230 anc1 = ddg.onlyRegisterRawAncestor(addr1, sp_);
231 offsetVal1 = addr2.move().source().value().intValue() *
232 offsetMul;
233 } else {
234 offsetData_.insert(
235 std::pair<int,OffsetData>(
236 pop1.poId(),OffsetData(NULL, INT_MAX)));
237 return ALIAS_UNKNOWN;
238 }
239 }
240
241 offsetData_.insert(
242 std::pair<int,OffsetData>(
243 pop1.poId(),OffsetData(anc1, offsetVal1)));
244
245 } else {
246 // direct memory op. have to search for the add.
247
248 // first find base and index of the first node.
249 const MoveNode* rawSrc1 =
250 ddg.onlyRegisterRawAncestor(*addrMove1, sp_);
251
252 if (!rawSrc1->isSourceOperation()) {
253 offsetData_.insert(
254 std::pair<int,OffsetData>(
255 pop1.poId(),OffsetData(rawSrc1, 0)));
256 } else {
257
258 ProgramOperation& po1 = rawSrc1->sourceOperation();
259
260 if (po1.operation().name() == "ADD" ||
261 po1.operation().name() == "SUB") {
262
263
264 // offset calc, add or sub. check for node2
265 MoveNodeSet& baseSet1 = po1.inputNode(1);
266 MoveNodeSet& offsetSet1 = po1.inputNode(2);
267
268 if (baseSet1.count() != 1 || offsetSet1.count() != 1) {
269 offsetData_.insert(
270 std::pair<int,OffsetData>(
271 pop1.poId(),OffsetData(NULL, INT_MAX)));
272 return ALIAS_UNKNOWN;
273 }
274
275 MoveNode& offsetNode1 = offsetSet1.at(0);
276 MoveNode& base1 = baseSet1.at(0);
277
278 if (!base1.move().source().isGPR() ||
279 !offsetNode1.move().source().isImmediate()) {
280 offsetData_.insert(
281 std::pair<int,OffsetData>(
282 pop1.poId(),OffsetData(NULL, INT_MAX)));
283 return ALIAS_UNKNOWN;
284 }
285
286 offsetVal1 = offsetNode1.move().source().value().intValue();
287 if (po1.operation().name() == "SUB") {
288 offsetVal1 = -offsetVal1;
289 }
290
291 anc1 = ddg.onlyRegisterRawAncestor(base1, sp_);
292 // update cache.
293 offsetData_.insert(
294 std::pair<int,OffsetData>(
295 pop1.poId(),OffsetData(anc1, offsetVal1)));
296 } else {
297 // comes directly from some untraceable op.
298 if (ddg.regRawSuccessorCount(*rawSrc1, false) > 1) {
299 offsetData_.insert(
300 std::pair<int,OffsetData>(
301 pop1.poId(),OffsetData(rawSrc1, 0)));
302 anc1 = rawSrc1;
303 offsetVal1 = 0;
304 } else {
305 offsetData_.insert(
306 std::pair<int,OffsetData>(
307 pop1.poId(),OffsetData(NULL, INT_MAX)));
308 return ALIAS_UNKNOWN;
309 }
310 }
311 }
312 }
313 }
314 // then find base and index for second node.
315
316 //first search cache.
317 i = offsetData_.find(pop2.poId());
318 if (i != offsetData_.end()) {
319 if (i->second.baseNode == NULL) {
320 return ALIAS_UNKNOWN;
321 } else {
322 anc2 = i->second.baseNode;
323 offsetVal2 = i->second.offset;
324 }
325 } else {
326 const MoveNode* addrMove2 = addressOperandMove(pop2);
327 if (addrMove2 == NULL) {
328
329 int offsetMul = 0;
330 TwoPartAddressOperandDetection addressParts =
332 switch(addressParts.offsetOperation) {
333 case TwoPartAddressOperandDetection::ADD:
334 offsetMul = 1;
335 break;
336 case TwoPartAddressOperandDetection::SUB:
337 offsetMul = -1;
338 break;
339 case TwoPartAddressOperandDetection::NOT_FOUND:
340 offsetData_.insert(
341 std::pair<int,OffsetData>(
342 pop2.poId(),OffsetData(NULL, INT_MAX)));
343 return ALIAS_UNKNOWN;
344 }
345
346 MoveNodeSet& addr1Set = pop2.inputNode(addressParts.operand1);
347 MoveNodeSet& addr2Set = pop2.inputNode(addressParts.operand2);
348 if (addr1Set.count() != 1) {
349 offsetData_.insert(
350 std::pair<int,OffsetData>(
351 pop2.poId(),OffsetData(NULL, INT_MAX)));
352 return ALIAS_UNKNOWN;
353 }
354 if (addr2Set.count() != 1) {
355 offsetData_.insert(
356 std::pair<int,OffsetData>(
357 pop2.poId(),OffsetData(NULL, INT_MAX)));
358 return ALIAS_UNKNOWN;
359 }
360 MoveNode& addr1 = addr1Set.at(0);
361 MoveNode& addr2 = addr2Set.at(0);
362
363 if (addr1.isSourceConstant() &&
364 addr2.move().source().isGPR()) {
365 anc2 = ddg.onlyRegisterRawAncestor(addr2, sp_);
366 offsetVal2 = addr1.move().source().value().intValue() *
367 offsetMul;
368 } else {
369 if (addr2.isSourceConstant() &&
370 addr1.move().source().isGPR()) {
371 anc2 = ddg.onlyRegisterRawAncestor(addr1, sp_);
372 offsetVal2 = addr2.move().source().value().intValue() *
373 offsetMul;
374 } else {
375 offsetData_.insert(
376 std::pair<int,OffsetData>(
377 pop2.poId(),OffsetData(NULL, INT_MAX)));
378 return ALIAS_UNKNOWN;
379 }
380 }
381
382 offsetData_.insert(
383 std::pair<int,OffsetData>(
384 pop2.poId(),OffsetData(anc2, offsetVal2)));
385 } else {
386 // direct memory op. have to search for the add.
387
388 // first find base and index of the first node.
389 const MoveNode* rawSrc2 =
390 ddg.onlyRegisterRawAncestor(*addrMove2, sp_);
391
392 if (!rawSrc2->isSourceOperation()) {
393 offsetData_.insert(
394 std::pair<int,OffsetData>(
395 pop2.poId(),OffsetData(rawSrc2, 0)));
396
397 } else {
398
399 ProgramOperation& po2 = rawSrc2->sourceOperation();
400
401 if (po2.operation().name() == "ADD" ||
402 po2.operation().name() == "SUB") {
403
404 // offset calc, add or sub. check for node2
405 MoveNodeSet& baseSet2 = po2.inputNode(1);
406 MoveNodeSet& offsetSet2 = po2.inputNode(2);
407
408 if (baseSet2.count() != 1 || offsetSet2.count() != 1) {
409 offsetData_.insert(
410 std::pair<int,OffsetData>(
411 pop2.poId(),OffsetData(NULL, INT_MAX)));
412 return ALIAS_UNKNOWN;
413 }
414
415 MoveNode& offsetNode2 = offsetSet2.at(0);
416 MoveNode& base2 = baseSet2.at(0);
417
418 // check that base is register coming from same place.
419
420 if (!base2.move().source().isGPR() ||
421 !offsetNode2.move().source().isImmediate()) {
422 offsetData_.insert(
423 std::pair<int,OffsetData>(
424 pop2.poId(),OffsetData(NULL, INT_MAX)));
425 return ALIAS_UNKNOWN;
426 }
427
428 offsetVal2 = offsetNode2.move().source().value().intValue();
429 if (po2.operation().name() == "SUB") {
430 offsetVal2 = -offsetVal2;
431 }
432
433 anc2 = ddg.onlyRegisterRawAncestor(base2, sp_);
434 // update cache.
435 offsetData_.insert(
436 std::pair<int,OffsetData>(
437 pop2.poId(),OffsetData(anc2, offsetVal2)));
438 } else {
439 // comes directly from some untraceable op.
440 if (ddg.regRawSuccessorCount(*rawSrc2, false) > 1) {
441 offsetData_.insert(
442 std::pair<int,OffsetData>(
443 pop2.poId(),OffsetData(rawSrc2, 0)));
444 anc2 = rawSrc2;
445 offsetVal2 = 0;
446 } else {
447 offsetData_.insert(
448 std::pair<int,OffsetData>(
449 pop2.poId(),OffsetData(NULL, INT_MAX)));
450 return ALIAS_UNKNOWN;
451 }
452 }
453 }
454 }
455 }
456 // now we have the defining move for base and offset. compare them
457
458 if (anc1 == NULL || anc2 == NULL) {
459 return ALIAS_UNKNOWN;
460 }
461
462 if (anc1 == anc2 || sameLoopAndPrevSources(ddg, *anc1, *anc2)) {
463
464 if (bbRel == MoveNodeUse::LOOP) {
465 if (!analyzeLoopPtrIncrease(ddg, *anc2, offsetVal2)) {
466 return ALIAS_UNKNOWN;
467 }
468 }
469
471 offsetVal1, offsetVal2, pop1, pop2);
472
473 return res;
474 }
475 return ALIAS_UNKNOWN;
476}
const MoveNode * onlyRegisterRawAncestor(const MoveNode &node, const std::string &sp) const
int regRawSuccessorCount(const MoveNode &mn, bool onlyScheduled)
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)
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
TTAProgram::Move & move()
bool isSourceOperation() const
Definition MoveNode.cc:168
bool isSourceConstant() const
Definition MoveNode.cc:238
std::map< int, OffsetData > offsetData_
bool analyzeLoopPtrIncrease(const DataDependenceGraph &ddg, const MoveNode &mn, long &offset)
bool sameLoopAndPrevSources(const DataDependenceGraph &ddg, const MoveNode &anc1, const MoveNode &anc2)
virtual TCEString name() const
Definition Operation.cc:93
const Operation & operation() const
unsigned int poId() const
MoveNodeSet & inputNode(int in) const
int intValue() const
Definition SimValue.cc:895
Terminal & source() const
Definition Move.cc:302
virtual SimValue value() const
Definition Terminal.cc:178
virtual bool isGPR() const
Definition Terminal.cc:107
virtual bool isImmediate() const
Definition Terminal.cc:63

References MemoryAliasAnalyzer::addressOperandMove(), MemoryAliasAnalyzer::ALIAS_UNKNOWN, analyzeLoopPtrIncrease(), MoveNodeSet::at(), MemoryAliasAnalyzer::compareIndeces(), MoveNodeSet::count(), MemoryAliasAnalyzer::findTwoPartAddressOperands(), ProgramOperation::inputNode(), SimValue::intValue(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), MoveNode::isSourceConstant(), MoveNode::isSourceOperation(), MoveNodeUse::LOOP, MoveNode::move(), Operation::name(), offsetData_, MemoryAliasAnalyzer::TwoPartAddressOperandDetection::offsetOperation, DataDependenceGraph::onlyRegisterRawAncestor(), MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand1, MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand2, ProgramOperation::operation(), ProgramOperation::poId(), DataDependenceGraph::regRawSuccessorCount(), sameLoopAndPrevSources(), TTAProgram::Move::source(), MoveNode::sourceOperation(), sp_, and TTAProgram::Terminal::value().

Here is the call graph for this function:

◆ analyzeLoopPtrIncrease()

bool OffsetAliasAnalyzer::analyzeLoopPtrIncrease ( const DataDependenceGraph ddg,
const MoveNode mn,
long &  offset 
)
private

Definition at line 495 of file OffsetAliasAnalyzer.cc.

496 {
497
498 MoveNode* prevSrc = ddg.onlyRegisterRawSource(mn,2,2);
499 MoveNode* loopSrc = ddg.onlyRegisterRawSource(mn,2,1);
500 // does not change in loop?
501 if (loopSrc == NULL) {
502 return true;
503 }
504
505 if (prevSrc == NULL) {
506 return false;
507 }
508 return findIncrement(*loopSrc, offset);
509}
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
static const MoveNode * findIncrement(const MoveNode &mn, long &increment)

References MemoryAliasAnalyzer::findIncrement(), and DataDependenceGraph::onlyRegisterRawSource().

Referenced by analyze().

Here is the call graph for this function:

◆ isAddressTraceable()

bool OffsetAliasAnalyzer::isAddressTraceable ( DataDependenceGraph ddg,
const ProgramOperation pop 
)
virtual

Checks if the node contains an adress that is an offset.

Parameters
ddgDDG where to analyze from
mnthe node being checked
Returns
true if is a traceable stack offset, false if not.

Implements MemoryAliasAnalyzer.

Definition at line 59 of file OffsetAliasAnalyzer.cc.

60 {
61
62 std::map<int,OffsetData>::iterator i = offsetData_.find(pop.poId());
63 if (i != offsetData_.end()) {
64 if (i->second.baseNode == NULL) {
65 return false;
66 } else {
67 return true;
68 }
69 }
70
71 const MoveNode* addrMove = addressOperandMove(pop);
72 if (addrMove == NULL) {
73
74 TwoPartAddressOperandDetection addressParts =
76 if (addressParts.offsetOperation ==
77 TwoPartAddressOperandDetection::NOT_FOUND) {
78 return false;
79 }
80
81 MoveNodeSet& addr1Set = pop.inputNode(addressParts.operand1);
82 MoveNodeSet& addr2Set = pop.inputNode(addressParts.operand2);
83 if (addr1Set.count() != 1) {
84 return false;
85 }
86 if (addr2Set.count() != 1) {
87 return false;
88 }
89 MoveNode& addr1 = addr1Set.at(0);
90 MoveNode& addr2 = addr2Set.at(0);
91
92 if ((addr1.move().source().isImmediate() &&
93 addr2.move().source().isGPR()) ||
94 (addr2.move().source().isImmediate() &&
95 addr1.move().source().isGPR())) {
96 return true;
97 } else {
98 return false;
99 }
100 }
101
102 // first find base and index of the first node.
103 const MoveNode* rawSrc = ddg.onlyRegisterRawAncestor(*addrMove, sp_);
104
105 if (!rawSrc->isSourceOperation()) {
106 offsetData_.insert(
107 std::pair<int,OffsetData>(
108 pop.poId(),OffsetData(rawSrc, 0)));
109 return true;
110 }
111
112 ProgramOperation& po = rawSrc->sourceOperation();
113
114 if (po.operation().name() != "ADD" &&
115 po.operation().name() != "SUB") {
116 if (ddg.regRawSuccessorCount(*rawSrc, false) > 1) {
117 offsetData_.insert(
118 std::pair<int,OffsetData>(
119 pop.poId(),OffsetData(rawSrc, 0)));
120 return true;
121 } else {
122 offsetData_.insert(
123 std::pair<int,OffsetData>(
124 pop.poId(),OffsetData(NULL, INT_MAX)));
125 return false;
126 }
127 }
128
129 // offset calc, add or sub. check for node2
130 MoveNodeSet& baseSet = po.inputNode(1);
131 MoveNodeSet& offsetSet = po.inputNode(2);
132
133 if (baseSet.count() != 1 || offsetSet.count() != 1) {
134 offsetData_.insert(
135 std::pair<int,OffsetData>(
136 pop.poId(),OffsetData(NULL, INT_MAX)));
137 return false;
138 }
139
140 MoveNode& offsetNode = offsetSet.at(0);
141 MoveNode& base = baseSet.at(0);
142
143 if (!base.move().source().isGPR() ||
144 !offsetNode.move().source().isImmediate()) {
145 offsetData_.insert(
146 std::pair<int,OffsetData>(
147 pop.poId(), OffsetData(NULL, INT_MAX)));
148 return false;
149 }
150
151 return true;
152}

References MemoryAliasAnalyzer::addressOperandMove(), MoveNodeSet::at(), MoveNodeSet::count(), MemoryAliasAnalyzer::findTwoPartAddressOperands(), ProgramOperation::inputNode(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), MoveNode::isSourceOperation(), MoveNode::move(), Operation::name(), offsetData_, MemoryAliasAnalyzer::TwoPartAddressOperandDetection::offsetOperation, DataDependenceGraph::onlyRegisterRawAncestor(), MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand1, MemoryAliasAnalyzer::TwoPartAddressOperandDetection::operand2, ProgramOperation::operation(), ProgramOperation::poId(), DataDependenceGraph::regRawSuccessorCount(), TTAProgram::Move::source(), MoveNode::sourceOperation(), and sp_.

Here is the call graph for this function:

◆ sameLoopAndPrevSources()

bool OffsetAliasAnalyzer::sameLoopAndPrevSources ( const DataDependenceGraph ddg,
const MoveNode anc1,
const MoveNode anc2 
)
private

Definition at line 478 of file OffsetAliasAnalyzer.cc.

479 {
480
481 MoveNode* prevSrc1 = ddg.onlyRegisterRawSource(anc1,2,2);
482 MoveNode* loopSrc1 = ddg.onlyRegisterRawSource(anc1,2,1);
483 MoveNode* prevSrc2 = ddg.onlyRegisterRawSource(anc2,2,2);
484 MoveNode* loopSrc2 = ddg.onlyRegisterRawSource(anc2,2,1);
485
486 return (prevSrc1 == prevSrc2 && loopSrc1 == loopSrc2 &&
487 prevSrc1 != NULL);
488}

References DataDependenceGraph::onlyRegisterRawSource().

Referenced by analyze().

Here is the call graph for this function:

Member Data Documentation

◆ offsetData_

std::map<int,OffsetData> OffsetAliasAnalyzer::offsetData_
private

Definition at line 69 of file OffsetAliasAnalyzer.hh.

Referenced by analyze(), and isAddressTraceable().

◆ sp_

TCEString OffsetAliasAnalyzer::sp_
private

Definition at line 71 of file OffsetAliasAnalyzer.hh.

Referenced by analyze(), and isAddressTraceable().


The documentation for this class was generated from the following files: