TempScopInfo: Add code to build the scalar dependences.

llvm-svn: 183653
This commit is contained in:
Hongbin Zheng 2013-06-10 13:55:34 +00:00
parent b96d1395f6
commit 599782bb6c
2 changed files with 76 additions and 5 deletions

View File

@ -39,8 +39,11 @@ public:
// The type of the scev affine function
enum TypeKind {
READ,
WRITE
READ = 0x1,
WRITE = 0x2,
SCALAR = 0x4,
SCALARREAD = SCALAR | READ,
SCALARWRITE = SCALAR | WRITE
};
private:
@ -64,9 +67,11 @@ public:
bool isAffine() const { return IsAffine; }
bool isRead() const { return Type == READ; }
bool isRead() const { return Type & READ; }
bool isWrite() const { return Type == WRITE; }
bool isWrite() const { return Type & WRITE; }
bool isScalar() const { return Type & SCALAR; }
};
class Comparison {
@ -237,9 +242,13 @@ class TempScopInfo : public FunctionPass {
// And also Remember the constrains for BBs
BBCondMapType BBConds;
// Access function of bbs.
// Access function of statements (currently BasicBlocks) .
AccFuncMapType AccFuncMap;
// Pre-created zero for the scalar accesses, with it we do not need create a
// zero scev every time when we need it.
const SCEV *ZeroOffset;
// Mapping regions to the corresponding Scop in current function.
TempScopMapType TempScops;
@ -274,6 +283,13 @@ class TempScopInfo : public FunctionPass {
/// instruction.
IRAccess buildIRAccess(Instruction *Inst, Loop *L, Region *R);
/// @brief Analyze and extract the cross-BB scalar dependences (or,
/// dataflow dependencies) of an instruction.
///
/// @param Inst The instruction to be analyzed
/// @param R The SCoP region
void buildScalarDependences(Instruction *Inst, Region *R);
void buildAccessFunctions(Region &RefRegion, BasicBlock &BB);
void buildLoopBounds(TempScop &Scop);

View File

@ -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);