Mercurial > hg > CbC > CbC_llvm
diff clang/lib/CodeGen/CGLoopInfo.h @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 0572611fdcc8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clang/lib/CodeGen/CGLoopInfo.h Thu Feb 13 15:10:13 2020 +0900 @@ -0,0 +1,288 @@ +//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This is the internal state used for llvm translation for loop statement +// metadata. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H +#define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { +class BasicBlock; +class Instruction; +class MDNode; +} // end namespace llvm + +namespace clang { +class Attr; +class ASTContext; +namespace CodeGen { + +/// Attributes that may be specified on loops. +struct LoopAttributes { + explicit LoopAttributes(bool IsParallel = false); + void clear(); + + /// Generate llvm.loop.parallel metadata for loads and stores. + bool IsParallel; + + /// State of loop vectorization or unrolling. + enum LVEnableState { Unspecified, Enable, Disable, Full }; + + /// Value for llvm.loop.vectorize.enable metadata. + LVEnableState VectorizeEnable; + + /// Value for llvm.loop.unroll.* metadata (enable, disable, or full). + LVEnableState UnrollEnable; + + /// Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full). + LVEnableState UnrollAndJamEnable; + + /// Value for llvm.loop.vectorize.predicate metadata + LVEnableState VectorizePredicateEnable; + + /// Value for llvm.loop.vectorize.width metadata. + unsigned VectorizeWidth; + + /// Value for llvm.loop.interleave.count metadata. + unsigned InterleaveCount; + + /// llvm.unroll. + unsigned UnrollCount; + + /// llvm.unroll. + unsigned UnrollAndJamCount; + + /// Value for llvm.loop.distribute.enable metadata. + LVEnableState DistributeEnable; + + /// Value for llvm.loop.pipeline.disable metadata. + bool PipelineDisabled; + + /// Value for llvm.loop.pipeline.iicount metadata. + unsigned PipelineInitiationInterval; +}; + +/// Information used when generating a structured loop. +class LoopInfo { +public: + /// Construct a new LoopInfo for the loop with entry Header. + LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, + const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc, + LoopInfo *Parent); + + /// Get the loop id metadata for this loop. + llvm::MDNode *getLoopID() const { return TempLoopID.get(); } + + /// Get the header block of this loop. + llvm::BasicBlock *getHeader() const { return Header; } + + /// Get the set of attributes active for this loop. + const LoopAttributes &getAttributes() const { return Attrs; } + + /// Return this loop's access group or nullptr if it does not have one. + llvm::MDNode *getAccessGroup() const { return AccGroup; } + + /// Create the loop's metadata. Must be called after its nested loops have + /// been processed. + void finish(); + +private: + /// Loop ID metadata. + llvm::TempMDTuple TempLoopID; + /// Header block of this loop. + llvm::BasicBlock *Header; + /// The attributes for this loop. + LoopAttributes Attrs; + /// The access group for memory accesses parallel to this loop. + llvm::MDNode *AccGroup = nullptr; + /// Start location of this loop. + llvm::DebugLoc StartLoc; + /// End location of this loop. + llvm::DebugLoc EndLoc; + /// The next outer loop, or nullptr if this is the outermost loop. + LoopInfo *Parent; + /// If this loop has unroll-and-jam metadata, this can be set by the inner + /// loop's LoopInfo to set the llvm.loop.unroll_and_jam.followup_inner + /// metadata. + llvm::MDNode *UnrollAndJamInnerFollowup = nullptr; + + /// Create a LoopID without any transformations. + llvm::MDNode * + createLoopPropertiesMetadata(llvm::ArrayRef<llvm::Metadata *> LoopProperties); + + /// Create a LoopID for transformations. + /// + /// The methods call each other in case multiple transformations are applied + /// to a loop. The transformation first to be applied will use LoopID of the + /// next transformation in its followup attribute. + /// + /// @param Attrs The loop's transformations. + /// @param LoopProperties Non-transformation properties such as debug + /// location, parallel accesses and disabled + /// transformations. These are added to the returned + /// LoopID. + /// @param HasUserTransforms [out] Set to true if the returned MDNode encodes + /// at least one transformation. + /// + /// @return A LoopID (metadata node) that can be used for the llvm.loop + /// annotation or followup-attribute. + /// @{ + llvm::MDNode * + createPipeliningMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + llvm::MDNode * + createPartialUnrollMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + llvm::MDNode * + createUnrollAndJamMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + llvm::MDNode * + createLoopVectorizeMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + llvm::MDNode * + createLoopDistributeMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + llvm::MDNode * + createFullUnrollMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); + /// @} + + /// Create a LoopID for this loop, including transformation-unspecific + /// metadata such as debug location. + /// + /// @param Attrs This loop's attributes and transformations. + /// @param LoopProperties Additional non-transformation properties to add + /// to the LoopID, such as transformation-specific + /// metadata that are not covered by @p Attrs. + /// @param HasUserTransforms [out] Set to true if the returned MDNode encodes + /// at least one transformation. + /// + /// @return A LoopID (metadata node) that can be used for the llvm.loop + /// annotation. + llvm::MDNode *createMetadata(const LoopAttributes &Attrs, + llvm::ArrayRef<llvm::Metadata *> LoopProperties, + bool &HasUserTransforms); +}; + +/// A stack of loop information corresponding to loop nesting levels. +/// This stack can be used to prepare attributes which are applied when a loop +/// is emitted. +class LoopInfoStack { + LoopInfoStack(const LoopInfoStack &) = delete; + void operator=(const LoopInfoStack &) = delete; + +public: + LoopInfoStack() {} + + /// Begin a new structured loop. The set of staged attributes will be + /// applied to the loop and then cleared. + void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, + const llvm::DebugLoc &EndLoc); + + /// Begin a new structured loop. Stage attributes from the Attrs list. + /// The staged attributes are applied to the loop and then cleared. + void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, + llvm::ArrayRef<const Attr *> Attrs, const llvm::DebugLoc &StartLoc, + const llvm::DebugLoc &EndLoc); + + /// End the current loop. + void pop(); + + /// Return the top loop id metadata. + llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); } + + /// Return true if the top loop is parallel. + bool getCurLoopParallel() const { + return hasInfo() ? getInfo().getAttributes().IsParallel : false; + } + + /// Function called by the CodeGenFunction when an instruction is + /// created. + void InsertHelper(llvm::Instruction *I) const; + + /// Set the next pushed loop as parallel. + void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; } + + /// Set the next pushed loop 'vectorize.enable' + void setVectorizeEnable(bool Enable = true) { + StagedAttrs.VectorizeEnable = + Enable ? LoopAttributes::Enable : LoopAttributes::Disable; + } + + /// Set the next pushed loop as a distribution candidate. + void setDistributeState(bool Enable = true) { + StagedAttrs.DistributeEnable = + Enable ? LoopAttributes::Enable : LoopAttributes::Disable; + } + + /// Set the next pushed loop unroll state. + void setUnrollState(const LoopAttributes::LVEnableState &State) { + StagedAttrs.UnrollEnable = State; + } + + /// Set the next pushed vectorize predicate state. + void setVectorizePredicateState(const LoopAttributes::LVEnableState &State) { + StagedAttrs.VectorizePredicateEnable = State; + } + + /// Set the next pushed loop unroll_and_jam state. + void setUnrollAndJamState(const LoopAttributes::LVEnableState &State) { + StagedAttrs.UnrollAndJamEnable = State; + } + + /// Set the vectorize width for the next loop pushed. + void setVectorizeWidth(unsigned W) { StagedAttrs.VectorizeWidth = W; } + + /// Set the interleave count for the next loop pushed. + void setInterleaveCount(unsigned C) { StagedAttrs.InterleaveCount = C; } + + /// Set the unroll count for the next loop pushed. + void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; } + + /// \brief Set the unroll count for the next loop pushed. + void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; } + + /// Set the pipeline disabled state. + void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; } + + /// Set the pipeline initiation interval. + void setPipelineInitiationInterval(unsigned C) { + StagedAttrs.PipelineInitiationInterval = C; + } + +private: + /// Returns true if there is LoopInfo on the stack. + bool hasInfo() const { return !Active.empty(); } + /// Return the LoopInfo for the current loop. HasInfo should be called + /// first to ensure LoopInfo is present. + const LoopInfo &getInfo() const { return *Active.back(); } + /// The set of attributes that will be applied to the next pushed loop. + LoopAttributes StagedAttrs; + /// Stack of active loops. + llvm::SmallVector<std::unique_ptr<LoopInfo>, 4> Active; +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif