Home | History | Annotate | Download | only in val
      1 // Copyright (c) 2015-2016 The Khronos Group Inc.
      2 //
      3 // Permission is hereby granted, free of charge, to any person obtaining a
      4 // copy of this software and/or associated documentation files (the
      5 // "Materials"), to deal in the Materials without restriction, including
      6 // without limitation the rights to use, copy, modify, merge, publish,
      7 // distribute, sublicense, and/or sell copies of the Materials, and to
      8 // permit persons to whom the Materials are furnished to do so, subject to
      9 // the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included
     12 // in all copies or substantial portions of the Materials.
     13 //
     14 // MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
     15 // KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
     16 // SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
     17 //    https://www.khronos.org/registry/
     18 //
     19 // THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     23 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25 // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
     26 
     27 #ifndef LIBSPIRV_VAL_CONSTRUCT_H_
     28 #define LIBSPIRV_VAL_CONSTRUCT_H_
     29 
     30 #include <cstdint>
     31 #include <vector>
     32 
     33 namespace libspirv {
     34 
     35 enum class ConstructType {
     36   kNone,
     37   /// The set of blocks dominated by a selection header, minus the set of blocks
     38   /// dominated by the header's merge block
     39   kSelection,
     40   /// The set of blocks dominated by an OpLoopMerge's Continue Target and post
     41   /// dominated by the corresponding back
     42   kContinue,
     43   ///  The set of blocks dominated by a loop header, minus the set of blocks
     44   ///  dominated by the loop's merge block, minus the loop's corresponding
     45   ///  continue construct
     46   kLoop,
     47   ///  The set of blocks dominated by an OpSwitch's Target or Default, minus the
     48   ///  set of blocks dominated by the OpSwitch's merge block (this construct is
     49   ///  only defined for those OpSwitch Target or Default that are not equal to
     50   ///  the OpSwitch's corresponding merge block)
     51   kCase
     52 };
     53 
     54 class BasicBlock;
     55 
     56 /// @brief This class tracks the CFG constructs as defined in the SPIR-V spec
     57 class Construct {
     58  public:
     59   Construct(ConstructType type, BasicBlock* dominator,
     60             BasicBlock* exit = nullptr,
     61             std::vector<Construct*> constructs = {});
     62 
     63   /// Returns the type of the construct
     64   ConstructType type() const;
     65 
     66   const std::vector<Construct*>& corresponding_constructs() const;
     67   std::vector<Construct*>& corresponding_constructs();
     68   void set_corresponding_constructs(std::vector<Construct*> constructs);
     69 
     70   /// Returns the dominator block of the construct.
     71   ///
     72   /// This is usually the header block or the first block of the construct.
     73   const BasicBlock* entry_block() const;
     74 
     75   /// Returns the dominator block of the construct.
     76   ///
     77   /// This is usually the header block or the first block of the construct.
     78   BasicBlock* entry_block();
     79 
     80   /// Returns the exit block of the construct.
     81   ///
     82   /// For a continue construct it is  the backedge block of the corresponding
     83   /// loop construct. For the case  construct it is the block that branches to
     84   /// the OpSwitch merge block or  other case blocks. Otherwise it is the merge
     85   /// block of the corresponding  header block
     86   const BasicBlock* exit_block() const;
     87 
     88   /// Returns the exit block of the construct.
     89   ///
     90   /// For a continue construct it is  the backedge block of the corresponding
     91   /// loop construct. For the case  construct it is the block that branches to
     92   /// the OpSwitch merge block or  other case blocks. Otherwise it is the merge
     93   /// block of the corresponding  header block
     94   BasicBlock* exit_block();
     95 
     96   /// Sets the exit block for this construct. This is useful for continue
     97   /// constructs which do not know the back-edge block during construction
     98   void set_exit(BasicBlock* exit_block);
     99 
    100  private:
    101   /// The type of the construct
    102   ConstructType type_;
    103 
    104   /// These are the constructs that are related to this construct. These
    105   /// constructs can be the continue construct, for the corresponding loop
    106   /// construct, the case construct that are part of the same OpSwitch
    107   /// instruction
    108   ///
    109   /// Here is a table that describes what constructs are included in
    110   /// @p corresponding_constructs_
    111   /// | this construct | corresponding construct          |
    112   /// |----------------|----------------------------------|
    113   /// | loop           | continue                         |
    114   /// | continue       | loop                             |
    115   /// | case           | other cases in the same OpSwitch |
    116   ///
    117   /// kContinue and kLoop constructs will always have corresponding
    118   /// constructs even if they are represented by the same block
    119   std::vector<Construct*> corresponding_constructs_;
    120 
    121   /// @brief Dominator block for the construct
    122   ///
    123   /// The dominator block for the construct. Depending on the construct this may
    124   /// be a selection header, a continue target of a loop, a loop header or a
    125   /// Target or Default block of a switch
    126   BasicBlock* entry_block_;
    127 
    128   /// @brief Exiting block for the construct
    129   ///
    130   /// The exit block for the construct. This can be a merge block for the loop
    131   /// and selection constructs, a back-edge block for a continue construct, or
    132   /// the branching block for the case construct
    133   BasicBlock* exit_block_;
    134 };
    135 
    136 }  /// namespace libspirv
    137 
    138 #endif  /// LIBSPIRV_VAL_CONSTRUCT_H_
    139