From ffa2446f28d22115e615f1f6609ac525f1472fa3 Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sat, 17 Oct 2015 08:54:13 +0000 Subject: [PATCH] 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 --- polly/include/polly/CodeGen/BlockGenerators.h | 10 ++++++ polly/lib/CodeGen/BlockGenerators.cpp | 33 ++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/polly/include/polly/CodeGen/BlockGenerators.h b/polly/include/polly/CodeGen/BlockGenerators.h index 49dc6e01eaab..8e1330bd205e 100644 --- a/polly/include/polly/CodeGen/BlockGenerators.h +++ b/polly/include/polly/CodeGen/BlockGenerators.h @@ -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. diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index d8755def05d7..4596ce7da1b1 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -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(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()); }