summaryrefslogtreecommitdiffstats
path: root/polly/lib/Analysis/TempScopInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/Analysis/TempScopInfo.cpp')
-rw-r--r--polly/lib/Analysis/TempScopInfo.cpp55
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);
OpenPOWER on IntegriCloud