Skip to content

Commit b06b15a

Browse files
committedJun 6, 2014
Adding a new #pragma for the vectorize and interleave optimization hints.
Patch thanks to Tyler Nowicki! llvm-svn: 210330
1 parent 909b749 commit b06b15a

15 files changed

+986
-93
lines changed
 

‎clang/include/clang/Basic/Attr.td

+50-3
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,53 @@ def MSVtorDisp : InheritableAttr {
17571757
let Documentation = [Undocumented];
17581758
}
17591759

1760-
def Unaligned : IgnoredAttr {
1761-
let Spellings = [Keyword<"__unaligned">];
1762-
}
1760+
def Unaligned : IgnoredAttr {
1761+
let Spellings = [Keyword<"__unaligned">];
1762+
}
1763+
1764+
def LoopHint : Attr {
1765+
/// vectorize: vectorizes loop operations if 'value != 0'.
1766+
/// vectorize_width: vectorize loop operations with width 'value'.
1767+
/// interleave: interleave multiple loop iterations if 'value != 0'.
1768+
/// interleave_count: interleaves 'value' loop interations.
1769+
1770+
/// FIXME: Add Pragma spelling to tablegen and
1771+
/// use it here.
1772+
let Spellings = [Keyword<"loop">];
1773+
1774+
/// State of the loop optimization specified by the spelling.
1775+
let Args = [EnumArgument<"Option", "OptionType",
1776+
["vectorize", "vectorize_width", "interleave", "interleave_count"],
1777+
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount"]>,
1778+
DefaultIntArgument<"Value", 1>];
1779+
1780+
let AdditionalMembers = [{
1781+
static StringRef getOptionName(int Option) {
1782+
switch(Option) {
1783+
case Vectorize: return "vectorize";
1784+
case VectorizeWidth: return "vectorize_width";
1785+
case Interleave: return "interleave";
1786+
case InterleaveCount: return "interleave_count";
1787+
}
1788+
llvm_unreachable("Unhandled LoopHint option.");
1789+
}
1790+
1791+
static StringRef getValueName(int Value) {
1792+
if (Value)
1793+
return "enable";
1794+
return "disable";
1795+
}
1796+
1797+
// FIXME: Modify pretty printer to print this pragma.
1798+
void print(raw_ostream &OS, const PrintingPolicy &Policy) const {
1799+
OS << "#pragma clang loop " << getOptionName(option) << "(";
1800+
if (option == VectorizeWidth || option == InterleaveCount)
1801+
OS << value;
1802+
else
1803+
OS << getValueName(value);
1804+
OS << ")\n";
1805+
}
1806+
}];
1807+
1808+
let Documentation = [Undocumented];
1809+
}

‎clang/include/clang/Basic/DiagnosticParseKinds.td

