From: Mark Heffernan Date: Wed, 23 Jul 2014 17:31:37 +0000 (+0000) Subject: In unroll pragma syntax and loop hint metadata, change "enable" forms to a new form... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e8d7ebcd5a430a93952cd2a527de84abd501df22;p=oota-llvm.git In unroll pragma syntax and loop hint metadata, change "enable" forms to a new form using the string "full". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213772 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 34873e1f41d..885da869da3 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -2987,20 +2987,6 @@ identification metadata. The ``llvm.loop.unroll`` metadata are only optimization hints and the unrolling will only be performed if the optimizer believes it is safe to do so. -'``llvm.loop.unroll.enable``' Metadata -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This metadata either disables loop unrolling or suggests that the loop -be unrolled fully. The first operand is the string -``llvm.loop.unroll.enable`` and the second operand is a bit. If the -bit operand value is 0 loop unrolling is disabled. A value of 1 -indicates that the loop should be fully unrolled. For example: - -.. code-block:: llvm - - !0 = metadata !{ metadata !"llvm.loop.unroll.enable", i1 0 } - !1 = metadata !{ metadata !"llvm.loop.unroll.enable", i1 1 } - '``llvm.loop.unroll.count``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3016,12 +3002,26 @@ example: If the trip count of the loop is less than the unroll count the loop will be partially unrolled. -If a loop has both a ``llvm.loop.unroll.enable`` metadata and -``llvm.loop.unroll.count`` metadata the behavior depends upon the -value of the ``llvm.loop.unroll.enable`` operand. If the value is 0, -the loop will not be unrolled. If the value is 1, the loop will be -unrolled with a factor determined by the ``llvm.loop.unroll.count`` -operand effectively ignoring the ``llvm.loop.unroll.enable`` metadata. +'``llvm.loop.unroll.disable``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This metadata either disables loop unrolling. The metadata has a single operand +which is the string ``llvm.loop.unroll.disable``. For example: + +.. code-block:: llvm + + !0 = metadata !{ metadata !"llvm.loop.unroll.disable" } + +'``llvm.loop.unroll.full``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This metadata either suggests that the loop should be unrolled fully. The +metadata has a single operand which is the string ``llvm.loop.unroll.disable``. +For example: + +.. code-block:: llvm + + !0 = metadata !{ metadata !"llvm.loop.unroll.full" } '``llvm.mem``' ^^^^^^^^^^^^^^^ diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index 935f289f040..ff2b8ed267d 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -52,7 +52,7 @@ UnrollRuntime("unroll-runtime", cl::ZeroOrMore, cl::init(false), cl::Hidden, static cl::opt PragmaUnrollThreshold("pragma-unroll-threshold", cl::init(16 * 1024), cl::Hidden, - cl::desc("Unrolled size limit for loops with an unroll(enable) or " + cl::desc("Unrolled size limit for loops with an unroll(full) or " "unroll_count pragma.")); namespace { @@ -138,12 +138,11 @@ namespace { // SetExplicitly is set to true if the unroll count is is set by // the user or a pragma rather than selected heuristically. unsigned - selectUnrollCount(const Loop *L, unsigned TripCount, bool HasEnablePragma, + selectUnrollCount(const Loop *L, unsigned TripCount, bool PragmaFullUnroll, unsigned PragmaCount, const TargetTransformInfo::UnrollingPreferences &UP, bool &SetExplicitly); - // Select threshold values used to limit unrolling based on a // total unrolled size. Parameters Threshold and PartialThreshold // are set to the maximum unrolled size for fully and partially @@ -219,13 +218,13 @@ static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls, return LoopSize; } -// Returns the value associated with the given metadata node name (for -// example, "llvm.loop.unroll.count"). If no such named metadata node -// exists, then nullptr is returned. -static const ConstantInt *GetUnrollMetadataValue(const Loop *L, - StringRef Name) { +// Returns the loop hint metadata node with the given name (for example, +// "llvm.loop.unroll.count"). If no such metadata node exists, then nullptr is +// returned. +const MDNode *GetUnrollMetadata(const Loop *L, StringRef Name) { MDNode *LoopID = L->getLoopID(); - if (!LoopID) return nullptr; + if (!LoopID) + return nullptr; // First operand should refer to the loop id itself. assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); @@ -233,41 +232,37 @@ static const ConstantInt *GetUnrollMetadataValue(const Loop *L, for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) { const MDNode *MD = dyn_cast(LoopID->getOperand(i)); - if (!MD) continue; + if (!MD) + continue; const MDString *S = dyn_cast(MD->getOperand(0)); - if (!S) continue; + if (!S) + continue; - if (Name.equals(S->getString())) { - assert(MD->getNumOperands() == 2 && - "Unroll hint metadata should have two operands."); - return cast(MD->getOperand(1)); - } + if (Name.equals(S->getString())) + return MD; } return nullptr; } -// Returns true if the loop has an unroll(enable) pragma. -static bool HasUnrollEnablePragma(const Loop *L) { - const ConstantInt *EnableValue = - GetUnrollMetadataValue(L, "llvm.loop.unroll.enable"); - return (EnableValue && EnableValue->getZExtValue()); +// Returns true if the loop has an unroll(full) pragma. +static bool HasUnrollFullPragma(const Loop *L) { + return GetUnrollMetadata(L, "llvm.loop.unroll.full"); } // Returns true if the loop has an unroll(disable) pragma. static bool HasUnrollDisablePragma(const Loop *L) { - const ConstantInt *EnableValue = - GetUnrollMetadataValue(L, "llvm.loop.unroll.enable"); - return (EnableValue && !EnableValue->getZExtValue()); + return GetUnrollMetadata(L, "llvm.loop.unroll.disable"); } // If loop has an unroll_count pragma return the (necessarily // positive) value from the pragma. Otherwise return 0. static unsigned UnrollCountPragmaValue(const Loop *L) { - const ConstantInt *CountValue = - GetUnrollMetadataValue(L, "llvm.loop.unroll.count"); - if (CountValue) { - unsigned Count = CountValue->getZExtValue(); + const MDNode *MD = GetUnrollMetadata(L, "llvm.loop.unroll.count"); + if (MD) { + assert(MD->getNumOperands() == 2 && + "Unroll count hint metadata should have two operands."); + unsigned Count = cast(MD->getOperand(1))->getZExtValue(); assert(Count >= 1 && "Unroll count must be positive."); return Count; } @@ -298,9 +293,8 @@ static void SetLoopAlreadyUnrolled(Loop *L) { // Add unroll(disable) metadata to disable future unrolling. LLVMContext &Context = L->getHeader()->getContext(); - SmallVector DisableOperands; - DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.enable")); - DisableOperands.push_back(ConstantInt::get(Type::getInt1Ty(Context), 0)); + SmallVector DisableOperands; + DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable")); MDNode *DisableNode = MDNode::get(Context, DisableOperands); Vals.push_back(DisableNode); @@ -312,7 +306,7 @@ static void SetLoopAlreadyUnrolled(Loop *L) { } unsigned LoopUnroll::selectUnrollCount( - const Loop *L, unsigned TripCount, bool HasEnablePragma, + const Loop *L, unsigned TripCount, bool PragmaFullUnroll, unsigned PragmaCount, const TargetTransformInfo::UnrollingPreferences &UP, bool &SetExplicitly) { SetExplicitly = true; @@ -326,9 +320,7 @@ unsigned LoopUnroll::selectUnrollCount( if (Count == 0) { if (PragmaCount) { Count = PragmaCount; - } else if (HasEnablePragma) { - // unroll(enable) pragma without an unroll_count pragma - // indicates to unroll loop fully. + } else if (PragmaFullUnroll) { Count = TripCount; } } @@ -368,9 +360,9 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { if (HasUnrollDisablePragma(L)) { return false; } - bool HasEnablePragma = HasUnrollEnablePragma(L); + bool PragmaFullUnroll = HasUnrollFullPragma(L); unsigned PragmaCount = UnrollCountPragmaValue(L); - bool HasPragma = HasEnablePragma || PragmaCount > 0; + bool HasPragma = PragmaFullUnroll || PragmaCount > 0; TargetTransformInfo::UnrollingPreferences UP; getUnrollingPreferences(L, TTI, UP); @@ -390,8 +382,8 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { // Select an initial unroll count. This may be reduced later based // on size thresholds. bool CountSetExplicitly; - unsigned Count = selectUnrollCount(L, TripCount, HasEnablePragma, PragmaCount, - UP, CountSetExplicitly); + unsigned Count = selectUnrollCount(L, TripCount, PragmaFullUnroll, + PragmaCount, UP, CountSetExplicitly); unsigned NumInlineCandidates; bool notDuplicatable; @@ -474,16 +466,16 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { DebugLoc LoopLoc = L->getStartLoc(); Function *F = Header->getParent(); LLVMContext &Ctx = F->getContext(); - if (HasEnablePragma && PragmaCount == 0) { + if (PragmaFullUnroll && PragmaCount == 0) { if (TripCount && Count != TripCount) { emitOptimizationRemarkMissed( Ctx, DEBUG_TYPE, *F, LoopLoc, - "Unable to fully unroll loop as directed by unroll(enable) pragma " + "Unable to fully unroll loop as directed by unroll(full) pragma " "because unrolled size is too large."); } else if (!TripCount) { emitOptimizationRemarkMissed( Ctx, DEBUG_TYPE, *F, LoopLoc, - "Unable to fully unroll loop as directed by unroll(enable) pragma " + "Unable to fully unroll loop as directed by unroll(full) pragma " "because loop has a runtime trip count."); } } else if (PragmaCount > 0 && Count != OriginalCount) { diff --git a/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll b/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll index 39da7fa70ad..dcde9ebfbbf 100644 --- a/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll +++ b/test/Transforms/LoopUnroll/unroll-pragmas-disabled.ll @@ -6,9 +6,9 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -; #pragma clang loop vectorize(enable) unroll(enable) unroll_count(4) vectorize_width(8) +; #pragma clang loop vectorize(enable) unroll(full) unroll_count(4) vectorize_width(8) ; -; Unroll metadata should be replaces with unroll(disable). Vectorize +; Unroll metadata should be replaced with unroll(disable). Vectorize ; metadata should be untouched. ; ; CHECK-LABEL: @loop1( @@ -32,7 +32,7 @@ for.end: ; preds = %for.body } !1 = metadata !{metadata !1, metadata !2, metadata !3, metadata !4, metadata !5} !2 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true} -!3 = metadata !{metadata !"llvm.loop.unroll.enable", i1 true} +!3 = metadata !{metadata !"llvm.loop.unroll.full"} !4 = metadata !{metadata !"llvm.loop.unroll.count", i32 4} !5 = metadata !{metadata !"llvm.loop.vectorize.width", i32 8} @@ -60,10 +60,10 @@ for.end: ; preds = %for.body ret void } !6 = metadata !{metadata !6, metadata !7} -!7 = metadata !{metadata !"llvm.loop.unroll.enable", i1 false} +!7 = metadata !{metadata !"llvm.loop.unroll.disable"} ; CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[VEC_ENABLE:.*]], metadata ![[WIDTH_8:.*]], metadata ![[UNROLL_DISABLE:.*]]} ; CHECK: ![[VEC_ENABLE]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true} ; CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 8} -; CHECK: ![[UNROLL_DISABLE]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 false} +; CHECK: ![[UNROLL_DISABLE]] = metadata !{metadata !"llvm.loop.unroll.disable"} ; CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2]], metadata ![[UNROLL_DISABLE:.*]]} diff --git a/test/Transforms/LoopUnroll/unroll-pragmas.ll b/test/Transforms/LoopUnroll/unroll-pragmas.ll index e1b24e44b5a..1ca249d20c5 100644 --- a/test/Transforms/LoopUnroll/unroll-pragmas.ll +++ b/test/Transforms/LoopUnroll/unroll-pragmas.ll @@ -55,11 +55,11 @@ for.end: ; preds = %for.body ret void } !1 = metadata !{metadata !1, metadata !2} -!2 = metadata !{metadata !"llvm.loop.unroll.enable", i1 false} +!2 = metadata !{metadata !"llvm.loop.unroll.disable"} ; loop64 has a high enough count that it should *not* be unrolled by ; the default unrolling heuristic. It serves as the control for the -; unroll(enable) pragma test loop64_with_.* tests below. +; unroll(full) pragma test loop64_with_.* tests below. ; ; CHECK-LABEL: @loop64( ; CHECK: store i32 @@ -83,7 +83,7 @@ for.end: ; preds = %for.body ret void } -; #pragma clang loop unroll(enable) +; #pragma clang loop unroll(full) ; Loop should be fully unrolled. ; ; CHECK-LABEL: @loop64_with_enable( @@ -106,7 +106,7 @@ for.end: ; preds = %for.body ret void } !3 = metadata !{metadata !3, metadata !4} -!4 = metadata !{metadata !"llvm.loop.unroll.enable", i1 true} +!4 = metadata !{metadata !"llvm.loop.unroll.full"} ; #pragma clang loop unroll_count(4) ; Loop should be unrolled 4 times. @@ -138,37 +138,7 @@ for.end: ; preds = %for.body !5 = metadata !{metadata !5, metadata !6} !6 = metadata !{metadata !"llvm.loop.unroll.count", i32 4} - -; #pragma clang loop unroll_count(enable) unroll_count(4) -; Loop should be unrolled 4 times. -; -; CHECK-LABEL: @loop64_with_enable_and_count4( -; CHECK: store i32 -; CHECK: store i32 -; CHECK: store i32 -; CHECK: store i32 -; CHECK-NOT: store i32 -; CHECK: br i1 -define void @loop64_with_enable_and_count4(i32* nocapture %a) { -entry: - br label %for.body - -for.body: ; preds = %for.body, %entry - %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] - %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv - %0 = load i32* %arrayidx, align 4 - %inc = add nsw i32 %0, 1 - store i32 %inc, i32* %arrayidx, align 4 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %exitcond = icmp eq i64 %indvars.iv.next, 64 - br i1 %exitcond, label %for.end, label %for.body, !llvm.loop !7 - -for.end: ; preds = %for.body - ret void -} -!7 = metadata !{metadata !7, metadata !6, metadata !4} - -; #pragma clang loop unroll_count(enable) +; #pragma clang loop unroll(full) ; Full unrolling is requested, but loop has a dynamic trip count so ; no unrolling should occur. ; @@ -261,7 +231,7 @@ for.end: ; preds = %for.body !10 = metadata !{metadata !10, metadata !11} !11 = metadata !{metadata !"llvm.loop.unroll.count", i32 1} -; #pragma clang loop unroll(enable) +; #pragma clang loop unroll(full) ; Loop has very high loop count (1 million) and full unrolling was requested. ; Loop should unrolled up to the pragma threshold, but not completely. ;