Skip to content

Commit 924371a

Browse files
committed
Implement assumption bounds.
1 parent 9760e3e commit 924371a

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
@@ -789,6 +789,82 @@ void initializeTransferEndLog(const DefinitionInfo &Out, bool HasChanges,
789789
#endif
790790
}
791791

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

lib/Support/SCEVUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ const SCEV *subtractSCEVAndCast(const SCEV *LHS,
650650
auto LC = dyn_cast<SCEVConstant>(InnerLHS);
651651
auto RC = dyn_cast<SCEVConstant>(InnerRHS);
652652
if (LC && RC) {
653-
llvm_unreachable("Subtract constant SCEVs with different cast.");
653+
llvm_unreachable("Subtract constant SCEVs with a different cast.");
654654
} else if (LC && !RC) {
655655
return restoreCasts(TQRHS, SE->getMinusSCEV(InnerLHS, InnerRHS), SE);
656656
} else if (!LC && RC) {
@@ -673,7 +673,7 @@ const SCEV *addSCEVAndCast(const SCEV *LHS,
673673
auto LC = dyn_cast<SCEVConstant>(LHS);
674674
auto RC = dyn_cast<SCEVConstant>(RHS);
675675
if (LC && RC) {
676-
llvm_unreachable("Add constant SCEVs with different cast.");
676+
llvm_unreachable("Add constant SCEVs with a different cast.");
677677
} else if (LC && !RC) {
678678
return restoreCasts(TQRHS, SE->getAddExpr(InnerLHS, InnerRHS), SE);
679679
} else if (!LC && RC) {

0 commit comments

Comments
 (0)