Skip to content

Commit d2953f8

Browse files
committed
Implement assumption bounds.
1 parent 7979b15 commit d2953f8

File tree

3 files changed

+102
-11
lines changed

3 files changed

+102
-11
lines changed

include/tsar/Analysis/Memory/DefinedMemory.h

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,14 @@ 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+
475483
/// This represents results of reach definition analysis results.
476484
typedef llvm::DenseMap<DFNode *,
477485
std::tuple<std::unique_ptr<DefUseSet>, std::unique_ptr<ReachSet>>,
@@ -495,8 +503,9 @@ class ReachDFFwk : private bcl::Uncopyable {
495503
const llvm::DataLayout &DL, llvm::AssumptionCache &AC,
496504
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo) :
497505
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI),
498-
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mAC(&AC), mGO(&GO),
499-
mDefInfo(&DefInfo) {}
506+
mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo) {
507+
initializeAssumptions(AC);
508+
}
500509

501510
/// Creates data-flow framework.
502511
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
@@ -506,8 +515,10 @@ class ReachDFFwk : private bcl::Uncopyable {
506515
const GlobalOptions &GO, DefinedMemoryInfo &DefInfo,
507516
InterprocDefUseInfo &InterprocDUInfo) :
508517
mAliasTree(&AT), mTLI(&TLI), mRegionInfo(&DFI), mDT(&DT),
509-
mDI(&DI), mSE(&SE), mDL(&DL), mAC(&AC), mGO(&GO), mDefInfo(&DefInfo),
510-
mInterprocDUInfo(&InterprocDUInfo) {}
518+
mDI(&DI), mSE(&SE), mDL(&DL), mGO(&GO), mDefInfo(&DefInfo),
519+
mInterprocDUInfo(&InterprocDUInfo) {
520+
initializeAssumptions(AC);
521+
}
511522

