diff options
author | Alexander Musman <alexander.musman@gmail.com> | 2014-05-22 08:54:05 +0000 |
---|---|---|
committer | Alexander Musman <alexander.musman@gmail.com> | 2014-05-22 08:54:05 +0000 |
commit | 515ad8c490582d9b3b71274ed9255dc4a23c4610 (patch) | |
tree | 1e04ab0b2131931f706383edba46261e93c58fc4 /clang/lib/CodeGen/CGLoopInfo.cpp | |
parent | 5f3ea477cf3b48710a5ef839624606311f0c4ab7 (diff) | |
download | bcm5719-llvm-515ad8c490582d9b3b71274ed9255dc4a23c4610.tar.gz bcm5719-llvm-515ad8c490582d9b3b71274ed9255dc4a23c4610.zip |
This patch adds a helper class (CGLoopInfo) for marking memory instructions with llvm.mem.parallel_loop_access metadata.
It also adds a simple initial version of codegen for pragma omp simd (it will change in the future to support all the clauses).
Differential revision: http://reviews.llvm.org/D3644
llvm-svn: 209411
Diffstat (limited to 'clang/lib/CodeGen/CGLoopInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGLoopInfo.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp new file mode 100644 index 00000000000..7b154b2d27e --- /dev/null +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -0,0 +1,112 @@ +//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CGLoopInfo.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Metadata.h" +using namespace clang; +using namespace CodeGen; +using namespace llvm; + +static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { + + if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 && + Attrs.VectorizerUnroll == 0 && + Attrs.VectorizerEnable == LoopAttributes::VecUnspecified) + return nullptr; + + SmallVector<Value *, 4> Args; + // Reserve operand 0 for loop id self reference. + MDNode *TempNode = MDNode::getTemporary(Ctx, None); + Args.push_back(TempNode); + + // Setting vectorizer.width + if (Attrs.VectorizerWidth > 0) { + Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.width"), + ConstantInt::get(Type::getInt32Ty(Ctx), + Attrs.VectorizerWidth) }; + Args.push_back(MDNode::get(Ctx, Vals)); + } + + // Setting vectorizer.unroll + if (Attrs.VectorizerUnroll > 0) { + Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.unroll"), + ConstantInt::get(Type::getInt32Ty(Ctx), + Attrs.VectorizerUnroll) }; + Args.push_back(MDNode::get(Ctx, Vals)); + } + + // Setting vectorizer.enable + if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { + Value *Vals[] = { MDString::get(Ctx, "llvm.vectorizer.enable"), + ConstantInt::get(Type::getInt1Ty(Ctx), + (Attrs.VectorizerEnable == + LoopAttributes::VecEnable)) }; + Args.push_back(MDNode::get(Ctx, Vals)); + } + + MDNode *LoopID = MDNode::get(Ctx, Args); + assert(LoopID->use_empty() && "LoopID should not be used"); + + // Set the first operand to itself. + LoopID->replaceOperandWith(0, LoopID); + MDNode::deleteTemporary(TempNode); + return LoopID; +} + +LoopAttributes::LoopAttributes(bool IsParallel) + : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified), + VectorizerWidth(0), VectorizerUnroll(0) {} + +void LoopAttributes::clear() { + IsParallel = false; + VectorizerWidth = 0; + VectorizerUnroll = 0; + VectorizerEnable = LoopAttributes::VecUnspecified; +} + +LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) + : LoopID(nullptr), Header(Header), Attrs(Attrs) { + LoopID = createMetadata(Header->getContext(), Attrs); +} + +void LoopInfoStack::push(BasicBlock *Header) { + Active.push_back(LoopInfo(Header, StagedAttrs)); + // Clear the attributes so nested loops do not inherit them. + StagedAttrs.clear(); +} + +void LoopInfoStack::pop() { + assert(!Active.empty() && "No active loops to pop"); + Active.pop_back(); +} + +void LoopInfoStack::InsertHelper(Instruction *I) const { + if (!hasInfo()) + return; + + const LoopInfo &L = getInfo(); + if (!L.getLoopID()) + return; + + if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) { + for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i) + if (TI->getSuccessor(i) == L.getHeader()) { + TI->setMetadata("llvm.loop", L.getLoopID()); + break; + } + return; + } + + if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory()) + I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID()); +} |