Path: blob/main/contrib/llvm-project/clang/lib/CodeGen/CGLoopInfo.h
35234 views
//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This is the internal state used for llvm translation for loop statement9// metadata.10//11//===----------------------------------------------------------------------===//1213#ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H14#define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H1516#include "llvm/ADT/ArrayRef.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/IR/DebugLoc.h"19#include "llvm/IR/Value.h"20#include "llvm/Support/Compiler.h"2122namespace llvm {23class BasicBlock;24class Instruction;25class MDNode;26} // end namespace llvm2728namespace clang {29class Attr;30class ASTContext;31class CodeGenOptions;32namespace CodeGen {3334/// Attributes that may be specified on loops.35struct LoopAttributes {36explicit LoopAttributes(bool IsParallel = false);37void clear();3839/// Generate llvm.loop.parallel metadata for loads and stores.40bool IsParallel;4142/// State of loop vectorization or unrolling.43enum LVEnableState { Unspecified, Enable, Disable, Full };4445/// Value for llvm.loop.vectorize.enable metadata.46LVEnableState VectorizeEnable;4748/// Value for llvm.loop.unroll.* metadata (enable, disable, or full).49LVEnableState UnrollEnable;5051/// Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).52LVEnableState UnrollAndJamEnable;5354/// Value for llvm.loop.vectorize.predicate metadata55LVEnableState VectorizePredicateEnable;5657/// Value for llvm.loop.vectorize.width metadata.58unsigned VectorizeWidth;5960// Value for llvm.loop.vectorize.scalable.enable61LVEnableState VectorizeScalable;6263/// Value for llvm.loop.interleave.count metadata.64unsigned InterleaveCount;6566/// llvm.unroll.67unsigned UnrollCount;6869/// llvm.unroll.70unsigned UnrollAndJamCount;7172/// Value for llvm.loop.distribute.enable metadata.73LVEnableState DistributeEnable;7475/// Value for llvm.loop.pipeline.disable metadata.76bool PipelineDisabled;7778/// Value for llvm.loop.pipeline.iicount metadata.79unsigned PipelineInitiationInterval;8081/// Value for 'llvm.loop.align' metadata.82unsigned CodeAlign;8384/// Value for whether the loop is required to make progress.85bool MustProgress;86};8788/// Information used when generating a structured loop.89class LoopInfo {90public:91/// Construct a new LoopInfo for the loop with entry Header.92LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs,93const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,94LoopInfo *Parent);9596/// Get the loop id metadata for this loop.97llvm::MDNode *getLoopID() const { return TempLoopID.get(); }9899/// Get the header block of this loop.100llvm::BasicBlock *getHeader() const { return Header; }101102/// Get the set of attributes active for this loop.103const LoopAttributes &getAttributes() const { return Attrs; }104105/// Return this loop's access group or nullptr if it does not have one.106llvm::MDNode *getAccessGroup() const { return AccGroup; }107108/// Create the loop's metadata. Must be called after its nested loops have109/// been processed.110void finish();111112/// Returns the first outer loop containing this loop if any, nullptr113/// otherwise.114const LoopInfo *getParent() const { return Parent; }115116private:117/// Loop ID metadata.118llvm::TempMDTuple TempLoopID;119/// Header block of this loop.120llvm::BasicBlock *Header;121/// The attributes for this loop.122LoopAttributes Attrs;123/// The access group for memory accesses parallel to this loop.124llvm::MDNode *AccGroup = nullptr;125/// Start location of this loop.126llvm::DebugLoc StartLoc;127/// End location of this loop.128llvm::DebugLoc EndLoc;129/// The next outer loop, or nullptr if this is the outermost loop.130LoopInfo *Parent;131/// If this loop has unroll-and-jam metadata, this can be set by the inner132/// loop's LoopInfo to set the llvm.loop.unroll_and_jam.followup_inner133/// metadata.134llvm::MDNode *UnrollAndJamInnerFollowup = nullptr;135136/// Create a LoopID without any transformations.137llvm::MDNode *138createLoopPropertiesMetadata(llvm::ArrayRef<llvm::Metadata *> LoopProperties);139140/// Create a LoopID for transformations.141///142/// The methods call each other in case multiple transformations are applied143/// to a loop. The transformation first to be applied will use LoopID of the144/// next transformation in its followup attribute.145///146/// @param Attrs The loop's transformations.147/// @param LoopProperties Non-transformation properties such as debug148/// location, parallel accesses and disabled149/// transformations. These are added to the returned150/// LoopID.151/// @param HasUserTransforms [out] Set to true if the returned MDNode encodes152/// at least one transformation.153///154/// @return A LoopID (metadata node) that can be used for the llvm.loop155/// annotation or followup-attribute.156/// @{157llvm::MDNode *158createPipeliningMetadata(const LoopAttributes &Attrs,159llvm::ArrayRef<llvm::Metadata *> LoopProperties,160bool &HasUserTransforms);161llvm::MDNode *162createPartialUnrollMetadata(const LoopAttributes &Attrs,163llvm::ArrayRef<llvm::Metadata *> LoopProperties,164bool &HasUserTransforms);165llvm::MDNode *166createUnrollAndJamMetadata(const LoopAttributes &Attrs,167llvm::ArrayRef<llvm::Metadata *> LoopProperties,168bool &HasUserTransforms);169llvm::MDNode *170createLoopVectorizeMetadata(const LoopAttributes &Attrs,171llvm::ArrayRef<llvm::Metadata *> LoopProperties,172bool &HasUserTransforms);173llvm::MDNode *174createLoopDistributeMetadata(const LoopAttributes &Attrs,175llvm::ArrayRef<llvm::Metadata *> LoopProperties,176bool &HasUserTransforms);177llvm::MDNode *178createFullUnrollMetadata(const LoopAttributes &Attrs,179llvm::ArrayRef<llvm::Metadata *> LoopProperties,180bool &HasUserTransforms);181/// @}182183/// Create a LoopID for this loop, including transformation-unspecific184/// metadata such as debug location.185///186/// @param Attrs This loop's attributes and transformations.187/// @param LoopProperties Additional non-transformation properties to add188/// to the LoopID, such as transformation-specific189/// metadata that are not covered by @p Attrs.190/// @param HasUserTransforms [out] Set to true if the returned MDNode encodes191/// at least one transformation.192///193/// @return A LoopID (metadata node) that can be used for the llvm.loop194/// annotation.195llvm::MDNode *createMetadata(const LoopAttributes &Attrs,196llvm::ArrayRef<llvm::Metadata *> LoopProperties,197bool &HasUserTransforms);198};199200/// A stack of loop information corresponding to loop nesting levels.201/// This stack can be used to prepare attributes which are applied when a loop202/// is emitted.203class LoopInfoStack {204LoopInfoStack(const LoopInfoStack &) = delete;205void operator=(const LoopInfoStack &) = delete;206207public:208LoopInfoStack() {}209210/// Begin a new structured loop. The set of staged attributes will be211/// applied to the loop and then cleared.212void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc,213const llvm::DebugLoc &EndLoc);214215/// Begin a new structured loop. Stage attributes from the Attrs list.216/// The staged attributes are applied to the loop and then cleared.217void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx,218const clang::CodeGenOptions &CGOpts,219llvm::ArrayRef<const Attr *> Attrs, const llvm::DebugLoc &StartLoc,220const llvm::DebugLoc &EndLoc, bool MustProgress = false);221222/// End the current loop.223void pop();224225/// Return the top loop id metadata.226llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); }227228/// Return true if the top loop is parallel.229bool getCurLoopParallel() const {230return hasInfo() ? getInfo().getAttributes().IsParallel : false;231}232233/// Function called by the CodeGenFunction when an instruction is234/// created.235void InsertHelper(llvm::Instruction *I) const;236237/// Set the next pushed loop as parallel.238void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; }239240/// Set the next pushed loop 'vectorize.enable'241void setVectorizeEnable(bool Enable = true) {242StagedAttrs.VectorizeEnable =243Enable ? LoopAttributes::Enable : LoopAttributes::Disable;244}245246/// Set the next pushed loop as a distribution candidate.247void setDistributeState(bool Enable = true) {248StagedAttrs.DistributeEnable =249Enable ? LoopAttributes::Enable : LoopAttributes::Disable;250}251252/// Set the next pushed loop unroll state.253void setUnrollState(const LoopAttributes::LVEnableState &State) {254StagedAttrs.UnrollEnable = State;255}256257/// Set the next pushed vectorize predicate state.258void setVectorizePredicateState(const LoopAttributes::LVEnableState &State) {259StagedAttrs.VectorizePredicateEnable = State;260}261262/// Set the next pushed loop unroll_and_jam state.263void setUnrollAndJamState(const LoopAttributes::LVEnableState &State) {264StagedAttrs.UnrollAndJamEnable = State;265}266267/// Set the vectorize width for the next loop pushed.268void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; }269270void setVectorizeScalable(const LoopAttributes::LVEnableState &State) {271StagedAttrs.VectorizeScalable = State;272}273274/// Set the interleave count for the next loop pushed.275void setInterleaveCount(unsigned C) { StagedAttrs.InterleaveCount = C; }276277/// Set the unroll count for the next loop pushed.278void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; }279280/// \brief Set the unroll count for the next loop pushed.281void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; }282283/// Set the pipeline disabled state.284void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; }285286/// Set the pipeline initiation interval.287void setPipelineInitiationInterval(unsigned C) {288StagedAttrs.PipelineInitiationInterval = C;289}290291/// Set value of code align for the next loop pushed.292void setCodeAlign(unsigned C) { StagedAttrs.CodeAlign = C; }293294/// Set no progress for the next loop pushed.295void setMustProgress(bool P) { StagedAttrs.MustProgress = P; }296297/// Returns true if there is LoopInfo on the stack.298bool hasInfo() const { return !Active.empty(); }299/// Return the LoopInfo for the current loop. HasInfo should be called300/// first to ensure LoopInfo is present.301const LoopInfo &getInfo() const { return *Active.back(); }302303private:304/// The set of attributes that will be applied to the next pushed loop.305LoopAttributes StagedAttrs;306/// Stack of active loops.307llvm::SmallVector<std::unique_ptr<LoopInfo>, 4> Active;308};309310} // end namespace CodeGen311} // end namespace clang312313#endif314315316