Skip to content

Commit 4f64f1b

Browse files
author
Tim Corringham
committed
Add llvm.licm.disable metadata
For some targets the LICM pass can result in sub-optimal code in some cases where it would be better not to run the pass, but it isn't always possible to suppress the transformations heuristically. Where the front-end has insight into such cases it is beneficial to attach loop metadata to disable the pass - this change adds the llvm.licm.disable metadata to enable that. Differential Revision: https://reviews.llvm.org/D64557 llvm-svn: 368296
1 parent 195ae90 commit 4f64f1b

File tree

5 files changed

+63
-2
lines changed

5 files changed

+63
-2
lines changed

llvm/docs/LangRef.rst

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5381,7 +5381,7 @@ suggests an unroll factor to the loop unroller:
53815381
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53825382

53835383
This metadata disables all optional loop transformations unless
5384-
explicitly instructed using other transformation metdata such as
5384+
explicitly instructed using other transformation metadata such as
53855385
``llvm.loop.unroll.enable``. That is, no heuristic will try to determine
53865386
whether a transformation is profitable. The purpose is to avoid that the
53875387
loop is transformed to a different loop before an explicitly requested
@@ -5720,10 +5720,24 @@ the non-distributed fallback version will have. See
57205720
'``llvm.loop.distribute.followup_all``' Metadata
57215721
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57225722

5723-
Thes attributes in this metdata is added to all followup loops of the
5723+
The attributes in this metadata is added to all followup loops of the
57245724
loop distribution pass. See
57255725
:ref:`Transformation Metadata <transformation-metadata>` for details.
57265726

5727+
'``llvm.licm.disable``' Metadata
5728+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5729+
5730+
This metadata indicates that loop-invariant code motion (LICM) should not be
5731+
performed on this loop. The metadata has a single operand which is the string
5732+
``llvm.licm.disable``. For example:
5733+
5734+
.. code-block:: llvm
5735+
5736+
!0 = !{!"llvm.licm.disable"}
5737+
5738+
Note that although it operates per loop it isn't given the llvm.loop prefix
5739+
as it is not affected by the ``llvm.loop.disable_nonforced`` metadata.
5740+
57275741
'``llvm.access.group``' Metadata
57285742
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57295743

llvm/include/llvm/Transforms/Utils/LoopUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ makeFollowupLoopID(MDNode *OrigLoopID, ArrayRef<StringRef> FollowupAttrs,
215215
/// Look for the loop attribute that disables all transformation heuristic.
216216
bool hasDisableAllTransformsHint(const Loop *L);
217217

218+
/// Look for the loop attribute that disables the LICM transformation heuristics.
219+
bool hasDisableLICMTransformsHint(const Loop *L);
220+
218221
/// The mode sets how eager a transformation should be applied.
219222
enum TransformationMode {
220223
/// The pass can use heuristics to determine whether a transformation should

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ bool LoopInvariantCodeMotion::runOnLoop(
330330

331331
assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form.");
332332

333+
// If this loop has metadata indicating that LICM is not to be performed then
334+
// just exit.
335+
if (hasDisableLICMTransformsHint(L)) {
336+
return false;
337+
}
338+
333339
std::unique_ptr<AliasSetTracker> CurAST;
334340
std::unique_ptr<MemorySSAUpdater> MSSAU;
335341
bool NoOfMemAccTooLarge = false;

llvm/lib/Transforms/Utils/LoopUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ using namespace llvm::PatternMatch;
4545
#define DEBUG_TYPE "loop-utils"
4646

4747
static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
48+
static const char *LLVMLoopDisableLICM = "llvm.licm.disable";
4849

4950
bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
5051
MemorySSAUpdater *MSSAU,
@@ -379,6 +380,10 @@ bool llvm::hasDisableAllTransformsHint(const Loop *L) {
379380
return getBooleanLoopAttribute(L, LLVMLoopDisableNonforced);
380381
}
381382

383+
bool llvm::hasDisableLICMTransformsHint(const Loop *L) {
384+
return getBooleanLoopAttribute(L, LLVMLoopDisableLICM);
385+
}
386+
382387
TransformationMode llvm::hasUnrollTransformation(Loop *L) {
383388
if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable"))
384389
return TM_SuppressedByUser;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: opt < %s -S -basicaa -licm | FileCheck %s
2+
3+
; Check that the LICM pass does not operate on a loop which has the
4+
; llvm.licm.disable metadata.
5+
; CHECK-LABEL: @licm_disable
6+
; CHECK: entry:
7+
; CHECK-NOT: load
8+
; CHECK: do.body:
9+
; CHECK: load i64, i64* bitcast (i32** @in to i64*)
10+
11+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
12+
target triple = "x86_64-pc-windows-msvc"
13+
14+
@in = internal unnamed_addr global i32* null, align 8
15+
@out = internal unnamed_addr global i32* null, align 8
16+
17+
define void @licm_disable(i32 %N) {
18+
entry:
19+
br label %do.body
20+
21+
do.body: ; preds = %entry
22+
%i.0 = phi i32 [ 0, %entry ], [ %inc, %do.body ]
23+
%v1 = load i64, i64* bitcast (i32** @in to i64*), align 8
24+
store i64 %v1, i64* bitcast (i32** @out to i64*), align 8
25+
%inc = add nsw i32 %i.0, 1
26+
%cmp = icmp slt i32 %inc, %N
27+
br i1 %cmp, label %do.body, label %do.end, !llvm.loop !1
28+
29+
do.end: ; preds = %do.body
30+
ret void
31+
}
32+
!1 = !{!1, !2}
33+
!2 = !{!"llvm.licm.disable"}

0 commit comments

Comments
 (0)