Skip to content

Commit

Permalink
New Loop Versioning LICM Pass
Browse files Browse the repository at this point in the history
Summary:
When alias analysis is uncertain about the aliasing between any two accesses,
it will return MayAlias. This uncertainty from alias analysis restricts LICM
from proceeding further. In cases where alias analysis is uncertain we might
use loop versioning as an alternative.

Loop Versioning will create a version of the loop with aggressive aliasing
assumptions in addition to the original with conservative (default) aliasing
assumptions. The version of the loop making aggressive aliasing assumptions
will have all the memory accesses marked as no-alias. These two versions of
loop will be preceded by a memory runtime check. This runtime check consists
of bound checks for all unique memory accessed in loop, and it ensures the
lack of memory aliasing. The result of the runtime check determines which of
the loop versions is executed: If the runtime check detects any memory
aliasing, then the original loop is executed. Otherwise, the version with
aggressive aliasing assumptions is used.

The pass is off by default and can be enabled with command line option 
-enable-loop-versioning-licm.

Reviewers: hfinkel, anemet, chatur01, reames

Subscribers: MatzeB, grosser, joker.eph, sanjoy, javed.absar, sbaranga,
             llvm-commits

Differential Revision: http://reviews.llvm.org/D9151

llvm-svn: 259986
  • Loading branch information
nema-ashutosh committed Feb 6, 2016
1 parent 0572837 commit df6763a
Show file tree
Hide file tree
Showing 12 changed files with 824 additions and 0 deletions.
11 changes: 11 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -4554,6 +4554,17 @@ For example:
!0 = !{!"llvm.loop.unroll.full"}
'``llvm.loop.licm_versioning.disable``' Metadata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This metadata indicates that the loop should not be versioned for the purpose
of enabling loop-invariant code motion (LICM). The metadata has a single operand
which is the string ``llvm.loop.licm_versioning.disable``. For example:

.. code-block:: llvm
!0 = !{!"llvm.loop.licm_versioning.disable"}
'``llvm.mem``'
^^^^^^^^^^^^^^^

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/InitializePasses.h
Expand Up @@ -176,6 +176,7 @@ void initializeGlobalMergePass(PassRegistry&);
void initializeLoopRerollPass(PassRegistry&);
void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&);
void initializeLoopVersioningLICMPass(PassRegistry&);
void initializeLoopIdiomRecognizePass(PassRegistry&);
void initializeLowerAtomicPass(PassRegistry&);
void initializeLowerBitSetsPass(PassRegistry&);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/LinkAllPasses.h
Expand Up @@ -111,6 +111,7 @@ namespace {
(void) llvm::createLoopRerollPass();
(void) llvm::createLoopUnrollPass();
(void) llvm::createLoopUnswitchPass();
(void) llvm::createLoopVersioningLICMPass();
(void) llvm::createLoopIdiomPass();
(void) llvm::createLoopRotatePass();
(void) llvm::createLowerExpectIntrinsicPass();
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/Transforms/Scalar.h
Expand Up @@ -193,6 +193,12 @@ Pass *createLoopRotatePass(int MaxHeaderSize = -1);
//
Pass *createLoopIdiomPass();

//===----------------------------------------------------------------------===//
//
// LoopVersioningLICM - This pass is a loop versioning pass for LICM.
//
Pass *createLoopVersioningLICMPass();

//===----------------------------------------------------------------------===//
//
// PromoteMemoryToRegister - This pass is used to promote memory references to
Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/Transforms/Utils/LoopUtils.h
Expand Up @@ -377,6 +377,14 @@ void computeLICMSafetyInfo(LICMSafetyInfo *, Loop *);

/// \brief Returns the instructions that use values defined in the loop.
SmallVector<Instruction *, 8> findDefsUsedOutsideOfLoop(Loop *L);

/// \brief Check string metadata into loop, if it exist return true,
/// else return false.
bool checkStringMetadataIntoLoop(Loop *TheLoop, StringRef Name);

/// \brief Set input string into loop metadata by keeping other values intact.
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
unsigned V = 0);
}

#endif
14 changes: 14 additions & 0 deletions llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
Expand Up @@ -116,6 +116,10 @@ static cl::opt<std::string> RunPGOInstrUse(
cl::desc("Enable use phase of PGO instrumentation and specify the path "
"of profile data file"));

static cl::opt<bool> UseLoopVersioningLICM(
"enable-loop-versioning-licm", cl::init(false), cl::Hidden,
cl::desc("Enable the experimental Loop Versioning LICM pass"));

PassManagerBuilder::PassManagerBuilder() {
OptLevel = 2;
SizeLevel = 0;
Expand Down Expand Up @@ -375,6 +379,16 @@ void PassManagerBuilder::populateModulePassManager(
// we must insert a no-op module pass to reset the pass manager.
MPM.add(createBarrierNoopPass());

// Scheduling LoopVersioningLICM when inining is over, because after that
// we may see more accurate aliasing. Reason to run this late is that too
// early versioning may prevent further inlining due to increase of code
// size. By placing it just after inlining other optimizations which runs
// later might get benefit of no-alias assumption in clone loop.
if (UseLoopVersioningLICM) {
MPM.add(createLoopVersioningLICMPass()); // Do LoopVersioningLICM
MPM.add(createLICMPass()); // Hoist loop invariants
}

if (!DisableUnitAtATime)
MPM.add(createReversePostOrderFunctionAttrsPass());

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Scalar/CMakeLists.txt
Expand Up @@ -28,6 +28,7 @@ add_llvm_library(LLVMScalarOpts
LoopStrengthReduce.cpp
LoopUnrollPass.cpp
LoopUnswitch.cpp
LoopVersioningLICM.cpp
LowerAtomic.cpp
LowerExpectIntrinsic.cpp
MemCpyOptimizer.cpp
Expand Down

0 comments on commit df6763a

Please sign in to comment.