Skip to content

Commit aa719af

Browse files
committed
[TSAR, Memory] Use assumption information to perform intersection of memory locations.
1 parent 924371a commit aa719af

File tree

12 files changed

+729
-392
lines changed

12 files changed

+729
-392
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===- AssumptionInfo.h -- Delinearization Engine --------------*- C++ -*-===//
2+
//
3+
// Traits Static Analyzer (SAPFOR)
4+
//
5+
// Copyright 2022 DVM System Group
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
//
21+
// This file allows to perform metadata-based delinearization of array accesses.
22+
//
23+
//===----------------------------------------------------------------------===/
24+
25+
#ifndef TSAR_ASSUMPTION_INFO_H
26+
#define TSAR_ASSUMPTION_INFO_H
27+
28+
#include "tsar/Analysis/Memory/Passes.h"
29+
#include <llvm/ADT/DenseMap.h>
30+
#include <llvm/Pass.h>
31+
#include <bcl/utility.h>
32+
33+
namespace llvm {
34+
class Value;
35+
}
36+
37+
namespace tsar {
38+
typedef llvm::Optional<int64_t> AssumptionBound;
39+
struct AssumptionBounds {
40+
AssumptionBound Lower = llvm::None;
41+
AssumptionBound Upper = llvm::None;
42+
};
43+
44+
typedef llvm::DenseMap<llvm::Value *, AssumptionBounds> AssumptionMap;
45+
}
46+
47+
namespace llvm {
48+
class AssumptionInfoPass : public FunctionPass, private bcl::Uncopyable {
49+
public:
50+
static char ID;
51+
52+
AssumptionInfoPass() : FunctionPass(ID) {
53+
initializeAssumptionInfoPassPass(*PassRegistry::getPassRegistry());
54+
}
55+
56+
bool runOnFunction(Function &F) override;
57+
void getAnalysisUsage(AnalysisUsage &AU) const override;
58+
void releaseMemory() override { mAM.clear(); }
59+
60+
const tsar::AssumptionMap & getAssumptionMap() const {
61+
return mAM;
62+
}
63+
private:
64+
tsar::AssumptionMap mAM;
65+
};
66+
}
67+
68+
#endif //TSAR_ASSUMPTION_INFO_H

include/tsar/Analysis/Memory/DefinedMemory.h

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -472,14 +472,6 @@ class ReachDFFwk : private bcl::Uncopyable {
472472
/// This covers IN and OUT value for a must/may reach definition analysis.
473473
typedef DFValue<ReachDFFwk, DefinitionInfo> ReachSet;
474474

475-
typedef llvm::Optional<int64_t> AssumptionBound;
476-
struct AssumptionBounds {
477-
AssumptionBound Lower = llvm::None;
478-
AssumptionBound Upper = llvm::None;
479-
};
480-
481-
typedef llvm::DenseMap<llvm::Value *, AssumptionBounds> AssumptionMap;
482-
483475
/// This represents results of reach definition analysis results.
484476
typedef llvm::DenseMap<DFNode *,
485477
std::tuple<std::unique_ptr<DefUseSet>, std::unique_ptr<ReachSet>>,
@@ -500,36 +492,32 @@ class ReachDFFwk : private bcl::Uncopyable {
500492
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
501493
const DFRegionInfo &DFI, const llvm::DominatorTree &DT,
502494
const DelinearizeInfo &DI, llvm::ScalarEvolution &SE,
503-
const llvm::DataLayout &DL, llvm::AssumptionCache &AC,
495+
const llvm::DataLayout &DL, const AssumptionMap &AM,
504496
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo) :
505497
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI),
506-
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo) {
507-
initializeAssumptions(AC);
508-
}
498+
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mAM(&AM), mGO(&GO),
499+
mDefInfo(&DefInfo) {}
509500

510501
/// Creates data-flow framework.
511502
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
512503
const DFRegionInfo &DFI, const llvm::DominatorTree &DT,
513504
const DelinearizeInfo &DI, llvm::ScalarEvolution &SE,
514-
const llvm::DataLayout &DL, llvm::AssumptionCache &AC,
505+
const llvm::DataLayout &DL, const AssumptionMap &AM,
515506
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo,
516507
InterprocDefUseInfo &InterprocDUInfo) :
517508
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI), mDT(&DT),
518-
mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo),
519-
mInterprocDUInfo(&InterprocDUInfo) {
520-
initializeAssumptions(AC);
521-
}
509+
mDI(&DI), mSE(&SE), mDL(&DL), mAM(&AM), mGO(&GO), mDefInfo(&DefInfo),
510+
mInterprocDUInfo(&InterprocDUInfo) {}
522511

523512
/// Creates data-flow framework.
524513
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
525514
const llvm::DominatorTree &DT, const DelinearizeInfo &DI,
526515
llvm::ScalarEvolution &SE, const llvm::DataLayout &DL,
527-
llvm::AssumptionCache &AC, const GlobalOptions &GO,
516+
const AssumptionMap &AM, const GlobalOptions &GO,
528517
DefinedMemoryInfo &DefInfo, InterprocDefUseInfo &InterprocDUInfo) :
529518
mAliasTree(&AT), mTLI(&TLI), mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL),
530-
mGO(&GO), mDefInfo(&DefInfo), mInterprocDUInfo(&InterprocDUInfo) {
531-
initializeAssumptions(AC);
532-
}
519+
mGO(&GO), mAM(&AM), mDefInfo(&DefInfo),
520+
mInterprocDUInfo(&InterprocDUInfo) {}
533521