512523
/// Creates data-flow framework.
513524
ReachDFFwk(AliasTree &AT, llvm::TargetLibraryInfo &TLI,
@@ -516,8 +527,9 @@ class ReachDFFwk : private bcl::Uncopyable {
516527
llvm::AssumptionCache &AC, const GlobalOptions &GO,
517528
DefinedMemoryInfo &DefInfo, InterprocDefUseInfo &InterprocDUInfo) :
518529
mAliasTree(&AT), mTLI(&TLI), mDT(&DT), mDI(&DI), mSE(&SE), mDL(&DL),
519-
mAC(&AC), mGO(&GO), mDefInfo(&DefInfo),
520-
mInterprocDUInfo(&InterprocDUInfo) {}
530+
mGO(&GO), mDefInfo(&DefInfo), mInterprocDUInfo(&InterprocDUInfo) {
531+
initializeAssumptions(AC);
532+
}
521533

522534
/// Return results of interprocedural analysis or nullptr.
523535
InterprocDefUseInfo * getInterprocDefUseInfo() noexcept {
@@ -557,8 +569,8 @@ class ReachDFFwk : private bcl::Uncopyable {
557569
const llvm::DataLayout & getDataLayout() const noexcept { return *mDL; }
558570

559571
/// Returns assumption cache.
560-
llvm::AssumptionCache & getAssumptionCache() const noexcept {
561-
return *mAC;
572+
const AssumptionMap & getAssumptionMap() const noexcept {
573+
return mAM;
562574
}
563575

564576
/// Returns global options.
@@ -568,6 +580,8 @@ class ReachDFFwk : private bcl::Uncopyable {
568580
/// in a data-flow graph of an outer region.
569581
void collapse(DFRegion *R);
570582
private:
583+
void initializeAssumptions(llvm::AssumptionCache &AC);
584+
571585
AliasTree *mAliasTree;
572586
llvm::TargetLibraryInfo *mTLI;
573587
const llvm::DominatorTree *mDT;
@@ -577,7 +591,7 @@ class ReachDFFwk : private bcl::Uncopyable {
577591
const DelinearizeInfo *mDI;
578592
llvm::ScalarEvolution *mSE;
579593
const llvm::DataLayout *mDL;
580-
llvm::AssumptionCache *mAC;
594+
AssumptionMap mAM;
581595
const GlobalOptions *mGO;
582596
};
583597

lib/Analysis/Memory/DefinedMemory.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,82 @@ void initializeTransferEndLog(const DefinitionInfo &Out, bool HasChanges,
796796
#endif
797797
}
798798

799+
void ReachDFFwk::initializeAssumptions(AssumptionCache &AC) {
800+
auto IsRelational = [](CmpInst::Predicate Pred) {
801+
return Pred == CmpInst::Predicate::ICMP_UGE ||
802+
Pred == CmpInst::Predicate::ICMP_SGE ||
803+
Pred == CmpInst::Predicate::ICMP_UGT ||
804+
Pred == CmpInst::Predicate::ICMP_SGT ||
805+
Pred == CmpInst::Predicate::ICMP_ULE ||
806+
Pred == CmpInst::Predicate::ICMP_SLE ||
807+
Pred == CmpInst::Predicate::ICMP_ULT ||
808+
Pred == CmpInst::Predicate::ICMP_SLT;
809+
};
810+
// C > V
811+
auto UpdateBound = [](ConstantInt *C, Value *V, CmpInst::Predicate Pred,
812+
AssumptionBounds &Bounds) {
813+
auto CV = C->getSExtValue();
814+
switch (Pred)
815+
{
816+
case CmpInst::Predicate::ICMP_UGE:
817+
case CmpInst::Predicate::ICMP_SGE:
818+
Bounds.Upper = Bounds.Upper ? std::max(CV, *Bounds.Upper) : CV;
819+
break;
820+
case CmpInst::Predicate::ICMP_UGT:
821+
case CmpInst::Predicate::ICMP_SGT:
822+
Bounds.Upper = Bounds.Upper ? std::max(CV - 1, *Bounds.Upper) :
823+
CV - 1;
824+
break;
825+
case CmpInst::Predicate::ICMP_ULE:
826+
case CmpInst::Predicate::ICMP_SLE:
827+
Bounds.Lower = Bounds.Lower ? std::min(CV, *Bounds.Lower) : CV;
828+
break;
829+
case CmpInst::Predicate::ICMP_ULT:
830+
case CmpInst::Predicate::ICMP_SLT:
831+
Bounds.Lower = Bounds.Lower ? std::min(CV + 1, *Bounds.Lower) :
832+
CV + 1;
833+
break;
834+
default:
835+
llvm_unreachable("Predicate must be relational!");
836+
}
837+
};
838+
for (auto &AssumeVH : AC.assumptions()) {
839+
if (!AssumeVH)
840+
continue;
841+
if (auto *I = dyn_cast<CallInst>(AssumeVH.Assume)) {
842+
//LLVM_DEBUG(dbgs() << "[ASSUME] CallInst: "; I->dump());
843+
auto *CI = dyn_cast<CmpInst>(I->getArgOperand(0));
844+
if (CI && CI->isIntPredicate() && IsRelational(CI->getPredicate())) {
845+
//LLVM_DEBUG(dbgs() << "[ASSUME] CmpInst: "; CI->dump());
846+
assert(CI->getNumOperands() == 2 &&
847+
"Number of operands for CmpInst must be 2!");
848+
auto *Op0 = CI->getOperand(0);
849+
auto *Op1 = CI->getOperand(1);
850+
auto *C0 = dyn_cast<ConstantInt>(Op0);
851+
auto *C1 = dyn_cast<ConstantInt>(Op1);
852+
if (C0 && !C1) {
853+
AssumptionBounds &Bounds = mAM.insert(
854+
std::make_pair(Op1, AssumptionBounds())).first->second;
855+
UpdateBound(C0, Op1, CI->getPredicate(), Bounds);
856+
} else if (!C0 && C1) {
857+
AssumptionBounds &Bounds = mAM.insert(
858+
std::make_pair(Op0, AssumptionBounds())).first->second;
859+
UpdateBound(C1, Op0, CI->getSwappedPredicate(), Bounds);
860+
}
861+
}
862+
}
863+
}
864+
LLVM_DEBUG(
865+
dbgs() << "[ASSUME] Bounds: ";
866+
for (auto &Pair : mAM) {
867+
dbgs() << "<";
868+
Pair.first->print(dbgs(), true);
869+
dbgs() << ", [" << Pair.second.Lower << ", " << Pair.second.Upper << "]> ";
870+
}
871+
dbgs() << "\n";
872+
);
873+
};
874+
799875
void DataFlowTraits<ReachDFFwk*>::initialize(
800876
DFNode *N, ReachDFFwk *DFF, GraphType) {
801877
assert(N && "Node must not be null!");
@@ -1213,6 +1289,7 @@ void ReachDFFwk::collapse(DFRegion *R) {
12131289
LLVM_DEBUG(printLocInfo("[COLLAPSE] Collapse Use location: ", Loc));
12141290
distribute(aggregate(R, N, Loc, this), Loc, OwnUses, OtherUses);
12151291
}
1292+
LLVM_DEBUG(dbgs() << "[COLLAPSE] MustReachIn:\n"; MustReachIn.dump(&getDomTree()));
12161293
LocationSet NewUses;
12171294
for (auto &Loc : OwnUses) {
12181295
SmallVector<MemoryLocationRange, 4> UseDiff;

lib/Support/SCEVUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ const SCEV *subtractSCEVAndCast(const SCEV *LHS,
654654
auto LC = dyn_cast<SCEVConstant>(InnerLHS);
655655
auto RC = dyn_cast<SCEVConstant>(InnerRHS);
656656
if (LC && RC) {
657-
llvm_unreachable("Subtract constant SCEVs with different cast.");
657+
llvm_unreachable("Subtract constant SCEVs with a different cast.");
658658
} else if (LC && !RC) {
659659
return restoreCasts(TQRHS, SE->getMinusSCEV(InnerLHS, InnerRHS), SE);
660660
} else if (!LC && RC) {
@@ -677,7 +677,7 @@ const SCEV *addSCEVAndCast(const SCEV *LHS,
677677
auto LC = dyn_cast<SCEVConstant>(LHS);
678678
auto RC = dyn_cast<SCEVConstant>(RHS);
679679
if (LC && RC) {
680-
llvm_unreachable("Add constant SCEVs with different cast.");
680+
llvm_unreachable("Add constant SCEVs with a different cast.");
681681
} else if (LC && !RC) {
682682
return restoreCasts(TQRHS, SE->getAddExpr(InnerLHS, InnerRHS), SE);
683683
} else if (!LC && RC) {

0 commit comments

Comments
 (0)