// Copyright (c) 2018 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_
#define SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_

#include <unordered_map>
#include <unordered_set>

#include "source/opt/function.h"
#include "source/util/bit_vector.h"

namespace spvtools {
namespace opt {

class IRContext;

// An analysis that, for each basic block, finds the constructs in which it is
// contained, so we can easily get headers and merge nodes.
class StructuredCFGAnalysis {
 public:
  explicit StructuredCFGAnalysis(IRContext* ctx);

  // Returns the id of the header of the innermost merge construct
  // that contains |bb_id|.  Returns |0| if |bb_id| is not contained in any
  // merge construct.
  uint32_t ContainingConstruct(uint32_t bb_id) {
    auto it = bb_to_construct_.find(bb_id);
    if (it == bb_to_construct_.end()) {
      return 0;
    }
    return it->second.containing_construct;
  }

  // Returns the id of the header of the innermost merge construct
  // that contains |inst|.  Returns |0| if |inst| is not contained in any
  // merge construct.
  uint32_t ContainingConstruct(Instruction* inst);

  // Returns the id of the merge block of the innermost merge construct
  // that contains |bb_id|.  Returns |0| if |bb_id| is not contained in any
  // merge construct.
  uint32_t MergeBlock(uint32_t bb_id);

  // Returns the id of the header of the innermost loop construct
  // that contains |bb_id|.  Return |0| if |bb_id| is not contained in any loop
  // construct.
  uint32_t ContainingLoop(uint32_t bb_id) {
    auto it = bb_to_construct_.find(bb_id);
    if (it == bb_to_construct_.end()) {
      return 0;
    }
    return it->second.containing_loop;
  }

  // Returns the id of the merge block of the innermost loop construct
  // that contains |bb_id|.  Return |0| if |bb_id| is not contained in any loop
  // construct.
  uint32_t LoopMergeBlock(uint32_t bb_id);

  // Returns the id of the continue block of the innermost loop construct
  // that contains |bb_id|.  Return |0| if |bb_id| is not contained in any loop
  // construct.
  uint32_t LoopContinueBlock(uint32_t bb_id);

  // Returns the loop nesting depth of |bb_id| within its function, i.e. the
  // number of loop constructs in which |bb_id| is contained. As per other
  // functions in StructuredCFGAnalysis, a loop header is not regarded as being
  // part of the loop that it heads, so that e.g. the nesting depth of an
  // outer-most loop header is 0.
  uint32_t LoopNestingDepth(uint32_t bb_id);

  // Returns the id of the header of the innermost switch construct
  // that contains |bb_id| as long as there is no intervening loop.  Returns |0|
  // if no such construct exists.
  uint32_t ContainingSwitch(uint32_t bb_id) {
    auto it = bb_to_construct_.find(bb_id);
    if (it == bb_to_construct_.end()) {
      return 0;
    }
    return it->second.containing_switch;
  }
  // Returns the id of the merge block of the innermost switch construct
  // that contains |bb_id| as long as there is no intervening loop.  Return |0|
  // if no such block exists.
  uint32_t SwitchMergeBlock(uint32_t bb_id);

  // Returns true if |bb_id| is the continue block for a loop.
  bool IsContinueBlock(uint32_t bb_id);

  // Returns true if |bb_id| is in the continue construct for its inner most
  // containing loop.
  bool IsInContainingLoopsContinueConstruct(uint32_t bb_id);

  // Returns true if |bb_id| is in the continue construct for any loop in its
  // function.
  bool IsInContinueConstruct(uint32_t bb_id);

  // Return true if |bb_id| is the merge block for a construct.
  bool IsMergeBlock(uint32_t bb_id);

  // Returns the set of function ids that are called directly or indirectly from
  // a continue construct.
  std::unordered_set<uint32_t> FindFuncsCalledFromContinue();

 private:
  // Struct used to hold the information for a basic block.
  // |containing_construct| is the header for the innermost containing
  // construct, or 0 if no such construct exists.  It could be a selection
  // construct or a loop construct.
  //
  // |containing_loop| is the innermost containing loop construct, or 0 if the
  // basic bloc is not in a loop.  If the basic block is in a selection
  // construct that is contained in a loop construct, then these two values will
  // not be the same.
  //
  // |containing_switch| is the innermost contain selection construct with an
  // |OpSwitch| for the branch, as long as there is not intervening loop.  This
  // is used to identify the selection construct from which it can break.
  //
  // |in_continue| is true of the block is in the continue construct for its
  // innermost containing loop.
  struct ConstructInfo {
    uint32_t containing_construct;
    uint32_t containing_loop;
    uint32_t containing_switch;
    bool in_continue;
  };

  // Populates |bb_to_construct_| with the innermost containing merge and loop
  // constructs for each basic block in |func|.
  void AddBlocksInFunction(Function* func);

  IRContext* context_;

  // A map from a basic block to the headers of its inner most containing
  // constructs.
  std::unordered_map<uint32_t, ConstructInfo> bb_to_construct_;
  utils::BitVector merge_blocks_;
};

}  // namespace opt
}  // namespace spvtools
#endif  // SOURCE_OPT_STRUCT_CFG_ANALYSIS_H_
