SjoerdMeijer updated this revision to Diff 210314.
SjoerdMeijer retitled this revision from "Loop #pragma tail_predicate" to "
#pragma clang loop predicate(enable|disable)".
SjoerdMeijer edited the summary of this revision.
Herald added a subscriber: zzheng.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64744/new/
https://reviews.llvm.org/D64744
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/CodeGen/CGLoopInfo.cpp
clang/lib/CodeGen/CGLoopInfo.h
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/SemaStmtAttr.cpp
clang/test/AST/ast-print-pragmas.cpp
clang/test/CodeGenCXX/pragma-loop.cpp
clang/test/Parser/pragma-loop.cpp
clang/test/Parser/pragma-unroll-and-jam.cpp
Index: clang/test/Parser/pragma-unroll-and-jam.cpp
===================================================================
--- clang/test/Parser/pragma-unroll-and-jam.cpp
+++ clang/test/Parser/pragma-unroll-and-jam.cpp
@@ -67,7 +67,7 @@
}
// pragma clang unroll_and_jam is disabled for the moment
-/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop unroll_and_jam(4)
+/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, predicate, or distribute}} */ #pragma clang loop unroll_and_jam(4)
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
List[i * Length + j] = Value;
Index: clang/test/Parser/pragma-loop.cpp
===================================================================
--- clang/test/Parser/pragma-loop.cpp
+++ clang/test/Parser/pragma-loop.cpp
@@ -81,6 +81,7 @@
#pragma clang loop vectorize(enable)
#pragma clang loop interleave(enable)
+#pragma clang loop predicate(enable)
#pragma clang loop unroll(full)
while (i + 1 < Length) {
List[i] = i;
@@ -95,6 +96,7 @@
#pragma clang loop vectorize(disable)
#pragma clang loop interleave(disable)
+#pragma clang loop predicate(disable)
#pragma clang loop unroll(disable)
while (i - 1 < Length) {
List[i] = i;
@@ -111,7 +113,7 @@
}
int VList[Length];
-#pragma clang loop vectorize(disable) interleave(disable) unroll(disable)
+#pragma clang loop vectorize(disable) interleave(disable) unroll(disable) predicate(disable)
for (int j : VList) {
VList[j] = List[j];
}
@@ -130,11 +132,13 @@
/* expected-error {{expected '('}} */ #pragma clang loop vectorize
/* expected-error {{expected '('}} */ #pragma clang loop interleave
+/* expected-error {{expected '('}} */ #pragma clang loop predicate
/* expected-error {{expected '('}} */ #pragma clang loop unroll
/* expected-error {{expected '('}} */ #pragma clang loop distribute
/* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable
/* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop predicate(enable
/* expected-error {{expected ')'}} */ #pragma clang loop unroll(full
/* expected-error {{expected ')'}} */ #pragma clang loop distribute(enable
@@ -147,7 +151,7 @@
/* expected-error {{missing argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll()
/* expected-error {{missing argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute()
-/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop
+/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, predicate, or distribute}} */ #pragma clang loop
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
@@ -245,6 +249,8 @@
/* expected-error {{duplicate directives 'vectorize(enable)' and 'vectorize(disable)'}} */ #pragma clang loop vectorize(disable)
#pragma clang loop interleave(enable)
/* expected-error {{duplicate directives 'interleave(enable)' and 'interleave(disable)'}} */ #pragma clang loop interleave(disable)
+#pragma clang loop predicate(enable)
+/* expected-error {{duplicate directives 'predicate(enable)' and 'predicate(disable)'}} */ #pragma clang loop predicate(disable)
#pragma clang loop unroll(full)
/* expected-error {{duplicate directives 'unroll(full)' and 'unroll(disable)'}} */ #pragma clang loop unroll(disable)
#pragma clang loop distribute(enable)
@@ -281,3 +287,7 @@
#pragma clang loop interleave(enable)
/* expected-error {{expected statement}} */ }
+
+void foo(void) {
+#pragma clang loop predicate(enable)
+/* expected-error {{expected statement}} */ }
Index: clang/test/CodeGenCXX/pragma-loop.cpp
===================================================================
--- clang/test/CodeGenCXX/pragma-loop.cpp
+++ clang/test/CodeGenCXX/pragma-loop.cpp
@@ -10,6 +10,7 @@
#pragma clang loop vectorize_width(4)
#pragma clang loop unroll(full)
#pragma clang loop distribute(enable)
+#pragma clang loop predicate(enable)
while (i < Length) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
List[i] = i * 2;
@@ -56,7 +57,7 @@
// Verify disable pragma clang loop directive generates correct metadata
void disable_test(int *List, int Length) {
-#pragma clang loop vectorize(disable) unroll(disable) distribute(disable)
+#pragma clang loop vectorize(disable) unroll(disable) distribute(disable) predicate(disable)
for (int i = 0; i < Length; i++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
List[i] = i * 2;
@@ -158,8 +159,11 @@
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
-// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
+// CHECK: !2 = distinct !{!2, !3, !5}
+// CHECK !3 = distinct !{!3, !4]}
+// CHECK: !4 = !{!"llvm.loop.predicate"}
+// CHECK-NOT: !{!"llvm.loop.predicate"}
+// CHECK: !5 = !{!"llvm.loop.unroll.full"}
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
Index: clang/test/AST/ast-print-pragmas.cpp
===================================================================
--- clang/test/AST/ast-print-pragmas.cpp
+++ clang/test/AST/ast-print-pragmas.cpp
@@ -17,10 +17,12 @@
// CHECK: #pragma clang loop distribute(disable)
// CHECK-NEXT: #pragma clang loop vectorize(enable)
// CHECK-NEXT: #pragma clang loop interleave(disable)
+// CHECK-NEXT: #pragma clang loop predicate(disable)
#pragma clang loop distribute(disable)
#pragma clang loop vectorize(enable)
#pragma clang loop interleave(disable)
+#pragma clang loop predicate(disable)
// CHECK-NEXT: while (i - 1 < Length)
while (i - 1 < Length) {
List[i] = i * 2;
@@ -30,10 +32,12 @@
// CHECK: #pragma clang loop distribute(enable)
// CHECK-NEXT: #pragma clang loop vectorize(disable)
// CHECK-NEXT: #pragma clang loop interleave(enable)
+// CHECK-NEXT: #pragma clang loop predicate(enable)
#pragma clang loop distribute(enable)
#pragma clang loop vectorize(disable)
#pragma clang loop interleave(enable)
+#pragma clang loop predicate(enable)
// CHECK-NEXT: while (i - 2 < Length)
while (i - 2 < Length) {
List[i] = i * 2;
Index: clang/lib/Sema/SemaStmtAttr.cpp
===================================================================
--- clang/lib/Sema/SemaStmtAttr.cpp
+++ clang/lib/Sema/SemaStmtAttr.cpp
@@ -133,6 +133,7 @@
.Case("vectorize", LoopHintAttr::Vectorize)
.Case("vectorize_width", LoopHintAttr::VectorizeWidth)
.Case("interleave", LoopHintAttr::Interleave)
+ .Case("predicate", LoopHintAttr::Predicate)
.Case("interleave_count", LoopHintAttr::InterleaveCount)
.Case("unroll", LoopHintAttr::Unroll)
.Case("unroll_count", LoopHintAttr::UnrollCount)
@@ -151,6 +152,7 @@
State = LoopHintAttr::Numeric;
} else if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave ||
+ Option == LoopHintAttr::Predicate ||
Option == LoopHintAttr::Unroll ||
Option == LoopHintAttr::Distribute ||
Option == LoopHintAttr::PipelineDisabled) {
@@ -189,7 +191,8 @@
const LoopHintAttr *StateAttr;
const LoopHintAttr *NumericAttr;
} HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
- {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
+ {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
+ {nullptr, nullptr}};
for (const auto *I : Attrs) {
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
@@ -205,7 +208,8 @@
Unroll,
UnrollAndJam,
Distribute,
- Pipeline
+ Pipeline,
+ Predicate
} Category;
switch (Option) {
case LoopHintAttr::Vectorize:
@@ -232,6 +236,9 @@
case LoopHintAttr::PipelineInitiationInterval:
Category = Pipeline;
break;
+ case LoopHintAttr::Predicate:
+ Category = Predicate;
+ break;
};
assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0]));
@@ -240,6 +247,7 @@
if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
Option == LoopHintAttr::UnrollAndJam ||
+ Option == LoopHintAttr::Predicate ||
Option == LoopHintAttr::PipelineDisabled ||
Option == LoopHintAttr::Distribute) {
// Enable|Disable|AssumeSafety hint. For example, vectorize(enable).
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -1071,6 +1071,7 @@
StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
.Case("vectorize", true)
.Case("interleave", true)
+ .Case("predicate", true)
.Default(false) ||
OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
OptionPipelineDisabled;
@@ -2823,6 +2824,7 @@
/// loop-hint:
/// 'vectorize' '(' loop-hint-keyword ')'
/// 'interleave' '(' loop-hint-keyword ')'
+/// 'predicate' '(' loop-hint-keyword ')'
/// 'unroll' '(' unroll-hint-keyword ')'
/// 'vectorize_width' '(' loop-hint-value ')'
/// 'interleave_count' '(' loop-hint-value ')'
@@ -2883,6 +2885,7 @@
bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
.Case("vectorize", true)
.Case("interleave", true)
+ .Case("predicate", true)
.Case("unroll", true)
.Case("distribute", true)
.Case("vectorize_width", true)
Index: clang/lib/CodeGen/CGLoopInfo.h
===================================================================
--- clang/lib/CodeGen/CGLoopInfo.h
+++ clang/lib/CodeGen/CGLoopInfo.h
@@ -51,6 +51,9 @@
/// Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
LVEnableState UnrollAndJamEnable;
+ /// Value for llvm.loop.predicate metadata
+ LVEnableState PredicateEnable;
+
/// Value for llvm.loop.vectorize.width metadata.
unsigned VectorizeWidth;
@@ -162,6 +165,11 @@
createFullUnrollMetadata(const LoopAttributes &Attrs,
llvm::ArrayRef<llvm::Metadata *> LoopProperties,
bool &HasUserTransforms);
+
+ llvm::MDNode *
+ createPredicateMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
/// @}
/// Create a LoopID for this loop, including transformation-unspecific
@@ -237,6 +245,12 @@
StagedAttrs.UnrollEnable = State;
}
+
+ void setPredicateState(const LoopAttributes::LVEnableState &State) {
+ StagedAttrs.PredicateEnable = State;
+ }
+
+
/// Set the next pushed loop unroll_and_jam state.
void setUnrollAndJamState(const LoopAttributes::LVEnableState &State) {
StagedAttrs.UnrollAndJamEnable = State;
Index: clang/lib/CodeGen/CGLoopInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGLoopInfo.cpp
+++ clang/lib/CodeGen/CGLoopInfo.cpp
@@ -342,6 +342,22 @@
return LoopID;
}
+MDNode *LoopInfo::createPredicateMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ if (Attrs.PredicateEnable != LoopAttributes::Enable)
+ return nullptr;
+
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.predicate")));
+ LoopProperties = NewLoopProperties;
+ return createLoopPropertiesMetadata(LoopProperties);
+}
+
MDNode *LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs,
ArrayRef<Metadata *> LoopProperties,
bool &HasUserTransforms) {
@@ -405,13 +421,19 @@
LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(),
AdditionalLoopProperties.end());
+
+ MDNode *N = createPredicateMetadata(Attrs, LoopProperties, HasUserTransforms);
+ if(N)
+ LoopProperties.push_back(N);
+
return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
}
LoopAttributes::LoopAttributes(bool IsParallel)
: IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
UnrollEnable(LoopAttributes::Unspecified),
- UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
+ UnrollAndJamEnable(LoopAttributes::Unspecified),
+ PredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
PipelineInitiationInterval(0) {}
@@ -425,6 +447,7 @@
VectorizeEnable = LoopAttributes::Unspecified;
UnrollEnable = LoopAttributes::Unspecified;
UnrollAndJamEnable = LoopAttributes::Unspecified;
+ PredicateEnable = LoopAttributes::Unspecified;
DistributeEnable = LoopAttributes::Unspecified;
PipelineDisabled = false;
PipelineInitiationInterval = 0;
@@ -446,6 +469,7 @@
Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
Attrs.PipelineInitiationInterval == 0 &&
+ Attrs.PredicateEnable == LoopAttributes::Unspecified &&
Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
@@ -480,6 +504,7 @@
BeforeJam.InterleaveCount = Attrs.InterleaveCount;
BeforeJam.VectorizeEnable = Attrs.VectorizeEnable;
BeforeJam.DistributeEnable = Attrs.DistributeEnable;
+ BeforeJam.PredicateEnable = Attrs.PredicateEnable;
switch (Attrs.UnrollEnable) {
case LoopAttributes::Unspecified:
@@ -495,6 +520,7 @@
break;
}
+ AfterJam.PredicateEnable = Attrs.PredicateEnable;
AfterJam.UnrollCount = Attrs.UnrollCount;
AfterJam.PipelineDisabled = Attrs.PipelineDisabled;
AfterJam.PipelineInitiationInterval = Attrs.PipelineInitiationInterval;
@@ -516,6 +542,7 @@
// add it manually.
SmallVector<Metadata *, 1> BeforeLoopProperties;
if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified ||
+ BeforeJam.PredicateEnable != LoopAttributes::Unspecified ||
BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0)
BeforeLoopProperties.push_back(
MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
@@ -603,6 +630,9 @@
case LoopHintAttr::UnrollAndJam:
setUnrollAndJamState(LoopAttributes::Disable);
break;
+ case LoopHintAttr::Predicate:
+ setPredicateState(LoopAttributes::Disable);
+ break;
case LoopHintAttr::Distribute:
setDistributeState(false);
break;
@@ -630,6 +660,9 @@
case LoopHintAttr::UnrollAndJam:
setUnrollAndJamState(LoopAttributes::Enable);
break;
+ case LoopHintAttr::Predicate:
+ setPredicateState(LoopAttributes::Enable);
+ break;
case LoopHintAttr::Distribute:
setDistributeState(true);
break;
@@ -653,6 +686,7 @@
break;
case LoopHintAttr::Unroll:
case LoopHintAttr::UnrollAndJam:
+ case LoopHintAttr::Predicate:
case LoopHintAttr::UnrollCount:
case LoopHintAttr::UnrollAndJamCount:
case LoopHintAttr::VectorizeWidth:
@@ -681,6 +715,7 @@
case LoopHintAttr::Distribute:
case LoopHintAttr::PipelineDisabled:
case LoopHintAttr::PipelineInitiationInterval:
+ case LoopHintAttr::Predicate:
llvm_unreachable("Options cannot be used with 'full' hint.");
break;
}
@@ -704,6 +739,7 @@
break;
case LoopHintAttr::Unroll:
case LoopHintAttr::UnrollAndJam:
+ case LoopHintAttr::Predicate:
case LoopHintAttr::Vectorize:
case LoopHintAttr::Interleave:
case LoopHintAttr::Distribute:
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1210,7 +1210,7 @@
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
"vectorize_width, interleave, interleave_count, unroll, unroll_count, "
- "pipeline, pipeline_initiation_interval, or distribute">;
+ "pipeline, pipeline_initiation_interval, predicate, or distribute">;
def err_pragma_fp_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2981,10 +2981,10 @@
let Args = [EnumArgument<"Option", "OptionType",
["vectorize", "vectorize_width", "interleave", "interleave_count",
"unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
- "pipeline", "pipeline_initiation_interval", "distribute"],
+ "pipeline", "pipeline_initiation_interval", "distribute", "predicate"],
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
"Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
- "PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>,
+ "PipelineDisabled", "PipelineInitiationInterval", "Distribute", "Predicate"]>,
EnumArgument<"State", "LoopHintState",
["enable", "disable", "numeric", "assume_safety", "full"],
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
@@ -3004,6 +3004,7 @@
case PipelineDisabled: return "pipeline";
case PipelineInitiationInterval: return "pipeline_initiation_interval";
case Distribute: return "distribute";
+ case Predicate: return "predicate";
}
llvm_unreachable("Unhandled LoopHint option.");
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits