forked from OSchip/llvm-project
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:
parent
3839b422e6
commit
ffa2446f28
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue