//===- subzero/src/IceCfg.h - Control flow graph ----------------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares the Cfg class, which represents the control flow graph and
/// the overall per-function compilation context.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICECFG_H
#define SUBZERO_SRC_ICECFG_H

#include "IceAssembler.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceGlobalContext.h"
#include "IceLoopAnalyzer.h"
#include "IceStringPool.h"
#include "IceTypes.h"

namespace Ice {

class Cfg {
  Cfg() = delete;
  Cfg(const Cfg &) = delete;
  Cfg &operator=(const Cfg &) = delete;

public:
  ~Cfg();

  static std::unique_ptr<Cfg> create(GlobalContext *Ctx,
                                     uint32_t SequenceNumber) {
    return std::unique_ptr<Cfg>(new Cfg(Ctx, SequenceNumber));
  }

  GlobalContext *getContext() const { return Ctx; }
  uint32_t getSequenceNumber() const { return SequenceNumber; }
  OptLevel getOptLevel() const { return OptimizationLevel; }

  static constexpr VerboseMask defaultVerboseMask() {
    return (IceV_NO_PER_PASS_DUMP_BEYOND << 1) - 1;
  }
  /// Returns true if any of the specified options in the verbose mask are set.
  /// If the argument is omitted, it checks if any verbose options at all are
  /// set.
  bool isVerbose(VerboseMask Mask = defaultVerboseMask()) const {
    return VMask & Mask;
  }
  void setVerbose(VerboseMask Mask) { VMask = Mask; }

  /// \name Manage the name and return type of the function being translated.
  /// @{
  void setFunctionName(GlobalString Name) { FunctionName = Name; }
  GlobalString getFunctionName() const { return FunctionName; }
  std::string getFunctionNameAndSize() const;
  void setReturnType(Type Ty) { ReturnType = Ty; }
  Type getReturnType() const { return ReturnType; }
  /// @}

  /// \name Manage the "internal" attribute of the function.
  /// @{
  void setInternal(bool Internal) { IsInternalLinkage = Internal; }
  bool getInternal() const { return IsInternalLinkage; }
  /// @}

  /// \name Manage errors.
  /// @{

  /// Translation error flagging. If support for some construct is known to be
  /// missing, instead of an assertion failure, setError() should be called and
  /// the error should be propagated back up. This way, we can gracefully fail
  /// to translate and let a fallback translator handle the function.
  void setError(const std::string &Message);
  bool hasError() const { return HasError; }
  std::string getError() const { return ErrorMessage; }
  /// @}

  /// \name Manage nodes (a.k.a. basic blocks, CfgNodes).
  /// @{
  void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; }
  CfgNode *getEntryNode() const { return Entry; }
  /// Create a node and append it to the end of the linearized list. The loop
  /// nest depth of the new node may not be valid if it is created after
  /// computeLoopNestDepth.
  CfgNode *makeNode();
  SizeT getNumNodes() const { return Nodes.size(); }
  const NodeList &getNodes() const { return Nodes; }
  /// Swap nodes of Cfg with given list of nodes.  The number of nodes must
  /// remain unchanged.
  void swapNodes(NodeList &NewNodes);
  /// @}

  /// String pool for CfgNode::Name values.
  StringPool *getNodeStrings() const { return NodeStrings.get(); }
  /// String pool for Variable::Name values.
  StringPool *getVarStrings() const { return VarStrings.get(); }

  /// \name Manage instruction numbering.
  /// @{
  InstNumberT newInstNumber() { return NextInstNumber++; }
  InstNumberT getNextInstNumber() const { return NextInstNumber; }
  /// @}

  /// \name Manage Variables.
  /// @{

  /// Create a new Variable with a particular type and an optional name. The
  /// Node argument is the node where the variable is defined.
  // TODO(jpp): untemplate this with separate methods: makeVariable and
  // makeStackVariable.
  template <typename T = Variable> T *makeVariable(Type Ty) {
    SizeT Index = Variables.size();
    auto *Var = T::create(this, Ty, Index);
    Variables.push_back(Var);
    return Var;
  }
  SizeT getNumVariables() const { return Variables.size(); }
  const VarList &getVariables() const { return Variables; }
  /// @}

  /// \name Manage arguments to the function.
  /// @{
  void addArg(Variable *Arg);
  const VarList &getArgs() const { return Args; }
  VarList &getArgs() { return Args; }
  void addImplicitArg(Variable *Arg);
  const VarList &getImplicitArgs() const { return ImplicitArgs; }
  /// @}

