|
@@ -107,6 +107,7 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
|
.Case("interleave_count", LoopHintAttr::InterleaveCount)
|
|
.Case("interleave_count", LoopHintAttr::InterleaveCount)
|
|
.Case("unroll", LoopHintAttr::Unroll)
|
|
.Case("unroll", LoopHintAttr::Unroll)
|
|
.Case("unroll_count", LoopHintAttr::UnrollCount)
|
|
.Case("unroll_count", LoopHintAttr::UnrollCount)
|
|
|
|
+ .Case("distribute", LoopHintAttr::Distribute)
|
|
.Default(LoopHintAttr::Vectorize);
|
|
.Default(LoopHintAttr::Vectorize);
|
|
if (Option == LoopHintAttr::VectorizeWidth ||
|
|
if (Option == LoopHintAttr::VectorizeWidth ||
|
|
Option == LoopHintAttr::InterleaveCount ||
|
|
Option == LoopHintAttr::InterleaveCount ||
|
|
@@ -117,7 +118,8 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
|
State = LoopHintAttr::Numeric;
|
|
State = LoopHintAttr::Numeric;
|
|
} else if (Option == LoopHintAttr::Vectorize ||
|
|
} else if (Option == LoopHintAttr::Vectorize ||
|
|
Option == LoopHintAttr::Interleave ||
|
|
Option == LoopHintAttr::Interleave ||
|
|
- Option == LoopHintAttr::Unroll) {
|
|
|
|
|
|
+ Option == LoopHintAttr::Unroll ||
|
|
|
|
+ Option == LoopHintAttr::Distribute) {
|
|
assert(StateLoc && StateLoc->Ident && "Loop hint must have an argument");
|
|
assert(StateLoc && StateLoc->Ident && "Loop hint must have an argument");
|
|
if (StateLoc->Ident->isStr("disable"))
|
|
if (StateLoc->Ident->isStr("disable"))
|
|
State = LoopHintAttr::Disable;
|
|
State = LoopHintAttr::Disable;
|
|
@@ -140,18 +142,21 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
|
static void
|
|
static void
|
|
CheckForIncompatibleAttributes(Sema &S,
|
|
CheckForIncompatibleAttributes(Sema &S,
|
|
const SmallVectorImpl<const Attr *> &Attrs) {
|
|
const SmallVectorImpl<const Attr *> &Attrs) {
|
|
- // There are 3 categories of loop hints attributes: vectorize, interleave,
|
|
|
|
- // and unroll. Each comes in two variants: a state form and a numeric form.
|
|
|
|
- // The state form selectively defaults/enables/disables the transformation
|
|
|
|
- // for the loop (for unroll, default indicates full unrolling rather than
|
|
|
|
- // enabling the transformation). The numeric form form provides an integer
|
|
|
|
- // hint (for example, unroll count) to the transformer. The following array
|
|
|
|
- // accumulates the hints encountered while iterating through the attributes
|
|
|
|
- // to check for compatibility.
|
|
|
|
|
|
+ // There are 4 categories of loop hints attributes: vectorize, interleave,
|
|
|
|
+ // unroll and distribute. Except for distribute they come in two variants: a
|
|
|
|
+ // state form and a numeric form. The state form selectively
|
|
|
|
+ // defaults/enables/disables the transformation for the loop (for unroll,
|
|
|
|
+ // default indicates full unrolling rather than enabling the transformation).
|
|
|
|
+ // The numeric form form provides an integer hint (for example, unroll count)
|
|
|
|
+ // to the transformer. The following array accumulates the hints encountered
|
|
|
|
+ // while iterating through the attributes to check for compatibility.
|
|
struct {
|
|
struct {
|
|
const LoopHintAttr *StateAttr;
|
|
const LoopHintAttr *StateAttr;
|
|
const LoopHintAttr *NumericAttr;
|
|
const LoopHintAttr *NumericAttr;
|
|
- } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
|
|
|
|
|
|
+ } HintAttrs[] = {{nullptr, nullptr},
|
|
|
|
+ {nullptr, nullptr},
|
|
|
|
+ {nullptr, nullptr},
|
|
|
|
+ {nullptr, nullptr}};
|
|
|
|
|
|
for (const auto *I : Attrs) {
|
|
for (const auto *I : Attrs) {
|
|
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
|
|
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
|
|
@@ -161,7 +166,7 @@ CheckForIncompatibleAttributes(Sema &S,
|
|
continue;
|
|
continue;
|
|
|
|
|
|
LoopHintAttr::OptionType Option = LH->getOption();
|
|
LoopHintAttr::OptionType Option = LH->getOption();
|
|
- enum { Vectorize, Interleave, Unroll } Category;
|
|
|
|
|
|
+ enum { Vectorize, Interleave, Unroll, Distribute } Category;
|
|
switch (Option) {
|
|
switch (Option) {
|
|
case LoopHintAttr::Vectorize:
|
|
case LoopHintAttr::Vectorize:
|
|
case LoopHintAttr::VectorizeWidth:
|
|
case LoopHintAttr::VectorizeWidth:
|
|
@@ -175,12 +180,17 @@ CheckForIncompatibleAttributes(Sema &S,
|
|
case LoopHintAttr::UnrollCount:
|
|
case LoopHintAttr::UnrollCount:
|
|
Category = Unroll;
|
|
Category = Unroll;
|
|
break;
|
|
break;
|
|
|
|
+ case LoopHintAttr::Distribute:
|
|
|
|
+ // Perform the check for duplicated 'distribute' hints.
|
|
|
|
+ Category = Distribute;
|
|
|
|
+ break;
|
|
};
|
|
};
|
|
|
|
|
|
auto &CategoryState = HintAttrs[Category];
|
|
auto &CategoryState = HintAttrs[Category];
|
|
const LoopHintAttr *PrevAttr;
|
|
const LoopHintAttr *PrevAttr;
|
|
if (Option == LoopHintAttr::Vectorize ||
|
|
if (Option == LoopHintAttr::Vectorize ||
|
|
- Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
|
|
|
|
|
|
+ Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
|
|
|
|
+ Option == LoopHintAttr::Distribute) {
|
|
// Enable|Disable|AssumeSafety hint. For example, vectorize(enable).
|
|
// Enable|Disable|AssumeSafety hint. For example, vectorize(enable).
|
|
PrevAttr = CategoryState.StateAttr;
|
|
PrevAttr = CategoryState.StateAttr;
|
|
CategoryState.StateAttr = LH;
|
|
CategoryState.StateAttr = LH;
|