Skip to content

Commit 170367b

Browse files
committed
[TSAR, Memory] Implement analysis of memory locations with variable bounds.
1 parent b42f3a0 commit 170367b

File tree

21 files changed

+1921
-471
lines changed

21 files changed

+1921
-471
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===- AssumptionInfo.h ----- Assumption Information ------------*- 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 provides assumption information for memory locations with variable
22+
// bounds.
23+
//
24+
//===----------------------------------------------------------------------===/
25+
26+
#ifndef TSAR_ASSUMPTION_INFO_H
27+
#define TSAR_ASSUMPTION_INFO_H
28+
29+
#include "tsar/Analysis/Memory/Passes.h"
30+
#include <llvm/ADT/DenseMap.h>
31+
#include <llvm/Pass.h>
32+
#include <bcl/utility.h>
33+
34+
namespace llvm {
35+
class Value;
36+
}
37+
38+
namespace tsar {
39+
typedef llvm::Optional<int64_t> AssumptionBound;
40+
struct AssumptionBounds {
41+
AssumptionBound Lower = llvm::None;
42+
AssumptionBound Upper = llvm::None;
43+
};
44+
45+
typedef llvm::DenseMap<llvm::Value *, AssumptionBounds> AssumptionMap;
46+
}
47+
48+
namespace llvm {
49+
class AssumptionInfoPass : public FunctionPass, private bcl::Uncopyable {
50+
public:
51+
static char ID;
52+
53+
AssumptionInfoPass() : FunctionPass(ID) {
54+
initializeAssumptionInfoPassPass(*PassRegistry::getPassRegistry());
55+
}
56+
57+
bool runOnFunction(Function &F) override;
58+
void getAnalysisUsage(AnalysisUsage &AU) const override;
59+
void releaseMemory() override { mAM.clear(); }
60+
61+
const tsar::AssumptionMap & getAssumptionMap() const {
62+
return mAM;
63+
}
64+
private:
65+
tsar::AssumptionMap mAM;
66+
};
67+
}
68+
69+
#endif //TSAR_ASSUMPTION_INFO_H

include/tsar/Analysis/Memory/DefinedMemory.h

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <llvm/Pass.h>
5353