  /// \name Manage the jump tables.
  /// @{
  void addJumpTable(InstJumpTable *JumpTable) {
    JumpTables.emplace_back(JumpTable);
  }
  /// @}

  /// \name Manage the Globals used by this function.
  /// @{
  std::unique_ptr<VariableDeclarationList> getGlobalInits() {
    return std::move(GlobalInits);
  }
  void addGlobal(VariableDeclaration *Global) {
    if (GlobalInits == nullptr) {
      GlobalInits.reset(new VariableDeclarationList);
    }
    GlobalInits->push_back(Global);
  }
  VariableDeclarationList *getGlobalPool() {
    if (GlobalInits == nullptr) {
      GlobalInits.reset(new VariableDeclarationList);
    }
    return GlobalInits.get();
  }
  /// @}

  /// \name Miscellaneous accessors.
  /// @{
  TargetLowering *getTarget() const { return Target.get(); }
  VariablesMetadata *getVMetadata() const { return VMetadata.get(); }
  Liveness *getLiveness() const { return Live.get(); }
  template <typename T = Assembler> T *getAssembler() const {
    return llvm::dyn_cast<T>(TargetAssembler.get());
  }
  std::unique_ptr<Assembler> releaseAssembler() {
    return std::move(TargetAssembler);
  }
  bool hasComputedFrame() const;
  bool getFocusedTiming() const { return FocusedTiming; }
  void setFocusedTiming() { FocusedTiming = true; }
  uint32_t getConstantBlindingCookie() const { return ConstantBlindingCookie; }
  /// @}

  /// Returns true if Var is a global variable that is used by the profiling
  /// code.
  static bool isProfileGlobal(const VariableDeclaration &Var);

  /// Passes over the CFG.
  void translate();
  /// After the CFG is fully constructed, iterate over the nodes and compute the
  /// predecessor and successor edges, in the form of CfgNode::InEdges[] and
  /// CfgNode::OutEdges[].
  void computeInOutEdges();
  /// Renumber the non-deleted instructions in the Cfg.  This needs to be done
  /// in preparation for live range analysis.  The instruction numbers in a
  /// block must be monotonically increasing.  The range of instruction numbers
  /// in a block, from lowest to highest, must not overlap with the range of any
  /// other block.
  ///
  /// Also, if the configuration specifies to do so, remove/unlink all deleted
  /// instructions from the Cfg, to speed up later passes over the instructions.
  void renumberInstructions();
  void placePhiLoads();
  void placePhiStores();
  void deletePhis();
  void advancedPhiLowering();
  void reorderNodes();
  void shuffleNodes();
  void localCSE(bool AssumeSSA);
  void floatConstantCSE();
  void shortCircuitJumps();
  void loopInvariantCodeMotion();

  /// Scan allocas to determine whether we need to use a frame pointer.
  /// If SortAndCombine == true, merge all the fixed-size allocas in the
  /// entry block and emit stack or frame pointer-relative addressing.
  void processAllocas(bool SortAndCombine);
  void doAddressOpt();
  /// Find clusters of insertelement/extractelement instructions that can be
  /// replaced by a shufflevector instruction.
  void materializeVectorShuffles();
  void doArgLowering();
  void doNopInsertion();
  void genCode();
  void genFrame();
  void generateLoopInfo();
  void livenessLightweight();
  void liveness(LivenessMode Mode);
  bool validateLiveness() const;
  void contractEmptyNodes();
  void doBranchOpt();
  void markNodesForSandboxing();

  /// \name  Manage the CurrentNode field.
  /// CurrentNode is used for validating the Variable::DefNode field during
  /// dumping/emitting.
  /// @{
  void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; }
  void resetCurrentNode() { setCurrentNode(nullptr); }
  const CfgNode *getCurrentNode() const { return CurrentNode; }
  /// @}

  /// Get the total amount of memory held by the per-Cfg allocator.
  size_t getTotalMemoryMB() const;

  /// Get the current memory usage due to liveness data structures.
  size_t getLivenessMemoryMB() const;

  void emit();
  void emitIAS();
  static void emitTextHeader(GlobalString Name, GlobalContext *Ctx,
                             const Assembler *Asm);
  void dump(const char *Message = "");

  /// Allocate data of type T using the per-Cfg allocator.
  template <typename T> T *allocate() { return Allocator->Allocate<T>(); }

  /// Allocate an array of data of type T using the per-Cfg allocator.
  template <typename T> T *allocateArrayOf(size_t NumElems) {
    return Allocator->Allocate<T>(NumElems);
  }

  /// Deallocate data that was allocated via allocate<T>().
  template <typename T> void deallocate(T *Object) {
    Allocator->Deallocate(Object);
  }

  /// Deallocate data that was allocated via allocateArrayOf<T>().
  template <typename T> void deallocateArrayOf(T *Array) {
    Allocator->Deallocate(Array);
  }

  /// Update Phi labels with InEdges.
  ///
  /// The WASM translator cannot always determine the right incoming edge for a
  /// value due to the CFG being built incrementally. The fixPhiNodes pass fills
  /// in the correct information once everything is known.
  void fixPhiNodes();

