16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===//
26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//                     The LLVM Compiler Infrastructure
46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source
66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details.
76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This is the internal state used for llvm translation for loop statement
116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// metadata.
126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#ifndef CLANG_CODEGEN_CGLOOPINFO_H
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define CLANG_CODEGEN_CGLOOPINFO_H
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/DenseMap.h"
196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/SmallVector.h"
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/IR/Value.h"
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/Support/Compiler.h"
226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace llvm {
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass BasicBlock;
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass Instruction;
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass MDNode;
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace llvm
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace clang {
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace CodeGen {
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Attributes that may be specified on loops.
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct LoopAttributes {
346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  explicit LoopAttributes(bool IsParallel = false);
356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void clear();
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Generate llvm.loop.parallel metadata for loads and stores.
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool IsParallel;
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
40ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  /// \brief Values of llvm.loop.vectorize.enable metadata.
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  enum LVEnableState { VecUnspecified, VecEnable, VecDisable };
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
43ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  /// \brief llvm.loop.vectorize.enable
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LVEnableState VectorizerEnable;
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
46ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  /// \brief llvm.loop.vectorize.width
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  unsigned VectorizerWidth;
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  /// \brief llvm.loop.vectorize.unroll
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  unsigned VectorizerUnroll;
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Information used when generating a structured loop.
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LoopInfo {
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic:
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Construct a new LoopInfo for the loop with entry Header.
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs);
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Get the loop id metadata for this loop.
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::MDNode *getLoopID() const { return LoopID; }
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Get the header block of this loop.
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::BasicBlock *getHeader() const { return Header; }
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Get the set of attributes active for this loop.
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const LoopAttributes &getAttributes() const { return Attrs; }
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprivate:
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Loop ID metadata.
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::MDNode *LoopID;
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Header block of this loop.
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::BasicBlock *Header;
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief The attributes for this loop.
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LoopAttributes Attrs;
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief A stack of loop information corresponding to loop nesting levels.
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// This stack can be used to prepare attributes which are applied when a loop
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// is emitted.
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LoopInfoStack {
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LoopInfoStack(const LoopInfoStack &) LLVM_DELETED_FUNCTION;
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void operator=(const LoopInfoStack &) LLVM_DELETED_FUNCTION;
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic:
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LoopInfoStack() {}
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Begin a new structured loop. The set of staged attributes will be
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// applied to the loop and then cleared.
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void push(llvm::BasicBlock *Header);
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief End the current loop.
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void pop();
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Return the top loop id metadata.
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); }
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Return true if the top loop is parallel.
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool getCurLoopParallel() const {
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return hasInfo() ? getInfo().getAttributes().IsParallel : false;
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Function called by the CodeGenFunction when an instruction is
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// created.
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void InsertHelper(llvm::Instruction *I) const;
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Set the next pushed loop as parallel.
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; }
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Set the next pushed loop 'vectorizer.enable'
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setVectorizerEnable(bool Enable = true) {
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    StagedAttrs.VectorizerEnable =
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Enable ? LoopAttributes::VecEnable : LoopAttributes::VecDisable;
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Set the vectorizer width for the next loop pushed.
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setVectorizerWidth(unsigned W) { StagedAttrs.VectorizerWidth = W; }
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Set the vectorizer unroll for the next loop pushed.
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setVectorizerUnroll(unsigned U) { StagedAttrs.VectorizerUnroll = U; }
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprivate:
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Returns true if there is LoopInfo on the stack.
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool hasInfo() const { return !Active.empty(); }
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Return the LoopInfo for the current loop. HasInfo should be called
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// first to ensure LoopInfo is present.
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const LoopInfo &getInfo() const { return Active.back(); }
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief The set of attributes that will be applied to the next pushed loop.
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LoopAttributes StagedAttrs;
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Stack of active loops.
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::SmallVector<LoopInfo, 4> Active;
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace CodeGen
1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace clang
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif // CLANG_CODEGEN_CGLOOPINFO_H
137