1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
//
// This file implements the AliasSetTracker and AliasSet classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/iMemory.h"
#include "llvm/iOther.h"
#include "llvm/iTerminators.h"
/// updateAccessTypes - Depending on what type of accesses are in this set,
/// decide whether the set contains just references, just modifications, or a
/// mix.
///
void AliasSet::updateAccessType() {
if (!Calls.empty() || !Invokes.empty()) {
AccessTy = ModRef;
} else if (!Loads.empty()) {
if (Stores.empty())
AccessTy = Refs;
else
AccessTy = ModRef;
} else {
AccessTy = Mods;
}
}
/// mergeSetIn - Merge the specified alias set into this alias set...
///
void AliasSet::mergeSetIn(const AliasSet &AS) {
// Merge instruction sets...
Loads.insert( Loads.end(), AS.Loads.begin() , AS.Loads.end());
Stores.insert( Stores.end(), AS.Stores.begin() , AS.Stores.end());
Calls.insert( Calls.end(), AS.Calls.begin() , AS.Calls.end());
Invokes.insert(Invokes.end(), AS.Invokes.begin(), AS.Invokes.end());
// Update the alias and access types of this set...
if (AS.getAliasType() == MayAlias)
AliasTy = MayAlias;
updateAccessType();
}
/// pointerAliasesSet - Return true if the specified pointer "may" (or must)
/// alias one of the members in the set.
///
bool AliasSet::pointerAliasesSet(const Value *Ptr, AliasAnalysis &AA) const {
if (!Calls.empty() || !Invokes.empty())
return true;
for (unsigned i = 0, e = Loads.size(); i != e; ++i)
if (AA.alias(Ptr, Loads[i]->getOperand(0)))
return true;
for (unsigned i = 0, e = Stores.size(); i != e; ++i)
if (AA.alias(Ptr, Stores[i]->getOperand(1)))
return true;
return false;
}
/// getSomePointer - This method may only be called when the AliasType of the
/// set is MustAlias. This is used to return any old pointer (which must alias
/// all other pointers in the set) so that the caller can decide whether to turn
/// this set into a may alias set or not.
///
Value *AliasSet::getSomePointer() const {
assert(getAliasType() == MustAlias &&
"Cannot call getSomePointer on a 'MayAlias' set!");
assert(Calls.empty() && Invokes.empty() && "Call/invokes mean may alias!");
if (!Loads.empty())
return Loads[0]->getOperand(0);
assert(!Stores.empty() && "There are no instructions in this set!");
return Stores[0]->getOperand(1);
}
/// findAliasSetForPointer - Given a pointer, find the one alias set to put the
/// instruction referring to the pointer into. If there are multiple alias sets
/// that may alias the pointer, merge them together and return the unified set.
///
AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr) {
AliasSet *FoundSet = 0;
for (unsigned i = 0; i != AliasSets.size(); ++i) {
if (AliasSets[i].pointerAliasesSet(Ptr, AA)) {
if (FoundSet == 0) { // If this is the first alias set ptr can go into...
FoundSet = &AliasSets[i]; // Remember it.
} else { // Otherwise, we must merge the sets...
FoundSet->mergeSetIn(AliasSets[i]); // Merge in contents...
AliasSets.erase(AliasSets.begin()+i); // Remove the set...
--i; // Don't skip the next set
}
}
}
return FoundSet;
}
void AliasSetTracker::add(LoadInst *LI) {
Value *Pointer = LI->getOperand(0);
// Check to see if the loaded pointer aliases any sets...
AliasSet *AS = findAliasSetForPointer(Pointer);
if (AS) {
AS->Loads.push_back(LI);
// Check to see if we need to change this into a MayAlias set now...
if (AS->getAliasType() == AliasSet::MustAlias)
if (AA.alias(AS->getSomePointer(), Pointer) != AliasAnalysis::MustAlias)
AS->AliasTy = AliasSet::MayAlias;
AS->updateAccessType();
} else {
// Otherwise create a new alias set to hold the load...
AliasSets.push_back(AliasSet());
AliasSets.back().Loads.push_back(LI);
AliasSets.back().AccessTy = AliasSet::Refs;
}
}
void AliasSetTracker::add(StoreInst *SI) {
Value *Pointer = SI->getOperand(1);
// Check to see if the loaded pointer aliases any sets...
AliasSet *AS = findAliasSetForPointer(Pointer);
if (AS) {
AS->Stores.push_back(SI);
// Check to see if we need to change this into a MayAlias set now...
if (AS->getAliasType() == AliasSet::MustAlias)
if (AA.alias(AS->getSomePointer(), Pointer) != AliasAnalysis::MustAlias)
AS->AliasTy = AliasSet::MayAlias;
AS->updateAccessType();
} else {
// Otherwise create a new alias set to hold the load...
AliasSets.push_back(AliasSet());
AliasSets.back().Stores.push_back(SI);
AliasSets.back().AccessTy = AliasSet::Mods;
}
}
void AliasSetTracker::mergeAllSets() {
if (AliasSets.size() < 2) return; // Noop
// Merge all of the sets into set #0
for (unsigned i = 1, e = AliasSets.size(); i != e; ++i)
AliasSets[0].mergeSetIn(AliasSets[i]);
// Delete extraneous sets...
AliasSets.erase(AliasSets.begin()+1, AliasSets.end());
}
void AliasSetTracker::add(CallInst *CI) {
if (!AliasSets.empty()) {
mergeAllSets();
} else {
AliasSets.push_back(AliasSet());
}
AliasSets[0].AccessTy = AliasSet::ModRef;
AliasSets[0].AliasTy = AliasSet::MayAlias;
AliasSets[0].Calls.push_back(CI);
}
void AliasSetTracker::add(InvokeInst *II) {
if (!AliasSets.empty()) {
mergeAllSets();
} else {
AliasSets.push_back(AliasSet());
}
AliasSets[0].AccessTy = AliasSet::ModRef;
AliasSets[0].AliasTy = AliasSet::MayAlias;
AliasSets[0].Invokes.push_back(II);
}
|