14 #include "llvm/IR/BasicBlock.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/InstrTypes.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Metadata.h"
19 using namespace clang::CodeGen;
23 const llvm::DebugLoc &StartLoc,
24 const llvm::DebugLoc &EndLoc) {
36 auto TempNode = MDNode::getTemporary(Ctx, None);
37 Args.push_back(TempNode.get());
41 Args.push_back(StartLoc.getAsMDNode());
45 Args.push_back(EndLoc.getAsMDNode());
50 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.vectorize.width"),
51 ConstantAsMetadata::get(ConstantInt::get(
53 Args.push_back(MDNode::get(Ctx, Vals));
58 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.interleave.count"),
59 ConstantAsMetadata::get(ConstantInt::get(
61 Args.push_back(MDNode::get(Ctx, Vals));
66 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.count"),
67 ConstantAsMetadata::get(ConstantInt::get(
69 Args.push_back(MDNode::get(Ctx, Vals));
74 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.vectorize.enable"),
75 ConstantAsMetadata::get(ConstantInt::get(
78 Args.push_back(MDNode::get(Ctx, Vals));
85 Name =
"llvm.loop.unroll.enable";
87 Name =
"llvm.loop.unroll.full";
89 Name =
"llvm.loop.unroll.disable";
90 Metadata *Vals[] = {MDString::get(Ctx, Name)};
91 Args.push_back(MDNode::get(Ctx, Vals));
95 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.distribute.enable"),
96 ConstantAsMetadata::get(ConstantInt::get(
99 Args.push_back(MDNode::get(Ctx, Vals));
103 MDNode *LoopID = MDNode::get(Ctx, Args);
104 LoopID->replaceOperandWith(0, LoopID);
111 InterleaveCount(0), UnrollCount(0),
125 const llvm::DebugLoc &StartLoc,
const llvm::DebugLoc &EndLoc)
126 : LoopID(nullptr), Header(Header), Attrs(Attrs) {
127 LoopID =
createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc);
131 const llvm::DebugLoc &EndLoc) {
132 Active.push_back(
LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
139 const llvm::DebugLoc &StartLoc,
140 const llvm::DebugLoc &EndLoc) {
143 for (
const auto *
Attr : Attrs) {
144 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
Attr);
145 const OpenCLUnrollHintAttr *OpenCLHint =
146 dyn_cast<OpenCLUnrollHintAttr>(
Attr);
149 if (!LH && !OpenCLHint) {
153 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
154 LoopHintAttr::LoopHintState
State = LoopHintAttr::Disable;
155 unsigned ValueInt = 1;
163 ValueInt = OpenCLHint->getUnrollHint();
165 State = LoopHintAttr::Full;
166 }
else if (ValueInt != 1) {
167 Option = LoopHintAttr::UnrollCount;
168 State = LoopHintAttr::Numeric;
171 auto *ValueExpr = LH->getValue();
173 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
174 ValueInt = ValueAPS.getSExtValue();
177 Option = LH->getOption();
178 State = LH->getState();
181 case LoopHintAttr::Disable:
183 case LoopHintAttr::Vectorize:
187 case LoopHintAttr::Interleave:
191 case LoopHintAttr::Unroll:
194 case LoopHintAttr::Distribute:
197 case LoopHintAttr::UnrollCount:
198 case LoopHintAttr::VectorizeWidth:
199 case LoopHintAttr::InterleaveCount:
200 llvm_unreachable(
"Options cannot be disabled.");
204 case LoopHintAttr::Enable:
206 case LoopHintAttr::Vectorize:
207 case LoopHintAttr::Interleave:
210 case LoopHintAttr::Unroll:
213 case LoopHintAttr::Distribute:
216 case LoopHintAttr::UnrollCount:
217 case LoopHintAttr::VectorizeWidth:
218 case LoopHintAttr::InterleaveCount:
219 llvm_unreachable(
"Options cannot enabled.");
223 case LoopHintAttr::AssumeSafety:
225 case LoopHintAttr::Vectorize:
226 case LoopHintAttr::Interleave:
231 case LoopHintAttr::Unroll:
232 case LoopHintAttr::UnrollCount:
233 case LoopHintAttr::VectorizeWidth:
234 case LoopHintAttr::InterleaveCount:
235 case LoopHintAttr::Distribute:
236 llvm_unreachable(
"Options cannot be used to assume mem safety.");
240 case LoopHintAttr::Full:
242 case LoopHintAttr::Unroll:
245 case LoopHintAttr::Vectorize:
246 case LoopHintAttr::Interleave:
247 case LoopHintAttr::UnrollCount:
248 case LoopHintAttr::VectorizeWidth:
249 case LoopHintAttr::InterleaveCount:
250 case LoopHintAttr::Distribute:
251 llvm_unreachable(
"Options cannot be used with 'full' hint.");
255 case LoopHintAttr::Numeric:
257 case LoopHintAttr::VectorizeWidth:
260 case LoopHintAttr::InterleaveCount:
263 case LoopHintAttr::UnrollCount:
266 case LoopHintAttr::Unroll:
267 case LoopHintAttr::Vectorize:
268 case LoopHintAttr::Interleave:
269 case LoopHintAttr::Distribute:
270 llvm_unreachable(
"Options cannot be assigned a value.");
278 push(Header, StartLoc, EndLoc);
282 assert(!Active.empty() &&
"No active loops to pop");
294 if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
295 for (
unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
296 if (TI->getSuccessor(i) == L.
getHeader()) {
297 TI->setMetadata(llvm::LLVMContext::MD_loop, L.
getLoopID());
304 I->setMetadata(
"llvm.mem.parallel_loop_access", L.
getLoopID());
Defines the clang::ASTContext interface.
void setUnrollCount(unsigned C)
Set the unroll count for the next loop pushed.
Attributes that may be specified on loops.
Information used when generating a structured loop.
LoopAttributes(bool IsParallel=false)
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Construct a new LoopInfo for the loop with entry Header.
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
llvm::BasicBlock * getHeader() const
Get the header block of this loop.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.
void pop()
End the current loop.
Whether values of this type can be null is (explicitly) unspecified.
void setVectorizeWidth(unsigned W)
Set the vectorize width for the next loop pushed.
detail::InMemoryDirectory::const_iterator I
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
void setInterleaveCount(unsigned C)
Set the interleave count for the next loop pushed.
unsigned UnrollCount
llvm.unroll.
void setParallel(bool Enable=true)
Set the next pushed loop as parallel.
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
static MDNode * createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
void setDistributeState(bool Enable=true)
Set the next pushed loop as a distribution candidate.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
const LoopAttributes & getAttributes() const
Get the set of attributes active for this loop.
void setUnrollState(const LoopAttributes::LVEnableState &State)
Set the next pushed loop unroll state.
void setVectorizeEnable(bool Enable=true)
Set the next pushed loop 'vectorize.enable'.
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
Attr - This represents one attribute.