+10-6
Original file line numberDiff line numberDiff line change
@@ -889,12 +889,16 @@ def err_omp_unexpected_directive : Error<
889889
def err_omp_expected_punc : Error<
890890
"expected ',' or ')' in '%0' clause">;
891891
def err_omp_unexpected_clause : Error<
892-
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
893-
def err_omp_more_one_clause : Error<
894-
"directive '#pragma omp %0' cannot contain more than one '%1' clause">;
895-
} // end of Parse Issue category.
896-
897-
let CategoryName = "Modules Issue" in {
892+
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
893+
def err_omp_more_one_clause : Error<
894+
"directive '#pragma omp %0' cannot contain more than one '%1' clause">;
895+
896+
// Pragma loop support.
897+
def err_pragma_loop_invalid_option : Error<
898+
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, vectorize_width, interleave, or interleave_count">;
899+
} // end of Parse Issue category.
900+
901+
let CategoryName = "Modules Issue" in {
898902
def err_module_expected_ident : Error<
899903
"expected a module name after module import">;
900904
def err_module_expected_semi : Error<

‎clang/include/clang/Basic/DiagnosticSemaKinds.td

+15-6
Original file line numberDiff line numberDiff line change
@@ -539,12 +539,21 @@ def err_pragma_push_visibility_mismatch : Error<
539539
def note_surrounding_namespace_ends_here : Note<
540540
"surrounding namespace with visibility attribute ends here">;
541541
def err_pragma_pop_visibility_mismatch : Error<
542-
"#pragma visibility pop with no matching #pragma visibility push">;
543-
def note_surrounding_namespace_starts_here : Note<
544-
"surrounding namespace with visibility attribute starts here">;
545-
546-
/// Objective-C parser diagnostics
547-
def err_duplicate_class_def : Error<
542+
"#pragma visibility pop with no matching #pragma visibility push">;
543+
def note_surrounding_namespace_starts_here : Note<
544+
"surrounding namespace with visibility attribute starts here">;
545+
def err_pragma_loop_invalid_value : Error<
546+
"%select{invalid|missing}0 value%select{ %1|}0; expected a positive integer value">;
547+
def err_pragma_loop_invalid_keyword : Error<
548+
"%select{invalid|missing}0 keyword%select{ %1|}0; expected 'enable' or 'disable'">;
549+
def err_pragma_loop_compatibility : Error<
550+
"%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;
551+
def err_pragma_loop_precedes_nonloop : Error<
552+
"expected a for, while, or do-while loop to follow the '#pragma clang loop' "
553+
"directive">;
554+
555+
/// Objective-C parser diagnostics
556+
def err_duplicate_class_def : Error<
548557
"duplicate interface definition for class %0">;
549558
def err_undef_superclass : Error<
550559
"cannot find interface declaration for %0, superclass of %1">;

‎clang/include/clang/Basic/TokenKinds.def

+5
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,11 @@ ANNOTATION(pragma_opencl_extension)
701701
ANNOTATION(pragma_openmp)
702702
ANNOTATION(pragma_openmp_end)
703703

704+
// Annotations for loop pragma directives #pragma clang loop ...
705+
// The lexer produces these so that they only take effect when the parser
706+
// handles #pragma loop ... directives.
707+
ANNOTATION(pragma_loop_hint)
708+
704709
// Annotations for module import translated from #include etc.
705710
ANNOTATION(module_include)
706711
ANNOTATION(module_begin)

‎clang/include/clang/Parse/Parser.h

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "clang/Lex/CodeCompletionHandler.h"
2121
#include "clang/Lex/Preprocessor.h"
2222
#include "clang/Sema/DeclSpec.h"
23+
#include "clang/Sema/LoopHint.h"
2324
#include "clang/Sema/Sema.h"
2425
#include "llvm/ADT/SmallVector.h"
2526
#include "llvm/Support/Compiler.h"
@@ -161,6 +162,7 @@ class Parser : public CodeCompletionHandler {
161162
std::unique_ptr<PragmaHandler> MSCodeSeg;
162163
std::unique_ptr<PragmaHandler> MSSection;
163164
std::unique_ptr<PragmaHandler> OptimizeHandler;
165+
std::unique_ptr<PragmaHandler> LoopHintHandler;
164166

165167
std::unique_ptr<CommentHandler> CommentSemaHandler;
166168

@@ -519,6 +521,10 @@ class Parser : public CodeCompletionHandler {
519521
/// #pragma clang __debug captured
520522
StmtResult HandlePragmaCaptured();
521523

524+
/// \brief Handle the annotation token produced for
525+
/// #pragma vectorize...
526+
LoopHint HandlePragmaLoopHint();
527+
522528
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
523529
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
524530
/// returns the token after Tok, etc.
@@ -1601,6 +1607,9 @@ class Parser : public CodeCompletionHandler {
16011607
StmtResult ParseReturnStatement();
16021608
StmtResult ParseAsmStatement(bool &msAsm);
16031609
StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
1610+
StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
1611+
SourceLocation *TrailingElseLoc,
1612+
ParsedAttributesWithRange &Attrs);
16041613

16051614
/// \brief Describes the behavior that should be taken for an __if_exists
16061615
/// block.

‎clang/include/clang/Sema/LoopHint.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===--- LoopHint.h - Types for LoopHint ------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_CLANG_SEMA_LOOPHINT_H
11+
#define LLVM_CLANG_SEMA_LOOPHINT_H
12+
13+
#include "clang/Basic/IdentifierTable.h"
14+
#include "clang/Basic/SourceLocation.h"
15+
#include "clang/Sema/AttributeList.h"
16+
#include "clang/Sema/Ownership.h"
17+
18+
namespace clang {
19+
20+
/// \brief Loop hint specified by a pragma loop directive.
21+
struct LoopHint {
22+
SourceRange Range;
23+
Expr *ValueExpr;
24+
IdentifierLoc *LoopLoc;
25+
IdentifierLoc *ValueLoc;
26+
IdentifierLoc *OptionLoc;
27+
};
28+
29+
} // end namespace clang
30+
31+
#endif // LLVM_CLANG_SEMA_LOOPHINT_H

‎clang/lib/AST/StmtPrinter.cpp

+16-2
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,22 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
168168
}
169169

170170
void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
171-
for (const auto *Attr : Node->getAttrs())
172-
Attr->printPretty(OS, Policy);
171+
std::string raw_attr_os;
172+
llvm::raw_string_ostream AttrOS(raw_attr_os);
173+
for (const auto *Attr : Node->getAttrs()) {
174+
// FIXME: This hack will be removed when printPretty
175+
// has been modified to print pretty pragmas
176+
if (const LoopHintAttr *LHA = dyn_cast<LoopHintAttr>(Attr)) {
177+
LHA->print(OS, Policy);
178+
} else
179+
Attr->printPretty(AttrOS, Policy);
180+
}
181+
182+
// Print attributes after pragmas.
183+
StringRef AttrStr = AttrOS.str();
184+
if (!AttrStr.empty())
185+
OS << AttrStr;
186+
173187
PrintStmt(Node->getSubStmt(), 0);
174188
}
175189

0 commit comments

Comments
 (0)