diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGLoopInfo.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGLoopInfo.h | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmtAttr.cpp | 4 |
5 files changed, 46 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 0675544bedf..3254fb81dcc 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "CGLoopInfo.h" +#include "clang/AST/Attr.h" +#include "clang/Sema/LoopHint.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/InstrTypes.h" @@ -76,7 +78,33 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) LoopID = createMetadata(Header->getContext(), Attrs); } -void LoopInfoStack::push(BasicBlock *Header) { +void LoopInfoStack::push(BasicBlock *Header, ArrayRef<const Attr *> Attrs) { + for (const auto *Attr : Attrs) { + const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr); + + // Skip non loop hint attributes + if (!LH) + continue; + + LoopHintAttr::OptionType Option = LH->getOption(); + LoopHintAttr::LoopHintState State = LH->getState(); + switch (Option) { + case LoopHintAttr::Vectorize: + case LoopHintAttr::Interleave: + if (State == LoopHintAttr::AssumeSafety) { + // Apply "llvm.mem.parallel_loop_access" metadata to load/stores. + setParallel(true); + } + break; + case LoopHintAttr::VectorizeWidth: + case LoopHintAttr::InterleaveCount: + case LoopHintAttr::Unroll: + case LoopHintAttr::UnrollCount: + // Nothing to do here for these loop hints. + break; + } + } + Active.push_back(LoopInfo(Header, StagedAttrs)); // Clear the attributes so nested loops do not inherit them. StagedAttrs.clear(); diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index aee162118a2..2249937cd0d 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H #define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/Value.h" @@ -27,6 +28,7 @@ class MDNode; } // end namespace llvm namespace clang { +class Attr; namespace CodeGen { /// \brief Attributes that may be specified on loops. @@ -86,7 +88,8 @@ public: /// \brief Begin a new structured loop. The set of staged attributes will be /// applied to the loop and then cleared. - void push(llvm::BasicBlock *Header); + void push(llvm::BasicBlock *Header, + llvm::ArrayRef<const Attr *> Attrs = llvm::None); /// \brief End the current loop. void pop(); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 744c61384c8..57f55aacfa6 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -682,7 +682,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); EmitBlock(LoopHeader.getBlock()); - LoopStack.push(LoopHeader.getBlock()); + LoopStack.push(LoopHeader.getBlock(), WhileAttrs); // Create an exit block for when the condition fails, which will // also become the break target. @@ -776,7 +776,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, // Emit the body of the loop. llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); - LoopStack.push(LoopBody); + LoopStack.push(LoopBody, DoAttrs); EmitBlockWithFallThrough(LoopBody, &S); { @@ -842,7 +842,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, llvm::BasicBlock *CondBlock = Continue.getBlock(); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, ForAttrs); // If the for loop doesn't have an increment we can just use the // condition as the continue block. Otherwise we'll need to create @@ -940,7 +940,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, ForAttrs); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 84256dfd8e3..892d3c6a52c 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -823,9 +823,11 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { ConsumeToken(); // The annotation token. SourceLocation StateLoc = Toks[0].getLocation(); IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo(); - if (!StateInfo || ((OptionUnroll ? !StateInfo->isStr("full") - : !StateInfo->isStr("enable")) && - !StateInfo->isStr("disable"))) { + if (!StateInfo || + ((OptionUnroll ? !StateInfo->isStr("full") + : !StateInfo->isStr("enable") && + !StateInfo->isStr("assume_safety")) && + !StateInfo->isStr("disable"))) { Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword) << /*FullKeyword=*/OptionUnroll; return false; @@ -1954,6 +1956,7 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, /// loop-hint-keyword: /// 'enable' /// 'disable' +/// 'assume_safety' /// /// unroll-hint-keyword: /// 'full' diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 19e2c8ed652..5b71c11b529 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -105,6 +105,8 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, if (StateLoc && StateLoc->Ident) { if (StateLoc->Ident->isStr("disable")) State = LoopHintAttr::Disable; + else if (StateLoc->Ident->isStr("assume_safety")) + State = LoopHintAttr::AssumeSafety; else State = LoopHintAttr::Enable; } @@ -159,7 +161,7 @@ CheckForIncompatibleAttributes(Sema &S, const LoopHintAttr *PrevAttr; if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) { - // Enable|disable hint. For example, vectorize(enable). + // Enable|Disable|AssumeSafety hint. For example, vectorize(enable). PrevAttr = CategoryState.StateAttr; CategoryState.StateAttr = LH; } else { |