534522
/// Return results of interprocedural analysis or nullptr.
535523
InterprocDefUseInfo * getInterprocDefUseInfo() noexcept {
@@ -568,8 +556,8 @@ class ReachDFFwk : private bcl::Uncopyable {
568556
/// Returns data layout.
569557
const llvm::DataLayout & getDataLayout() const noexcept { return *mDL; }
570558

571-
/// Returns assumption cache.
572-
const AssumptionMap & getAssumptionMap() const noexcept {
559+
/// Returns assumption map.
560+
const AssumptionMap * getAssumptionMap() const noexcept {
573561
return mAM;
574562
}
575563

@@ -580,8 +568,6 @@ class ReachDFFwk : private bcl::Uncopyable {
580568
/// in a data-flow graph of an outer region.
581569
void collapse(DFRegion *R);
582570
private:
583-
void initializeAssumptions(llvm::AssumptionCache &AC);
584-
585571
AliasTree *mAliasTree;
586572
llvm::TargetLibraryInfo *mTLI;
587573
const llvm::DominatorTree *mDT;
@@ -591,7 +577,7 @@ class ReachDFFwk : private bcl::Uncopyable {
591577
const DelinearizeInfo *mDI;
592578
llvm::ScalarEvolution *mSE;
593579
const llvm::DataLayout *mDL;
594-
AssumptionMap mAM;
580+
const AssumptionMap *mAM;
595581
const GlobalOptions *mGO;
596582
};
597583

include/tsar/Analysis/Memory/MemoryLocationRange.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#ifndef TSAR_MEMORY_LOCATION_RANGE_H
2626
#define TSAR_MEMORY_LOCATION_RANGE_H
2727

28+
#include "tsar/Analysis/Memory/AssumptionInfo.h"
2829
#include <llvm/ADT/APInt.h>
2930
#include <llvm/ADT/BitmaskEnum.h>
3031
#include <llvm/Analysis/MemoryLocation.h>
@@ -76,6 +77,7 @@ struct MemoryLocationRange {
7677
llvm::AAMDNodes AATags;
7778
LocKind Kind;
7879
llvm::ScalarEvolution *SE;
80+
const AssumptionMap *AM;
7981

8082
/// Return a location with information about the memory reference by the given
8183
/// instruction.
@@ -143,24 +145,26 @@ struct MemoryLocationRange {
143145
LocationSize UpperBound = UnknownSize,
144146
const llvm::AAMDNodes &AATags = llvm::AAMDNodes())
145147
: Ptr(Ptr), LowerBound(LowerBound), UpperBound(UpperBound),
146-
AATags(AATags), SE(nullptr), Kind(LocKind::Default) {}
148+
AATags(AATags), SE(nullptr), AM(nullptr), Kind(LocKind::Default) {}
147149

148150
explicit MemoryLocationRange(const llvm::Value *Ptr,
149151
LocationSize LowerBound,
150152
LocationSize UpperBound,
151153
LocKind Kind,
152154
llvm::ScalarEvolution *SE,
155+
AssumptionMap *AM,
153156
const llvm::AAMDNodes &AATags = llvm::AAMDNodes())
154157
: Ptr(Ptr), LowerBound(LowerBound), UpperBound(UpperBound), Kind(Kind),
155-
SE(SE), AATags(AATags) {}
158+
SE(SE), AM(AM), AATags(AATags) {}
156159

157160
MemoryLocationRange(const llvm::MemoryLocation &Loc)
158161
: Ptr(Loc.Ptr), LowerBound(0), UpperBound(Loc.Size), AATags(Loc.AATags),
159-
Kind(LocKind::Default), SE(nullptr) {}
162+
Kind(LocKind::Default), SE(nullptr), AM(nullptr) {}
160163

161164
MemoryLocationRange(const MemoryLocationRange &Loc)
162165
: Ptr(Loc.Ptr), LowerBound(Loc.LowerBound), UpperBound(Loc.UpperBound),
163-
AATags(Loc.AATags), DimList(Loc.DimList), Kind(Loc.Kind), SE(Loc.SE) {}
166+
AATags(Loc.AATags), DimList(Loc.DimList), Kind(Loc.Kind), SE(Loc.SE),
167+
AM(Loc.AM) {}
164168

165169
MemoryLocationRange &operator=(const llvm::MemoryLocation &Loc) {
166170
Ptr = Loc.Ptr;
@@ -169,13 +173,15 @@ struct MemoryLocationRange {
169173
AATags = Loc.AATags;
170174
Kind = Default;
171175
SE = nullptr;
176+
AM = nullptr;
172177
return *this;
173178
}
174179

175180
bool operator==(const MemoryLocationRange &Other) const {
176181
return Ptr == Other.Ptr && AATags == Other.AATags &&
177182
LowerBound == Other.LowerBound && UpperBound == Other.UpperBound &&
178-
DimList == Other.DimList && SE == Other.SE && Kind == Other.Kind;
183+
DimList == Other.DimList && SE == Other.SE && AM == Other.AM &&
184+
Kind == Other.Kind;
179185
}
180186

181187
llvm::StringRef getKindAsString() const {

include/tsar/Analysis/Memory/Passes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,5 +234,9 @@ ModulePass * createGlobalsAccessCollector();
234234
// Initialize a pass to access list of explicit accesses to global
235235
// values in a function.
236236
void initializeGlobalsAccessWrapperPass(PassRegistry &Registry);
237+
238+
FunctionPass *createAssumptionInfoPass();
239+
240+
void initializeAssumptionInfoPassPass(PassRegistry& Registry);
237241
}
238242
#endif//TSAR_MEMORY_ANALYSIS_PASSES_H

include/tsar/Support/SCEVUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
namespace llvm {
3232
class ScalarEvolution;
3333
class SCEV;
34+
class SCEVAddRecExpr;
3435
}
3536

3637
namespace tsar {
@@ -91,5 +92,11 @@ const llvm::SCEV *subtractSCEVAndCast(const llvm::SCEV *LHS,
9192
llvm::Optional<int64_t> compareSCEVs(const llvm::SCEV *LHS,
9293
const llvm::SCEV *RHS,
9394
llvm::ScalarEvolution *SE);
95+
96+
/// Return the value of this chain of recurrences at the specified
97+
/// iteration number.
98+
const llvm::SCEV *evaluateAtIteration(const llvm::SCEVAddRecExpr *ARE,
99+
const llvm::SCEV *It,
100+
llvm::ScalarEvolution *SE);
94101
}
95102
#endif//TSAR_SCEV_UTILS_H

0 commit comments

Comments
 (0)