@@ -929,45 +929,45 @@ void SplitGather(CallInst *CI) {
929929 CI->eraseFromParent ();
930930}
931931
932- // pre-transformation analysis to determine
933- // which kind of mem should we place TPM at
934- static bool checkSVMNecessary (Value *V, int LoadsMet = 0 ) {
935- // do not handle ConstExprs for now
936- if (!isa<Instruction>(V) && !isa<Argument>(V))
937- return false ;
938- if (isa<LoadInst>(V)) {
939- if (LoadsMet > 0 )
940- return true ;
941- else
932+ class SVMChecker {
933+ std::map<Value *, int > Visited;
934+
935+ public:
936+ // pre-transformation analysis to determine
937+ // which kind of mem should we place TPM at
938+ int checkSVMNecessary (Value *V) {
939+ if (Visited.count (V) > 0 )
940+ return Visited.at (V);
941+ // do not handle ConstExprs for now
942+ if (!isa<Instruction>(V) && !isa<Argument>(V))
943+ return 0 ;
944+ int LoadsMet = 0 ;
945+ if (isa<LoadInst>(V)) {
942946 ++LoadsMet;
943- } else if (auto *CI = dyn_cast<CallInst>(V)) {
944- auto IID = GenXIntrinsic::getAnyIntrinsicID (CI);
945- if (IID == GenXIntrinsic::genx_gather_private ||
946- IID == GenXIntrinsic::genx_scatter_private ||
947- IID == GenXIntrinsic::not_any_intrinsic) {
948- // do not process users of priv mem intrinsics
949- // or calls to other functions
950- return false ;
947+ } else if (auto *CI = dyn_cast<CallInst>(V)) {
948+ auto IID = GenXIntrinsic::getAnyIntrinsicID (CI);
949+ if (IID == GenXIntrinsic::genx_gather_private ||
950+ IID == GenXIntrinsic::genx_scatter_private ||
951+ IID == GenXIntrinsic::not_any_intrinsic) {
952+ // do not process users of priv mem intrinsics
953+ // or calls to other functions
954+ return 0 ;
955+ }
956+ } else if (isa<PHINode>(V) || isa<ICmpInst>(V)) {
957+ // do not go thru phi as loops may appear and
958+ // it doesn't seem necessary for the analysis now
959+ return 0 ;
951960 }
952- } else if (isa<PHINode>(V)) {
953- // do not go thru phi as loops may appear and
954- // it doesn't seem necessary for the analysis now
955- return false ;
956- }
957- bool Result = false ;
958- for (auto *U : V->users ()) {
959- Result |= checkSVMNecessary (U, LoadsMet);
960- if (Result)
961- break ;
961+ int Result = 0 ;
962+ for (auto *U : V->users ()) {
963+ Result = std::max (Result, checkSVMNecessary (U));
964+ }
965+ Visited.insert (std::make_pair (V, Result + LoadsMet));
966+ return Result + LoadsMet;
962967 }
963- return Result;
964- }
965968
966- // required to pass find_if's typecheck
967- static bool checkSVMNecessaryPred (Value *V) {
968- assert (isa<Instruction>(V) || isa<Argument>(V));
969- return checkSVMNecessary (V);
970- }
969+ bool operator ()(Value *V) { return checkSVMNecessary (V) > 1 ; }
970+ };
971971
972972void GenXThreadPrivateMemory::addUsers (Value *V) {
973973 assert (isa<Instruction>(V) || isa<Argument>(V));
@@ -1027,7 +1027,7 @@ bool GenXThreadPrivateMemory::runOnModule(Module &M) {
10271027 for (auto &F : M)
10281028 visit (F);
10291029 if (!m_useGlobalMem &&
1030- std::find_if (m_alloca.begin (), m_alloca.end (), checkSVMNecessaryPred ) !=
1030+ std::find_if (m_alloca.begin (), m_alloca.end (), SVMChecker () ) !=
10311031 m_alloca.end ()) {
10321032 LLVM_DEBUG (dbgs () << " Switching TPM to SVM\n " );
10331033 // TODO: move the name string to vc-intrinsics *MD::useGlobalMem
@@ -1183,7 +1183,7 @@ void GenXThreadPrivateMemory::visitAllocaInst(AllocaInst &I) {
11831183
11841184void GenXThreadPrivateMemory::visitFunction (Function &F) {
11851185 for (auto &Arg : F.args ())
1186- if (Arg.getType ()->isPointerTy () && checkSVMNecessaryPred (&Arg)) {
1186+ if (Arg.getType ()->isPointerTy () && SVMChecker () (&Arg)) {
11871187 LLVM_DEBUG (dbgs () << " Switching TPM to SVM: svm arg\n " );
11881188 // TODO: move the name string to vc-intrinsics *MD::useGlobalMem
11891189 if (!m_useGlobalMem)
0 commit comments