private:
  friend class CfgAllocatorTraits; // for Allocator access.

  Cfg(GlobalContext *Ctx, uint32_t SequenceNumber);

  /// Adds a call to the ProfileSummary runtime function as the first
  /// instruction in this CFG's entry block.
  void addCallToProfileSummary();

  /// Iterates over the basic blocks in this CFG, adding profiling code to each
  /// one of them. It returns a list with all the globals that the profiling
  /// code needs to be defined.
  void profileBlocks();

  void createNodeNameDeclaration(const std::string &NodeAsmName);
  void
  createBlockProfilingInfoDeclaration(const std::string &NodeAsmName,
                                      VariableDeclaration *NodeNameDeclaration);

  /// Iterate through the registered jump tables and emit them.
  void emitJumpTables();

  enum AllocaBaseVariableType {
    BVT_StackPointer,
    BVT_FramePointer,
    BVT_UserPointer
  };
  void sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas,
                             uint32_t CombinedAlignment, InstList &Insts,
                             AllocaBaseVariableType BaseVariableType);
  void findRematerializable();
  CfgVector<Inst *>
  findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body);

  GlobalContext *Ctx;
  uint32_t SequenceNumber; /// output order for emission
  OptLevel OptimizationLevel = Opt_m1;
  uint32_t ConstantBlindingCookie = 0; /// cookie for constant blinding
  VerboseMask VMask;
  GlobalString FunctionName;
  Type ReturnType = IceType_void;
  bool IsInternalLinkage = false;
  bool HasError = false;
  bool FocusedTiming = false;
  std::string ErrorMessage = "";
  CfgNode *Entry = nullptr; /// entry basic block
  NodeList Nodes;           /// linearized node list; Entry should be first
  InstNumberT NextInstNumber;
  VarList Variables;
  VarList Args;         /// subset of Variables, in argument order
  VarList ImplicitArgs; /// subset of Variables
  std::unique_ptr<ArenaAllocator> Allocator;
  // Separate string pools for CfgNode and Variable names, due to a combination
  // of the uniqueness requirement, and assumptions in lit tests.
  std::unique_ptr<StringPool> NodeStrings;
  std::unique_ptr<StringPool> VarStrings;
  std::unique_ptr<Liveness> Live;
  std::unique_ptr<TargetLowering> Target;
  std::unique_ptr<VariablesMetadata> VMetadata;
  std::unique_ptr<Assembler> TargetAssembler;
  /// Globals required by this CFG. Mostly used for the profiler's globals.
  std::unique_ptr<VariableDeclarationList> GlobalInits;
  CfgVector<InstJumpTable *> JumpTables;
  /// CurrentNode is maintained during dumping/emitting just for validating
  /// Variable::DefNode. Normally, a traversal over CfgNodes maintains this, but
  /// before global operations like register allocation, resetCurrentNode()
  /// should be called to avoid spurious validation failures.
  const CfgNode *CurrentNode = nullptr;
  CfgVector<Loop> LoopInfo;

public:
  static void TlsInit() { CfgAllocatorTraits::init(); }
};

template <> Variable *Cfg::makeVariable<Variable>(Type Ty);

struct NodeStringPoolTraits {
  using OwnerType = Cfg;
  static StringPool *getStrings(const OwnerType *PoolOwner) {
    return PoolOwner->getNodeStrings();
  }
};
using NodeString = StringID<NodeStringPoolTraits>;

struct VariableStringPoolTraits {
  using OwnerType = Cfg;
  static StringPool *getStrings(const OwnerType *PoolOwner) {
    return PoolOwner->getVarStrings();
  }
};
using VariableString = StringID<VariableStringPoolTraits>;

} // end of namespace Ice

#endif // SUBZERO_SRC_ICECFG_H
