Skip to content

Commit 3ac4e77

Browse files
committed
[TSAR, Memory, AliasTree] Do not use UnknownSize for allocas.
Accesses outside the allocated side are forbidden. So, the size of local variables is known even if someone takes there address.
1 parent 2816c63 commit 3ac4e77

File tree

8 files changed

+119
-91
lines changed

8 files changed

+119
-91
lines changed

include/tsar/Analysis/Memory/EstimateMemory.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,10 @@ class AliasTree {
10891089

10901090
/// Returns the smallest estimate memory location which covers a specified
10911091
/// memory location or nullptr.
1092+
///
1093+
/// \attention The size of found location (EM) may be smaller than the size of
1094+
/// a specified one (Loc) if it is known that access out of the EM size leads
1095+
/// to undefined behavior.
10921096
EstimateMemory * find(const llvm::MemoryLocation &Loc) {
10931097
return const_cast<EstimateMemory *>(
10941098
static_cast<const AliasTree *>(this)->find(Loc));
@@ -1099,12 +1103,18 @@ class AliasTree {
10991103
///
11001104
/// TODO ([email protected]): implement accurate search do not ignore lower
11011105
/// bound.
1106+
/// \attention The size of found location (EM) may be smaller than the size of
1107+
/// a specified one (Loc) if it is known that access out of the EM size leads
1108+
/// to undefined behavior.
11021109
const EstimateMemory * find(const MemoryLocationRange &Loc) const {
11031110
return find(llvm::MemoryLocation(Loc.Ptr, Loc.UpperBound, Loc.AATags));
11041111
}
11051112

11061113
/// Returns the smallest estimate memory location which covers a specified
11071114
/// memory location or nullptr.
1115+
/// \attention The size of found location (EM) may be smaller than the size of
1116+
/// a specified one (Loc) if it is known that access out of the EM size leads
1117+
/// to undefined behavior.
11081118
EstimateMemory * find(const MemoryLocationRange &Loc) {
11091119
return const_cast<EstimateMemory *>(
11101120
static_cast<const AliasTree *>(this)->find(Loc));

lib/Analysis/Memory/DefinedMemory.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ void DataFlowTraits<ReachDFFwk*>::initialize(
426426
[&DL, &AT, InterDUInfo, &TLI, &DU](Instruction &I, MemoryLocation &&Loc,
427427
unsigned Idx, AccessInfo R, AccessInfo W) {
428428
auto *EM = AT.find(Loc);
429+
// EM may be smaller than Loc if it is known that access out of the
430+
// EM size leads to undefined behavior.
431+
Loc.Size = EM->getSize();
429432
assert(EM && "Estimate memory location must not be null!");
430433
auto &AA = AT.getAliasAnalysis();
431434
/// List of ambiguous pointers contains only one pointer for each set

lib/Analysis/Memory/EstimateMemory.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,30 @@ STATISTIC(NumMergedNode, "Number of alias nodes merged in");
5151
STATISTIC(NumEstimateMemory, "Number of estimate memory created");
5252
STATISTIC(NumUnknownMemory, "Number of unknown memory created");
5353

54+
static inline void clarifyUnknownSize(const DataLayout &DL,
55+
MemoryLocation &Loc, const DominatorTree *DT = nullptr) {
56+
if (Loc.Size.hasValue())
57+
return;
58+
if (auto GV = dyn_cast<GlobalValue>(Loc.Ptr)) {
59+
auto Ty = GV->getValueType();
60+
if (Ty->isSized())
61+
Loc.Size = LocationSize::precise(DL.getTypeStoreSize(Ty));
62+
} else if (auto AI = dyn_cast<AllocaInst>(Loc.Ptr)) {
63+
auto Ty = AI->getAllocatedType();
64+
auto Size = AI->getArraySize();
65+
if (Ty->isSized() && isa<ConstantInt>(Size))
66+
Loc.Size = LocationSize::precise(
67+
cast<ConstantInt>(Size)->getValue().getZExtValue() *
68+
DL.getTypeStoreSize(Ty));
69+
}
70+
LLVM_DEBUG(if (Loc.Size.hasValue()) {
71+
dbgs()
72+
<< "[ALIAS TREE]: decrease the location size to the allocated size: ";
73+
printLocationSource(dbgs(), Loc, DT);
74+
dbgs() << "\n";
75+
});
76+
}
77+
5478
namespace tsar {
5579
Value * stripPointer(const DataLayout &DL, Value *Ptr) {
5680
assert(Ptr && "Pointer to memory location must not be null!");
@@ -179,18 +203,7 @@ bool stripMemoryLevel(const DataLayout &DL, MemoryLocation &Loc) {
179203
return true;
180204
}
181205
Loc.Size = LocationSize::unknown();
182-
if (auto GV = dyn_cast<GlobalValue>(Loc.Ptr)) {
183-
auto Ty = GV->getValueType();
184-
if (Ty->isSized())
185-
Loc.Size = LocationSize::precise(DL.getTypeStoreSize(Ty));
186-
} else if (auto AI = dyn_cast<AllocaInst>(Loc.Ptr)) {
187-
auto Ty = AI->getAllocatedType();
188-
auto Size = AI->getArraySize();
189-
if (Ty->isSized() && isa<ConstantInt>(Size))
190-
Loc.Size = LocationSize::precise(
191-
cast<ConstantInt>(Size)->getValue().getZExtValue() *
192-
DL.getTypeStoreSize(Ty));
193-
}
206+
clarifyUnknownSize(DL, Loc);
194207
return true;
195208
}
196209
return false;
@@ -491,6 +504,7 @@ void AliasTree::add(const MemoryLocation &Loc) {
491504
mSearchCache.clear();
492505
using CT = bcl::ChainTraits<EstimateMemory, Hierarchy>;
493506
MemoryLocation Base(Loc);
507+
clarifyUnknownSize(*mDL, Base, mDT);
494508
EstimateMemory *PrevChainEnd = nullptr;
495509
do {
496510
LLVM_DEBUG(evaluateMemoryLevelLog(Base, getDomTree()));
@@ -831,6 +845,7 @@ const AliasUnknownNode * AliasTree::findUnknown(
831845
const EstimateMemory * AliasTree::find(const llvm::MemoryLocation &Loc) const {
832846
assert(Loc.Ptr && "Pointer to memory location must not be null!");
833847
MemoryLocation Base(Loc);
848+
clarifyUnknownSize(*mDL, Base, mDT);
834849
stripToBase(*mDL, Base);
835850
auto SearchInfo = mSearchCache.try_emplace(Base, nullptr);
836851
if (!SearchInfo.second)
@@ -1014,8 +1029,8 @@ bool EstimateMemoryPass::runOnFunction(Function &F) {
10141029
AccessedUnknown.insert(&I);
10151030
mAliasTree->addUnknown(&I);
10161031
};
1017-
for_each_memory(F, TLI, [&addLocation](
1018-
Instruction &, MemoryLocation &&Loc, unsigned, AccessInfo, AccessInfo) {
1032+
for_each_memory(F, TLI, [&DL, &addLocation](
1033+
Instruction &I, MemoryLocation &&Loc, unsigned, AccessInfo, AccessInfo) {
10191034
addLocation(std::move(Loc));
10201035
},
10211036
[&addUnknown](Instruction &I, AccessInfo, AccessInfo) {

test/analysis/da_di/address_1.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@ void foo (int N) {
88
//CHECK: Printing analysis 'Dependency Analysis (Metadata)' for function 'foo':
99
//CHECK: loop at depth 1 address_1.c:5:3
1010
//CHECK: output:
11-
//CHECK: <X:4:10, ?> bar():6:5
11+
//CHECK: <X:4:10, 8> bar():6:5
1212
//CHECK: anti:
13-
//CHECK: <X:4:10, ?> bar():6:5
13+
//CHECK: <X:4:10, 8> bar():6:5
1414
//CHECK: flow:
15-
//CHECK: <X:4:10, ?> bar():6:5
15+
//CHECK: <X:4:10, 8> bar():6:5
1616
//CHECK: induction:
1717
//CHECK: <I:5[5:3], 4>:[Int,0,10,1]
1818
//CHECK: lock:
19-
//CHECK: <I:5[5:3], 4> | <X:4:10, ?> bar():6:5
19+
//CHECK: <I:5[5:3], 4> | <X:4:10, 8> bar():6:5
2020
//CHECK: header access:
2121
//CHECK: <I:5[5:3], 4>
2222
//CHECK: explicit access:
23-
//CHECK: <I:5[5:3], 4> | <X:4:10, ?> bar():6:5
23+
//CHECK: <I:5[5:3], 4> | <X:4:10, 8> bar():6:5
2424
//CHECK: address access:
25-
//CHECK: <X:4:10, ?> bar():6:5
25+
//CHECK: <X:4:10, 8> bar():6:5
2626
//CHECK: explicit access (separate):
27-
//CHECK: <I:5[5:3], 4> <X:4:10, ?> bar():6:5
27+
//CHECK: <I:5[5:3], 4> <X:4:10, 8> bar():6:5
2828
//CHECK: lock (separate):
29-
//CHECK: <I:5[5:3], 4> <X:4:10, ?>
29+
//CHECK: <I:5[5:3], 4> <X:4:10, 8>
3030
//CHECK: address access (separate):
31-
//CHECK: <X:4:10, ?> bar():6:5
31+
//CHECK: <X:4:10, 8> bar():6:5
3232
//CHECK: no promoted scalar (separate):
33-
//CHECK: <X:4:10, ?>
33+
//CHECK: <X:4:10, 8>
3434
//CHECK: direct access (separate):
35-
//CHECK: <I:5[5:3], 4> <X:4:10, ?> bar():6:5
35+
//CHECK: <I:5[5:3], 4> <X:4:10, 8> bar():6:5

test/analysis/da_di/address_5.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@ void bar() {
1212
//CHECK: Printing analysis 'Dependency Analysis (Metadata)' for function 'bar':
1313
//CHECK: loop at depth 1 address_5.c:7:3
1414
//CHECK: output:
15-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5
15+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5
1616
//CHECK: anti:
17-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5
17+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5
1818
//CHECK: flow:
19-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5
19+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5
2020
//CHECK: induction:
2121
//CHECK: <I:7[7:3], 4>:[Int,0,10,1]
2222
//CHECK: lock:
23-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5 | <I:7[7:3], 4>
23+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5 | <I:7[7:3], 4>
2424
//CHECK: header access:
2525
//CHECK: <I:7[7:3], 4>
2626
//CHECK: explicit access:
27-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5 | <I:7[7:3], 4>
27+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5 | <I:7[7:3], 4>
2828
//CHECK: address access:
29-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?> exec():9:5 init():8:5
29+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8> exec():9:5 init():8:5
3030
//CHECK: explicit access (separate):
31-
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, ?> exec():9:5 init():8:5
31+
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, 8> exec():9:5 init():8:5
3232
//CHECK: lock (separate):
33-
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, ?>
33+
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, 8>
3434
//CHECK: address access (separate):
35-
//CHECK: <P:5:8, ?> exec():9:5 init():8:5
35+
//CHECK: <P:5:8, 8> exec():9:5 init():8:5
3636
//CHECK: no promoted scalar (separate):
37-
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, ?>
37+
//CHECK: <*P:{9:10|5:8}, ?> <P:5:8, 8>
3838
//CHECK: direct access (separate):
39-
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, ?> exec():9:5 init():8:5
39+
//CHECK: <*P:{9:10|5:8}, ?> <I:7[7:3], 4> <P:5:8, 8> exec():9:5 init():8:5

test/analysis/da_di/address_6.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,24 @@ int foo() {
1616
//CHECK: Printing analysis 'Dependency Analysis (Metadata)' for function 'foo':
1717
//CHECK: loop at depth 1 address_6.c:8:3
1818
//CHECK: private:
19-
//CHECK: <X:6:7, ?>
19+
//CHECK: <X:6:7, 4>
2020
//CHECK: induction:
2121
//CHECK: <I:8[8:3], 4>:[Int,0,10,1]
2222
//CHECK: reduction:
2323
//CHECK: <S:6, 4>:mult
2424
//CHECK: no promoted scalar:
25-
//CHECK: <X:6:7, ?>
25+
//CHECK: <X:6:7, 4>
2626
//CHECK: lock:
27-
//CHECK: <I:8[8:3], 4> | <X:6:7, ?>
27+
//CHECK: <I:8[8:3], 4> | <X:6:7, 4>
2828
//CHECK: header access:
2929
//CHECK: <I:8[8:3], 4>
3030
//CHECK: explicit access:
31-
//CHECK: <I:8[8:3], 4> | <S:6, 4>
31+
//CHECK: <I:8[8:3], 4> | <S:6, 4> | <X:6:7, 4>
3232
//CHECK: explicit access (separate):
33-
//CHECK: <I:8[8:3], 4> <S:6, 4>
33+
//CHECK: <I:8[8:3], 4> <S:6, 4> <X:6:7, 4>
3434
//CHECK: lock (separate):
35-
//CHECK: <I:8[8:3], 4> <X:6:7, ?>
35+
//CHECK: <I:8[8:3], 4> <X:6:7, 4>
3636
//CHECK: no promoted scalar (separate):
37-
//CHECK: <X:6:7, ?>
37+
//CHECK: <X:6:7, 4>
3838
//CHECK: direct access (separate):
39-
//CHECK: <I:8[8:3], 4> <S:6, 4> <X:6:7, ?>
39+
//CHECK: <I:8[8:3], 4> <S:6, 4> <X:6:7, 4>

test/analysis/da_di/interproc_1.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,24 @@ void bar(int X, int N, float * restrict A) {
1919
//CHECK: induction:
2020
//CHECK: <I:7[7:3], 4>:[Int,0,,1]
2121
//CHECK: read only:
22-
//CHECK: <A:5, 8> | <N:5, 4> | <X:5:14, ?>
22+
//CHECK: <A:5, 8> | <N:5, 4> | <X:5:14, 4>
2323
//CHECK: no promoted scalar:
24-
//CHECK: <X:5:14, ?>
24+
//CHECK: <X:5:14, 4>
2525
//CHECK: lock:
26-
//CHECK: <I:7[7:3], 4> | <N:5, 4> | <X:5:14, ?>
26+
//CHECK: <I:7[7:3], 4> | <N:5, 4> | <X:5:14, 4>
2727
//CHECK: header access:
2828
//CHECK: <I:7[7:3], 4> | <N:5, 4>
2929
//CHECK: explicit access:
30-
//CHECK: <A:5, 8> | <I:7[7:3], 4> | <N:5, 4> | <X:5:14, ?>
30+
//CHECK: <A:5, 8> | <I:7[7:3], 4> | <N:5, 4> | <X:5:14, 4>
3131
//CHECK: address access:
32-
//CHECK: <X:5:14, ?>
32+
//CHECK: <X:5:14, 4>
3333
//CHECK: explicit access (separate):
34-
//CHECK: <A:5, 8> <I:7[7:3], 4> <N:5, 4> <X:5:14, ?>
34+
//CHECK: <A:5, 8> <I:7[7:3], 4> <N:5, 4> <X:5:14, 4>
3535
//CHECK: lock (separate):
36-
//CHECK: <I:7[7:3], 4> <N:5, 4> <X:5:14, ?>
36+
//CHECK: <I:7[7:3], 4> <N:5, 4> <X:5:14, 4>
3737
//CHECK: address access (separate):
38-
//CHECK: <X:5:14, ?>
38+
//CHECK: <X:5:14, 4>
3939
//CHECK: no promoted scalar (separate):
40-
//CHECK: <X:5:14, ?>
40+
//CHECK: <X:5:14, 4>
4141
//CHECK: direct access (separate):
42-
//CHECK: <*A:5, ?> <A:5, 8> <I:7[7:3], 4> <N:5, 4> <X:5:14, ?>
42+
//CHECK: <*A:5, ?> <A:5, 8> <I:7[7:3], 4> <N:5, 4> <X:5:14, 4>

0 commit comments

Comments
 (0)