summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGLoopInfo.cpp112
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 0000000..a273f1d
--- /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());
+}
OpenPOWER on IntegriCloud