diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp | 112 | 
1 files changed, 112 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp new file mode 100644 index 000000000000..a273f1d4dda8 --- /dev/null +++ b/contrib/llvm/tools/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.loop.vectorize.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.loop.interleave.count"), +                      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.loop.vectorize.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()); +}  | 
