Index: include/polly/ScopDetection.h =================================================================== --- include/polly/ScopDetection.h +++ include/polly/ScopDetection.h @@ -195,7 +195,7 @@ /// /// @param CI The call instruction to check. /// @return True if the call instruction is valid, false otherwise. - static bool isValidCallInst(CallInst &CI); + bool isValidCallInst(CallInst &CI) const; /// @brief Check if a value is invariant in the region Reg. /// Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -299,7 +299,7 @@ return true; } -bool ScopDetection::isValidCallInst(CallInst &CI) { +bool ScopDetection::isValidCallInst(CallInst &CI) const { if (CI.doesNotReturn()) return false; @@ -370,6 +370,18 @@ } } + switch (AA->getModRefBehavior(CalledFunction)) { + case AliasAnalysis::DoesNotAccessMemory: + case AliasAnalysis::OnlyReadsArgumentPointees: + case AliasAnalysis::OnlyAccessesArgumentPointees: + return true; + // TODO Handle the case everything is read. + case AliasAnalysis::OnlyReadsMemory: + break; + default: + break; + } + return false; } Index: lib/Analysis/TempScopInfo.cpp =================================================================== --- lib/Analysis/TempScopInfo.cpp +++ lib/Analysis/TempScopInfo.cpp @@ -257,6 +257,51 @@ } } + bool OnlyReadsPointees = false; + Function *CalledFunction = CI->getCalledFunction(); + switch (AA->getModRefBehavior(CalledFunction)) { + case AliasAnalysis::DoesNotAccessMemory: + return; + case AliasAnalysis::OnlyReadsArgumentPointees: + OnlyReadsPointees = true; + // Fall through + case AliasAnalysis::OnlyAccessesArgumentPointees: + for (const auto &ArgUse : CI->arg_operands()) { + Value *Arg = ArgUse.get(); + if (!Arg->getType()->isPointerTy()) + continue; + + ReadAF = SE->getSCEVAtScope(Arg, L); + ReadBasePtr = dyn_cast(SE->getPointerBase(ReadAF)); + assert(ReadBasePtr && "Could not find base pointer"); + ReadAF = SE->getMinusSCEV(ReadAF, ReadBasePtr); + RSize = + TD->getTypeStoreSize(ReadBasePtr->getType()->getPointerElementType()); + Accs.push_back(std::make_pair( + IRAccess(IRAccess::READ, ReadBasePtr->getValue(), ReadAF, RSize, + false, Subscripts, Sizes, ReadAF, ReadUB), + CI)); + + if (OnlyReadsPointees) + continue; + + WriteAF = SE->getSCEVAtScope(Arg, L); + WriteBasePtr = dyn_cast(SE->getPointerBase(WriteAF)); + assert(WriteBasePtr && "Could not find base pointer"); + WriteAF = SE->getMinusSCEV(WriteAF, WriteBasePtr); + WSize = TD->getTypeStoreSize( + WriteBasePtr->getType()->getPointerElementType()); + Accs.push_back(std::make_pair( + IRAccess(IRAccess::MAY_WRITE, WriteBasePtr->getValue(), WriteAF, + WSize, false, Subscripts, Sizes, WriteAF, WriteUB), + CI)); + } + // TODO Handle the case everything is read. + case AliasAnalysis::OnlyReadsMemory: + default: + break; + } + llvm_unreachable("Unknown call instruction, cannot model the effect!"); }