2424
2525#include " tsar/Analysis/Memory/DefinedMemory.h"
2626#include " tsar/Analysis/DFRegionInfo.h"
27+ #include " tsar/Analysis/Memory/Delinearization.h"
2728#include " tsar/Analysis/Memory/EstimateMemory.h"
2829#include " tsar/Analysis/Memory/MemoryAccessUtils.h"
2930#include " tsar/Analysis/Memory/Utils.h"
3031#include " tsar/Support/Utils.h"
3132#include " tsar/Support/IRUtils.h"
33+ #include " tsar/Support/SCEVUtils.h"
3234#include " tsar/Unparse/Utils.h"
3335#include < llvm/ADT/STLExtras.h>
3436#include < llvm/Analysis/AliasAnalysis.h>
3537#include < llvm/Analysis/AliasSetTracker.h>
3638#include < llvm/Analysis/LoopInfo.h>
39+ #include " llvm/Analysis/ScalarEvolution.h"
40+ #include " llvm/Analysis/ScalarEvolutionExpressions.h"
3741#include < llvm/Analysis/ValueTracking.h>
3842#include < llvm/Config/llvm-config.h>
3943#include < llvm/IR/Dominators.h>
@@ -53,6 +57,8 @@ char DefinedMemoryPass::ID = 0;
5357INITIALIZE_PASS_BEGIN (DefinedMemoryPass, " def-mem" ,
5458 " Defined Memory Region Analysis" , false , true )
5559 LLVM_DEBUG(INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass));
60+ INITIALIZE_PASS_DEPENDENCY (DelinearizationPass)
61+ INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
5662 INITIALIZE_PASS_DEPENDENCY(DFRegionInfoPass)
5763 INITIALIZE_PASS_DEPENDENCY(EstimateMemoryPass)
5864 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
@@ -67,18 +73,23 @@ bool llvm::DefinedMemoryPass::runOnFunction(Function & F) {
6773 const DominatorTree *DT = nullptr ;
6874 LLVM_DEBUG (DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ());
6975 auto *DFF = cast<DFFunction>(RegionInfo.getTopLevelRegion ());
76+ auto &DI = getAnalysis<DelinearizationPass>().getDelinearizeInfo ();
77+ auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE ();
7078 auto &GDM = getAnalysis<GlobalDefinedMemoryWrapper>();
79+ auto &DL = F.getParent ()->getDataLayout ();
7180 if (GDM) {
72- ReachDFFwk ReachDefFwk (AliasTree, TLI, DT, mDefInfo , *GDM);
81+ ReachDFFwk ReachDefFwk (AliasTree, TLI, DT, mDefInfo , DI, SE, DL, *GDM);
7382 solveDataFlowUpward (&ReachDefFwk, DFF);
7483 } else {
75- ReachDFFwk ReachDefFwk (AliasTree, TLI, DT, mDefInfo );
84+ ReachDFFwk ReachDefFwk (AliasTree, TLI, DT, mDefInfo , DI, SE, DL );
7685 solveDataFlowUpward (&ReachDefFwk, DFF);
7786 }
7887 return false ;
7988}
8089
8190void DefinedMemoryPass::getAnalysisUsage (AnalysisUsage & AU) const {
91+ AU.addRequired <DelinearizationPass>();
92+ AU.addRequired <ScalarEvolutionWrapperPass>();
8293 LLVM_DEBUG (AU.addRequired <DominatorTreeWrapperPass>());
8394 AU.addRequired <DFRegionInfoPass>();
8495 AU.addRequired <EstimateMemoryPass>();
@@ -579,6 +590,49 @@ void ReachDFFwk::collapse(DFRegion *R) {
579590 // of execution paths of iterations of the loop.
580591 DFNode *ExitNode = R->getExitNode ();
581592 const DefinitionInfo &ExitingDefs = RT::getValue (ExitNode, this );
593+ auto calcArrayLocation = [this , R](const tsar::MemoryLocationRange &Loc) {
594+ MemoryLocationRange arrayLoc;
595+ arrayLoc.Ptr = nullptr ;
596+ auto LocInfo = getDelinearizeInfo ()->findRange (Loc.Ptr );
597+ if (LocInfo.first && LocInfo.first ->isDelinearized () &&
598+ LocInfo.second ->isValid ()) {
599+ for (auto *S : LocInfo.second ->Subscripts ) {
600+ auto *SE = getScalarEvolution ();
601+ auto AddRecInfo = computeSCEVAddRec (S, *SE);
602+ if (AddRecInfo.second ) {
603+ auto SCEV = AddRecInfo.first ;
604+ if (static_cast <SCEVTypes>(SCEV->getSCEVType ()) != scAddRecExpr) {
605+ break ;
606+ }
607+ auto addRecExpr = cast<SCEVAddRecExpr>(SCEV);
608+ if (auto *DFL = dyn_cast<DFLoop>(R)) {
609+ auto *L = DFL->getLoop ();
610+ auto maxTripCount = SE->getSmallConstantMaxTripCount (L);
611+ if (maxTripCount == 0 )
612+ break ;
613+ auto rangeMin = SE->getSignedRangeMin (SCEV);
614+ auto rangeMax = SE->getSignedRangeMax (SCEV);
615+ auto *stepSCEV = addRecExpr->getOperand (1 );
616+ if (static_cast <SCEVTypes>(stepSCEV->getSCEVType ()) !=
617+ scConstant)
618+ break ;
619+ auto stepNumber = *cast<SCEVConstant>(stepSCEV)->
620+ getValue ()->getValue ().getRawData ();
621+ if (stepNumber > 1 )
622+ break ;
623+ PointerType *pointerType = cast<PointerType>(
624+ LocInfo.first ->getBase ()->getType ());
625+ auto arrayElementSize = getDataLayout ().getTypeStoreSize (
626+ pointerType->getElementType ());
627+ arrayLoc = Loc;
628+ arrayLoc.LowerBound = *rangeMin.getRawData () * arrayElementSize;
629+ arrayLoc.UpperBound = (*rangeMax.getRawData ()+1 ) * arrayElementSize;
630+ }
631+ }
632+ }
633+ }
634+ return arrayLoc;
635+ };
582636 for (DFNode *N : R->getNodes ()) {
583637 auto DefItr = getDefInfo ().find (N);
584638 assert (DefItr != getDefInfo ().end () &&
@@ -624,8 +678,13 @@ void ReachDFFwk::collapse(DFRegion *R) {
624678 break ;
625679 }
626680 }
627- if (!RS->getIn ().MustReach .contain (Loc) && !(StartInLoop && EndInLoop))
628- DefUse->addUse (Loc);
681+ if (!RS->getIn ().MustReach .contain (Loc) && !(StartInLoop && EndInLoop)) {
682+ auto arrayLoc = calcArrayLocation (Loc);
683+ if (arrayLoc.Ptr != nullptr )
684+ DefUse->addUse (arrayLoc);
685+ else
686+ DefUse->addUse (Loc);
687+ }
629688 }
630689 // It is possible that some locations are only written in the loop.
631690 // In this case this locations are not located at set of node uses but
@@ -648,13 +707,27 @@ void ReachDFFwk::collapse(DFRegion *R) {
648707 // X = ...;
649708 // }
650709 for (auto &Loc : DU->getDefs ()) {
651- if (ExitingDefs.MustReach .contain (Loc))
652- DefUse->addDef (Loc);
710+ if (ExitingDefs.MustReach .contain (Loc)) {
711+ auto arrayLoc = calcArrayLocation (Loc);
712+ if (arrayLoc.Ptr != nullptr )
713+ DefUse->addDef (arrayLoc);
714+ else
715+ DefUse->addDef (Loc);
716+ } else {
717+ auto arrayLoc = calcArrayLocation (Loc);
718+ if (arrayLoc.Ptr != nullptr )
719+ DefUse->addMayDef (arrayLoc);
720+ else
721+ DefUse->addMayDef (Loc);
722+ }
723+ }
724+ for (auto &Loc : DU->getMayDefs ()) {
725+ auto arrayLoc = calcArrayLocation (Loc);
726+ if (arrayLoc.Ptr != nullptr )
727+ DefUse->addMayDef (arrayLoc);
653728 else
654729 DefUse->addMayDef (Loc);
655730 }
656- for (auto &Loc : DU->getMayDefs ())
657- DefUse->addMayDef (Loc);
658731 DefUse->addExplicitAccesses (DU->getExplicitAccesses ());
659732 DefUse->addExplicitUnknowns (DU->getExplicitUnknowns ());
660733 for (auto Loc : DU->getAddressAccesses ())
0 commit comments