diff options
Diffstat (limited to 'polly/lib/Analysis/TempScopInfo.cpp')
-rw-r--r-- | polly/lib/Analysis/TempScopInfo.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/polly/lib/Analysis/TempScopInfo.cpp b/polly/lib/Analysis/TempScopInfo.cpp index 78210a532f6..b475ab4555d 100644 --- a/polly/lib/Analysis/TempScopInfo.cpp +++ b/polly/lib/Analysis/TempScopInfo.cpp @@ -15,6 +15,7 @@ #include "polly/TempScopInfo.h" #include "polly/LinkAllPasses.h" +#include "polly/CodeGen/BlockGenerators.h" #include "polly/Support/GICHelper.h" #include "polly/Support/SCEVValidator.h" #include "polly/Support/ScopHelper.h" @@ -73,6 +74,57 @@ void TempScop::printDetail(llvm::raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI, const Region *CurR, unsigned ind) const {} +void TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R) { + // No need to translate these scalar dependences into polyhedral form, because + // synthesizable scalars can be generated by the code generator. + if (canSynthesize(Inst, LI, SE, R)) + return; + + bool AnyCrossStmtUse = false; + BasicBlock *ParentBB = Inst->getParent(); + + for (Instruction::use_iterator UI = Inst->use_begin(), UE = Inst->use_end(); + UI != UE; ++UI) { + Instruction *U = dyn_cast<Instruction>(*UI); + + // Ignore the strange user + if (U == 0) + continue; + + BasicBlock *UseParent = U->getParent(); + + // Ignore the users in the same BB (statement) + if (UseParent == ParentBB) + continue; + + // No need to translate these scalar dependences into polyhedral form, + // because synthesizable scalars can be generated by the code generator. + if (canSynthesize(U, LI, SE, R)) + continue; + + // Now U is used in another statement. + AnyCrossStmtUse = true; + + // Do not build a read access that is not in the current SCoP + if (!R->contains(UseParent)) + continue; + + assert(!isa<PHINode>(U) && "Non synthesizable PHINode found in a SCoP!"); + + // Use the def instruction as base address of the IRAccess, so that it will + // become the the name of the scalar access in the polyhedral form. + IRAccess ScalarAccess(IRAccess::SCALARREAD, Inst, ZeroOffset, 1, true); + AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, U)); + } + + // If the Instruction is used outside the statement, we need to build the + // write access. + if (AnyCrossStmtUse) { + IRAccess ScalarAccess(IRAccess::SCALARWRITE, Inst, ZeroOffset, 1, true); + AccFuncMap[ParentBB].push_back(std::make_pair(ScalarAccess, Inst)); + } +} + IRAccess TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R) { unsigned Size; enum IRAccess::TypeKind Type; @@ -107,6 +159,8 @@ void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB) { Instruction *Inst = I; if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) Functions.push_back(std::make_pair(buildIRAccess(Inst, L, &R), Inst)); + + if (!isa<StoreInst>(Inst)) buildScalarDependences(Inst, &R); } if (Functions.empty()) @@ -260,6 +314,7 @@ bool TempScopInfo::runOnFunction(Function &F) { SD = &getAnalysis<ScopDetection>(); AA = &getAnalysis<AliasAnalysis>(); TD = &getAnalysis<DataLayout>(); + ZeroOffset = SE->getConstant(TD->getIntPtrType(F.getContext()), 0); for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) { Region *R = const_cast<Region *>(*I); |