5454
namespace llvm {
55+
class AssumptionCache;
5556
class DominatorTree;
5657
class Value;
5758
class Instruction;
@@ -92,6 +93,11 @@ class DefUseSet {
9293
/// Set of memory locations.
9394
typedef MemorySet<MemoryLocationRange> LocationSet;
9495

96+
/// Set of data flow nodes with which memory locations from the
97+
/// ExplicitAccesses set are associated.
98+
typedef llvm::SmallDenseMap<const llvm::Value *,
99+
llvm::SmallDenseSet<const DFNode *>> ExplicitNodeMap;
100+
95101
/// Returns set of the must defined locations.
96102
const LocationSet & getDefs() const { return mDefs; }
97103

@@ -209,8 +215,9 @@ class DefUseSet {
209215
return mUses.insert(Uses.begin(), Uses.end());
210216
}
211217

212-
/// TODO: description
213-
void updateCollapsedLocations() {
218+
/// Replaced collapsed memory locations with its expanded forms which are
219+
/// of kind `Default`.
220+
void summarizeCollapsedLocations() {
214221
LocationSet DestDefs, DestMayDefs, DestUses;
215222
for (auto &Loc : mDefs) {
216223
if (Loc.Kind == MemoryLocationRange::LocKind::Collapsed)
@@ -385,6 +392,42 @@ class DefUseSet {
385392
.second;
386393
}
387394

395+
/// Inserts a data flow node associated with a collapsable explicit access
396+
/// ExplLoc. ColLoc is a collapsed memory location created from the ExplLoc.
397+
void addNodeOfCollapsableExplicitAccess(
398+
const MemoryLocationRange &ExplLoc,
399+
const MemoryLocationRange &ColLoc,
400+
const DFNode *N) {
401+
assert(ExplLoc.Ptr && "Location pointer must not be null!");
402+
assert(ColLoc.Kind == MemoryLocationRange::LocKind::Collapsed &&
403+
"Location must be of a `collapsed` kind!");
404+
mCollapsableExplicitAccesses.try_emplace(ExplLoc.Ptr).first->second.insert(N);
405+
}
406+
407+
/// Returns a map of collapsable explicit accesses with associated data flow
408+
/// nodes.
409+
const ExplicitNodeMap & getCollapsableExplicitAccesses() const {
410+
return mCollapsableExplicitAccesses;
411+
}
412+
413+
/// Specifies that there are a collapsable explicit access to all collapsable
414+
/// explicit accesses from a specified map.
415+
void addCollapsableExplicitAccesses(const ExplicitNodeMap &ENM) {
416+
for (auto Itr = ENM.begin(); Itr != ENM.end(); ++Itr) {
417+
auto &NodeList = Itr->second;
418+
mCollapsableExplicitAccesses.try_emplace(Itr->first).
419+
first->second.insert(NodeList.begin(), NodeList.end());
420+
}
421+
}
422+
423+
/// Returns a pointer to a set of data flow nodes associated with the memory
424+
/// location Loc if it is collabsable. Returns `nullptr` otherwise.
425+
const llvm::SmallDenseSet<const DFNode *> *
426+
getNodesOfCollapsableExplicitAccess(const MemoryLocationRange &Loc) const {
427+
auto Itr = mCollapsableExplicitAccesses.find(Loc.Ptr);
428+
return Itr == mCollapsableExplicitAccesses.end() ? nullptr : &Itr->second;
429+
}
430+
388431
private:
389432
LocationSet mDefs;
390433
LocationSet mMayDefs;
@@ -395,6 +438,7 @@ class DefUseSet {
395438
InstructionSet mExplicitUnknowns;
396439
InstructionSet mAddressUnknowns;
397440
TransitiveMap mAddressTransitives;
441+
ExplicitNodeMap mCollapsableExplicitAccesses;
398442
};
399443

400444
/// This presents information whether a location has definition after a node
@@ -448,29 +492,32 @@ class ReachDFFwk : private bcl::Uncopyable {
448492
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
449493
const DFRegionInfo &DFI, const llvm::DominatorTree &DT,
450494
const DelinearizeInfo &DI, llvm::ScalarEvolution &SE,
451-
const llvm::DataLayout &DL, const GlobalOptions &GO,
452-
DefinedMemoryInfo &DefInfo) :
495+
const llvm::DataLayout &DL, const AssumptionMap &AM,
496+
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo) :
453497
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI),
454-
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo) {}
498+
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mAM(&AM), mGO(&GO),
499+
mDefInfo(&DefInfo) {}
455500

456501
/// Creates data-flow framework.
457502
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
458503
const DFRegionInfo &DFI, const llvm::DominatorTree &DT,
459504
const DelinearizeInfo &DI, llvm::ScalarEvolution &SE,
460-
const llvm::DataLayout &DL, const GlobalOptions &GO,
461-
DefinedMemoryInfo &DefInfo, InterprocDefUseInfo &InterprocDUInfo) :
505+
const llvm::DataLayout &DL, const AssumptionMap &AM,
506+
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo,
507+
InterprocDefUseInfo &InterprocDUInfo) :
462508
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI), mDT(&DT),
463-
mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo),
509+
mDI(&DI), mSE(&SE), mDL(&DL), mAM(&AM), mGO(&GO), mDefInfo(&DefInfo),
464510
mInterprocDUInfo(&InterprocDUInfo) {}
465511

466512
/// Creates data-flow framework.
467513
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
468514
const llvm::DominatorTree &DT, const DelinearizeInfo &DI,
469515
llvm::ScalarEvolution &SE, const llvm::DataLayout &DL,
470-
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo,
471-
InterprocDefUseInfo &InterprocDUInfo) :
516+
const AssumptionMap &AM, const GlobalOptions &GO,
517+
DefinedMemoryInfo &DefInfo, InterprocDefUseInfo &InterprocDUInfo) :
472518
mAliasTree(&AT), mTLI(&TLI), mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL),
473-
mGO(&GO), mDefInfo(&DefInfo), mInterprocDUInfo(&InterprocDUInfo) {}
519+
mGO(&GO), mAM(&AM), mDefInfo(&DefInfo),
520+
mInterprocDUInfo(&InterprocDUInfo) {}
474521

475522
/// Return results of interprocedural analysis or nullptr.
476523
InterprocDefUseInfo * getInterprocDefUseInfo() noexcept {
@@ -509,6 +556,11 @@ class ReachDFFwk : private bcl::Uncopyable {
509556
/// Returns data layout.
510557
const llvm::DataLayout & getDataLayout() const noexcept { return *mDL; }
511558

559+
/// Returns assumption map.
560+
const AssumptionMap * getAssumptionMap() const noexcept {
561+
return mAM;
562+
}
563+
512564
/// Returns global options.
513565
const GlobalOptions & getGlobalOptions() const noexcept { return *mGO; }
514566

@@ -525,6 +577,7 @@ class ReachDFFwk : private bcl::Uncopyable {
525577
const DelinearizeInfo *mDI;
526578
llvm::ScalarEvolution *mSE;
527579
const llvm::DataLayout *mDL;
580+
const AssumptionMap *mAM;
528581
const GlobalOptions *mGO;
529582
};
530583

0 commit comments

Comments
 (0)