1 //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CGLoopInfo.h"
11 #include "clang/AST/Attr.h"
12 #include "clang/Sema/LoopHint.h"
13 #include "llvm/IR/BasicBlock.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/InstrTypes.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/Metadata.h"
18 using namespace clang::CodeGen;
21 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) {
23 if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 &&
24 Attrs.VectorizerUnroll == 0 &&
25 Attrs.VectorizerEnable == LoopAttributes::VecUnspecified)
28 SmallVector<Metadata *, 4> Args;
29 // Reserve operand 0 for loop id self reference.
30 auto TempNode = MDNode::getTemporary(Ctx, None);
31 Args.push_back(TempNode.get());
33 // Setting vectorizer.width
34 if (Attrs.VectorizerWidth > 0) {
35 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
36 ConstantAsMetadata::get(ConstantInt::get(
37 Type::getInt32Ty(Ctx), Attrs.VectorizerWidth))};
38 Args.push_back(MDNode::get(Ctx, Vals));
41 // Setting vectorizer.unroll
42 if (Attrs.VectorizerUnroll > 0) {
43 Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
44 ConstantAsMetadata::get(ConstantInt::get(
45 Type::getInt32Ty(Ctx), Attrs.VectorizerUnroll))};
46 Args.push_back(MDNode::get(Ctx, Vals));
49 // Setting vectorizer.enable
50 if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) {
52 MDString::get(Ctx, "llvm.loop.vectorize.enable"),
53 ConstantAsMetadata::get(ConstantInt::get(
55 (Attrs.VectorizerEnable == LoopAttributes::VecEnable)))};
56 Args.push_back(MDNode::get(Ctx, Vals));
59 // Set the first operand to itself.
60 MDNode *LoopID = MDNode::get(Ctx, Args);
61 LoopID->replaceOperandWith(0, LoopID);
65 LoopAttributes::LoopAttributes(bool IsParallel)
66 : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
67 VectorizerWidth(0), VectorizerUnroll(0) {}
69 void LoopAttributes::clear() {
73 VectorizerEnable = LoopAttributes::VecUnspecified;
76 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
77 : LoopID(nullptr), Header(Header), Attrs(Attrs) {
78 LoopID = createMetadata(Header->getContext(), Attrs);
81 void LoopInfoStack::push(BasicBlock *Header,
82 ArrayRef<const clang::Attr *> Attrs) {
83 for (const auto *Attr : Attrs) {
84 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
86 // Skip non loop hint attributes
90 LoopHintAttr::OptionType Option = LH->getOption();
91 LoopHintAttr::LoopHintState State = LH->getState();
93 case LoopHintAttr::Vectorize:
94 case LoopHintAttr::Interleave:
95 if (State == LoopHintAttr::AssumeSafety) {
96 // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
100 case LoopHintAttr::VectorizeWidth:
101 case LoopHintAttr::InterleaveCount:
102 case LoopHintAttr::Unroll:
103 case LoopHintAttr::UnrollCount:
104 // Nothing to do here for these loop hints.
109 Active.push_back(LoopInfo(Header, StagedAttrs));
110 // Clear the attributes so nested loops do not inherit them.
114 void LoopInfoStack::pop() {
115 assert(!Active.empty() && "No active loops to pop");
119 void LoopInfoStack::InsertHelper(Instruction *I) const {
123 const LoopInfo &L = getInfo();
127 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
128 for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
129 if (TI->getSuccessor(i) == L.getHeader()) {
130 TI->setMetadata("llvm.loop", L.getLoopID());
136 if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
137 I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());