#define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
#include "llvm/Transforms/Utils/ValueMapper.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
namespace llvm {
/// analyze L
/// if versioning is necessary version L
/// transform L
- void versionLoop();
+ void versionLoop() { versionLoop(findDefsUsedOutsideOfLoop(VersionedLoop)); }
- /// \brief Adds the necessary PHI nodes for the versioned loops based on the
- /// loop-defined values used outside of the loop.
- ///
- /// This needs to be called after versionLoop if there are defs in the loop
- /// that are used outside the loop. FIXME: this should be invoked internally
- /// by versionLoop and made private.
- void addPHINodes(const SmallVectorImpl<Instruction *> &DefsUsedOutside);
+ /// \brief Same but if the client has already precomputed the set of values
+ /// used outside the loop, this API will allows passing that.
+ void versionLoop(const SmallVectorImpl<Instruction *> &DefsUsedOutside);
/// \brief Returns the versioned loop. Control flows here if pointers in the
/// loop don't alias (i.e. all memchecks passed). (This loop is actually the
Loop *getNonVersionedLoop() { return NonVersionedLoop; }
private:
+ /// \brief Adds the necessary PHI nodes for the versioned loops based on the
+ /// loop-defined values used outside of the loop.
+ ///
+ /// This needs to be called after versionLoop if there are defs in the loop
+ /// that are used outside the loop.
+ void addPHINodes(const SmallVectorImpl<Instruction *> &DefsUsedOutside);
+
/// \brief The original loop. This becomes the "versioned" one. I.e.,
/// control flows here if pointers in the loop don't alias.
Loop *VersionedLoop;
DEBUG(dbgs() << "\nPointers:\n");
DEBUG(LAI.getRuntimePointerChecking()->printChecks(dbgs(), Checks));
LoopVersioning LVer(std::move(Checks), LAI, L, LI, DT);
- LVer.versionLoop();
- LVer.addPHINodes(DefsUsedOutside);
+ LVer.versionLoop(DefsUsedOutside);
}
// Create identical copies of the original loop for each partition and hook
assert(L->getLoopPreheader() && "No preheader");
}
-void LoopVersioning::versionLoop() {
+void LoopVersioning::versionLoop(
+ const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
Instruction *FirstCheckInst;
Instruction *MemRuntimeCheck;
// Add the memcheck in the original preheader (this is empty initially).
// The loops merge in the original exit block. This is now dominated by the
// memchecking block.
DT->changeImmediateDominator(VersionedLoop->getExitBlock(), MemCheckBB);
+
+ // Adds the necessary PHI nodes for the versioned loops based on the
+ // loop-defined values used outside of the loop.
+ addPHINodes(DefsUsedOutside);
}
void LoopVersioning::addPHINodes(