13 #include "llvm/IR/BasicBlock.h" 14 #include "llvm/IR/CFG.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" 23 const llvm::DebugLoc &StartLoc,
24 const llvm::DebugLoc &EndLoc, MDNode *&AccGroup) {
39 auto TempNode = MDNode::getTemporary(Ctx, None);
40 Args.push_back(TempNode.get());
44 Args.push_back(StartLoc.getAsMDNode());
48 Args.push_back(EndLoc.getAsMDNode());
53 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.vectorize.width"),
54 ConstantAsMetadata::get(ConstantInt::get(
56 Args.push_back(MDNode::get(Ctx, Vals));
61 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.interleave.count"),
62 ConstantAsMetadata::get(ConstantInt::get(
64 Args.push_back(MDNode::get(Ctx, Vals));
69 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll.count"),
70 ConstantAsMetadata::get(ConstantInt::get(
72 Args.push_back(MDNode::get(Ctx, Vals));
77 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.unroll_and_jam.count"),
78 ConstantAsMetadata::get(ConstantInt::get(
80 Args.push_back(MDNode::get(Ctx, Vals));
85 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.vectorize.enable"),
86 ConstantAsMetadata::get(ConstantInt::get(
89 Args.push_back(MDNode::get(Ctx, Vals));
96 Name =
"llvm.loop.unroll.enable";
98 Name =
"llvm.loop.unroll.full";
100 Name =
"llvm.loop.unroll.disable";
101 Metadata *Vals[] = {MDString::get(Ctx, Name)};
102 Args.push_back(MDNode::get(Ctx, Vals));
109 Name =
"llvm.loop.unroll_and_jam.enable";
111 Name =
"llvm.loop.unroll_and_jam.full";
113 Name =
"llvm.loop.unroll_and_jam.disable";
114 Metadata *Vals[] = {MDString::get(Ctx, Name)};
115 Args.push_back(MDNode::get(Ctx, Vals));
119 Metadata *Vals[] = {MDString::get(Ctx,
"llvm.loop.distribute.enable"),
120 ConstantAsMetadata::get(ConstantInt::get(
123 Args.push_back(MDNode::get(Ctx, Vals));
127 AccGroup = MDNode::getDistinct(Ctx, {});
128 Args.push_back(MDNode::get(
129 Ctx, {MDString::get(Ctx,
"llvm.loop.parallel_accesses"), AccGroup}));
134 MDString::get(Ctx,
"llvm.loop.pipeline.disable"),
135 ConstantAsMetadata::get(ConstantInt::get(
137 Args.push_back(MDNode::get(Ctx, Vals));
142 MDString::get(Ctx,
"llvm.loop.pipeline.initiationinterval"),
143 ConstantAsMetadata::get(ConstantInt::get(
145 Args.push_back(MDNode::get(Ctx, Vals));
149 MDNode *LoopID = MDNode::get(Ctx, Args);
150 LoopID->replaceOperandWith(0, LoopID);
158 InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
160 PipelineInitiationInterval(0) {}
177 const llvm::DebugLoc &StartLoc,
const llvm::DebugLoc &EndLoc)
178 : LoopID(nullptr), Header(Header), Attrs(Attrs) {
180 createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc, AccGroup);
184 const llvm::DebugLoc &EndLoc) {
185 Active.push_back(
LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
192 const llvm::DebugLoc &StartLoc,
193 const llvm::DebugLoc &EndLoc) {
196 for (
const auto *
Attr : Attrs) {
197 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
Attr);
198 const OpenCLUnrollHintAttr *OpenCLHint =
199 dyn_cast<OpenCLUnrollHintAttr>(
Attr);
202 if (!LH && !OpenCLHint) {
206 LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
207 LoopHintAttr::LoopHintState
State = LoopHintAttr::Disable;
208 unsigned ValueInt = 1;
216 ValueInt = OpenCLHint->getUnrollHint();
218 State = LoopHintAttr::Full;
219 }
else if (ValueInt != 1) {
220 Option = LoopHintAttr::UnrollCount;
221 State = LoopHintAttr::Numeric;
224 auto *ValueExpr = LH->getValue();
226 llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
227 ValueInt = ValueAPS.getSExtValue();
230 Option = LH->getOption();
231 State = LH->getState();
234 case LoopHintAttr::Disable:
236 case LoopHintAttr::Vectorize:
238 setVectorizeWidth(1);
240 case LoopHintAttr::Interleave:
242 setInterleaveCount(1);
244 case LoopHintAttr::Unroll:
247 case LoopHintAttr::UnrollAndJam:
250 case LoopHintAttr::Distribute:
251 setDistributeState(
false);
253 case LoopHintAttr::PipelineDisabled:
254 setPipelineDisabled(
true);
256 case LoopHintAttr::UnrollCount:
257 case LoopHintAttr::UnrollAndJamCount:
258 case LoopHintAttr::VectorizeWidth:
259 case LoopHintAttr::InterleaveCount:
260 case LoopHintAttr::PipelineInitiationInterval:
261 llvm_unreachable(
"Options cannot be disabled.");
265 case LoopHintAttr::Enable:
267 case LoopHintAttr::Vectorize:
268 case LoopHintAttr::Interleave:
269 setVectorizeEnable(
true);
271 case LoopHintAttr::Unroll:
274 case LoopHintAttr::UnrollAndJam:
277 case LoopHintAttr::Distribute:
278 setDistributeState(
true);
280 case LoopHintAttr::UnrollCount:
281 case LoopHintAttr::UnrollAndJamCount:
282 case LoopHintAttr::VectorizeWidth:
283 case LoopHintAttr::InterleaveCount:
284 case LoopHintAttr::PipelineDisabled:
285 case LoopHintAttr::PipelineInitiationInterval:
286 llvm_unreachable(
"Options cannot enabled.");
290 case LoopHintAttr::AssumeSafety:
292 case LoopHintAttr::Vectorize:
293 case LoopHintAttr::Interleave:
296 setVectorizeEnable(
true);
298 case LoopHintAttr::Unroll:
299 case LoopHintAttr::UnrollAndJam:
300 case LoopHintAttr::UnrollCount:
301 case LoopHintAttr::UnrollAndJamCount:
302 case LoopHintAttr::VectorizeWidth:
303 case LoopHintAttr::InterleaveCount:
304 case LoopHintAttr::Distribute:
305 case LoopHintAttr::PipelineDisabled:
306 case LoopHintAttr::PipelineInitiationInterval:
307 llvm_unreachable(
"Options cannot be used to assume mem safety.");
311 case LoopHintAttr::Full:
313 case LoopHintAttr::Unroll:
316 case LoopHintAttr::UnrollAndJam:
319 case LoopHintAttr::Vectorize:
320 case LoopHintAttr::Interleave:
321 case LoopHintAttr::UnrollCount:
322 case LoopHintAttr::UnrollAndJamCount:
323 case LoopHintAttr::VectorizeWidth:
324 case LoopHintAttr::InterleaveCount:
325 case LoopHintAttr::Distribute:
326 case LoopHintAttr::PipelineDisabled:
327 case LoopHintAttr::PipelineInitiationInterval:
328 llvm_unreachable(
"Options cannot be used with 'full' hint.");
332 case LoopHintAttr::Numeric:
334 case LoopHintAttr::VectorizeWidth:
335 setVectorizeWidth(ValueInt);
337 case LoopHintAttr::InterleaveCount:
338 setInterleaveCount(ValueInt);
340 case LoopHintAttr::UnrollCount:
341 setUnrollCount(ValueInt);
343 case LoopHintAttr::UnrollAndJamCount:
344 setUnrollAndJamCount(ValueInt);
346 case LoopHintAttr::PipelineInitiationInterval:
347 setPipelineInitiationInterval(ValueInt);
349 case LoopHintAttr::Unroll:
350 case LoopHintAttr::UnrollAndJam:
351 case LoopHintAttr::Vectorize:
352 case LoopHintAttr::Interleave:
353 case LoopHintAttr::Distribute:
354 case LoopHintAttr::PipelineDisabled:
355 llvm_unreachable(
"Options cannot be assigned a value.");
363 push(Header, StartLoc, EndLoc);
367 assert(!Active.empty() &&
"No active loops to pop");
372 if (I->mayReadOrWriteMemory()) {
376 if (MDNode *Group = AL.getAccessGroup())
377 AccessGroups.push_back(Group);
379 MDNode *UnionMD =
nullptr;
380 if (AccessGroups.size() == 1)
381 UnionMD = cast<MDNode>(AccessGroups[0]);
382 else if (AccessGroups.size() >= 2)
383 UnionMD = MDNode::get(I->getContext(), AccessGroups);
384 I->setMetadata(
"llvm.access.group", UnionMD);
394 if (I->isTerminator()) {
395 for (BasicBlock *Succ : successors(I))
397 I->setMetadata(llvm::LLVMContext::MD_loop, L.
getLoopID());
Defines the clang::ASTContext interface.
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Attributes that may be specified on loops.
unsigned UnrollAndJamCount
llvm.unroll.
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).
unsigned PipelineInitiationInterval
Value for llvm.loop.pipeline.iicount metadata.
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.
LVEnableState UnrollAndJamEnable
Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
unsigned UnrollCount
llvm.unroll.
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
llvm::MDNode * getLoopID() const
Get the loop id metadata for this loop.
void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
Begin a new structured loop.
bool PipelineDisabled
Value for llvm.loop.pipeline.disable metadata.
static const TypeInfo & getInfo(unsigned id)
static MDNode * createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc, MDNode *&AccGroup)
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
llvm::BasicBlock * getHeader() const
Get the header block of this loop.
Attr - This represents one attribute.