BlockGenerator: Register outside users of scalars directly

Instead of checking at code generation time for each ScopStmt if a scalar has
external uses, we just iterate over the ScopArrayInfo descriptions we have and
check each of these for possible external uses.

Besides being somehow clearer, this approach has the benefit that we will always
create valid LLVM-IR even in case we disable the code generation of ScopStmt
bodies e.g. for testing purposes.

llvm-svn: 250608
This commit is contained in:
Tobias Grosser 2015-10-17 08:54:13 +00:00
parent 3839b422e6
commit ffa2446f28
2 changed files with 38 additions and 5 deletions

View File

@ -373,6 +373,16 @@ protected:
void handleOutsideUsers(const Region &R, Instruction *Inst,
Value *Address = nullptr);
/// @brief Find scalar statements that have outside users.
///
/// We register these scalar values to later update subsequent scalar uses of
/// these values to either use the newly computed value from within the scop
/// (if the scop was executed) or the unchanged original code (if the run-time
/// check failed).
///
/// @param S The scop for which to find the outside users.
void findOutsideUsers(Scop &S);
/// @brief Initialize the memory of demoted scalars.
///
/// @param S The scop for which to generate the scalar initializers.

View File

@ -312,10 +312,6 @@ void BlockGenerator::copyBB(ScopStmt &Stmt, BasicBlock *BB, BasicBlock *CopyBB,
// in their alloca. First the scalars that have dependences inside the SCoP,
// then the ones that might escape the SCoP.
generateScalarStores(Stmt, BB, LTS, BBMap);
const Region &R = Stmt.getParent()->getRegion();
for (Instruction &Inst : *BB)
handleOutsideUsers(R, &Inst);
}
Value *BlockGenerator::getOrCreateAlloca(Value *ScalarBase,
@ -572,7 +568,8 @@ void BlockGenerator::createScalarFinalization(Region &R) {
}
}
void BlockGenerator::finalizeSCoP(Scop &S) {
void BlockGenerator::findOutsideUsers(Scop &S) {
auto &R = S.getRegion();
// Handle PHI nodes that were in the original exit and are now
// moved into the region exiting block.
@ -589,6 +586,32 @@ void BlockGenerator::finalizeSCoP(Scop &S) {
}
}
for (auto &Pair : S.arrays()) {
auto &Array = Pair.second;
if (Array->getNumberOfDimensions() != 0)
continue;
if (Array->isPHI())
continue;
auto *Inst = dyn_cast<Instruction>(Array->getBasePtr());
if (!Inst)
continue;
// Scop invariant hoisting moves some of the base pointers out of the scop.
// We can ignore these, as the invariant load hoisting already registers the
// relevant outside users.
if (!R.contains(Inst))
continue;
handleOutsideUsers(R, Inst, nullptr);
}
}
void BlockGenerator::finalizeSCoP(Scop &S) {
findOutsideUsers(S);
createScalarInitialization(S);
createScalarFinalization(S.getRegion());
}