Home | History | Annotate | Download | only in opt
      1 // Copyright (c) 2016 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef LIBSPIRV_OPT_CONSTANTS_H_
     16 #define LIBSPIRV_OPT_CONSTANTS_H_
     17 
     18 #include <memory>
     19 #include <utility>
     20 #include <vector>
     21 
     22 #include "make_unique.h"
     23 #include "types.h"
     24 
     25 namespace spvtools {
     26 namespace opt {
     27 namespace analysis {
     28 
     29 // Class hierarchy to represent the normal constants defined through
     30 // OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull and
     31 // OpConstantComposite instructions.
     32 // TODO(qining): Add class for constants defined with OpConstantSampler.
     33 class Constant;
     34 class ScalarConstant;
     35 class IntConstant;
     36 class FloatConstant;
     37 class BoolConstant;
     38 class CompositeConstant;
     39 class StructConstant;
     40 class VectorConstant;
     41 class ArrayConstant;
     42 class NullConstant;
     43 
     44 // Abstract class for a SPIR-V constant. It has a bunch of As<subclass> methods,
     45 // which is used as a way to probe the actual <subclass>
     46 class Constant {
     47  public:
     48   Constant() = delete;
     49   virtual ~Constant() {}
     50 
     51   // Make a deep copy of this constant.
     52   virtual std::unique_ptr<Constant> Copy() const = 0;
     53 
     54   // reflections
     55   virtual ScalarConstant* AsScalarConstant() { return nullptr; }
     56   virtual IntConstant* AsIntConstant() { return nullptr; }
     57   virtual FloatConstant* AsFloatConstant() { return nullptr; }
     58   virtual BoolConstant* AsBoolConstant() { return nullptr; }
     59   virtual CompositeConstant* AsCompositeConstant() { return nullptr; }
     60   virtual StructConstant* AsStructConstant() { return nullptr; }
     61   virtual VectorConstant* AsVectorConstant() { return nullptr; }
     62   virtual ArrayConstant* AsArrayConstant() { return nullptr; }
     63   virtual NullConstant* AsNullConstant() { return nullptr; }
     64 
     65   virtual const ScalarConstant* AsScalarConstant() const { return nullptr; }
     66   virtual const IntConstant* AsIntConstant() const { return nullptr; }
     67   virtual const FloatConstant* AsFloatConstant() const { return nullptr; }
     68   virtual const BoolConstant* AsBoolConstant() const { return nullptr; }
     69   virtual const CompositeConstant* AsCompositeConstant() const {
     70     return nullptr;
     71   }
     72   virtual const StructConstant* AsStructConstant() const { return nullptr; }
     73   virtual const VectorConstant* AsVectorConstant() const { return nullptr; }
     74   virtual const ArrayConstant* AsArrayConstant() const { return nullptr; }
     75   virtual const NullConstant* AsNullConstant() const { return nullptr; }
     76 
     77   const analysis::Type* type() const { return type_; }
     78 
     79  protected:
     80   Constant(const analysis::Type* ty) : type_(ty) {}
     81 
     82   // The type of this constant.
     83   const analysis::Type* type_;
     84 };
     85 
     86 // Abstract class for scalar type constants.
     87 class ScalarConstant : public Constant {
     88  public:
     89   ScalarConstant() = delete;
     90   ScalarConstant* AsScalarConstant() override { return this; }
     91   const ScalarConstant* AsScalarConstant() const override { return this; }
     92 
     93   // Returns a const reference of the value of this constant in 32-bit words.
     94   virtual const std::vector<uint32_t>& words() const { return words_; }
     95 
     96  protected:
     97   ScalarConstant(const analysis::Type* ty, const std::vector<uint32_t>& w)
     98       : Constant(ty), words_(w) {}
     99   ScalarConstant(const analysis::Type* ty, std::vector<uint32_t>&& w)
    100       : Constant(ty), words_(std::move(w)) {}
    101   std::vector<uint32_t> words_;
    102 };
    103 
    104 // Integer type constant.
    105 class IntConstant : public ScalarConstant {
    106  public:
    107   IntConstant(const analysis::Integer* ty, const std::vector<uint32_t>& w)
    108       : ScalarConstant(ty, w) {}
    109   IntConstant(const analysis::Integer* ty, std::vector<uint32_t>&& w)
    110       : ScalarConstant(ty, std::move(w)) {}
    111 
    112   IntConstant* AsIntConstant() override { return this; }
    113   const IntConstant* AsIntConstant() const override { return this; }
    114 
    115   // Make a copy of this IntConstant instance.
    116   std::unique_ptr<IntConstant> CopyIntConstant() const {
    117     return MakeUnique<IntConstant>(type_->AsInteger(), words_);
    118   }
    119   std::unique_ptr<Constant> Copy() const override {
    120     return std::unique_ptr<Constant>(CopyIntConstant().release());
    121   }
    122 };
    123 
    124 // Float type constant.
    125 class FloatConstant : public ScalarConstant {
    126  public:
    127   FloatConstant(const analysis::Float* ty, const std::vector<uint32_t>& w)
    128       : ScalarConstant(ty, w) {}
    129   FloatConstant(const analysis::Float* ty, std::vector<uint32_t>&& w)
    130       : ScalarConstant(ty, std::move(w)) {}
    131 
    132   FloatConstant* AsFloatConstant() override { return this; }
    133   const FloatConstant* AsFloatConstant() const override { return this; }
    134 
    135   // Make a copy of this FloatConstant instance.
    136   std::unique_ptr<FloatConstant> CopyFloatConstant() const {
    137     return MakeUnique<FloatConstant>(type_->AsFloat(), words_);
    138   }
    139   std::unique_ptr<Constant> Copy() const override {
    140     return std::unique_ptr<Constant>(CopyFloatConstant().release());
    141   }
    142 };
    143 
    144 // Bool type constant.
    145 class BoolConstant : public ScalarConstant {
    146  public:
    147   BoolConstant(const analysis::Bool* ty, bool v)
    148       : ScalarConstant(ty, {static_cast<uint32_t>(v)}), value_(v) {}
    149 
    150   BoolConstant* AsBoolConstant() override { return this; }
    151   const BoolConstant* AsBoolConstant() const override { return this; }
    152 
    153   // Make a copy of this BoolConstant instance.
    154   std::unique_ptr<BoolConstant> CopyBoolConstant() const {
    155     return MakeUnique<BoolConstant>(type_->AsBool(), value_);
    156   }
    157   std::unique_ptr<Constant> Copy() const override {
    158     return std::unique_ptr<Constant>(CopyBoolConstant().release());
    159   }
    160 
    161   bool value() const { return value_; }
    162 
    163  private:
    164   bool value_;
    165 };
    166 
    167 // Abstract class for composite constants.
    168 class CompositeConstant : public Constant {
    169  public:
    170   CompositeConstant() = delete;
    171   CompositeConstant* AsCompositeConstant() override { return this; }
    172   const CompositeConstant* AsCompositeConstant() const override { return this; }
    173 
    174   // Returns a const reference of the components holded in this composite
    175   // constant.
    176   virtual const std::vector<const Constant*>& GetComponents() const {
    177     return components_;
    178   }
    179 
    180  protected:
    181   CompositeConstant(const analysis::Type* ty) : Constant(ty), components_() {}
    182   CompositeConstant(const analysis::Type* ty,
    183                     const std::vector<const Constant*>& components)
    184       : Constant(ty), components_(components) {}
    185   CompositeConstant(const analysis::Type* ty,
    186                     std::vector<const Constant*>&& components)
    187       : Constant(ty), components_(std::move(components)) {}
    188   std::vector<const Constant*> components_;
    189 };
    190 
    191 // Struct type constant.
    192 class StructConstant : public CompositeConstant {
    193  public:
    194   StructConstant(const analysis::Struct* ty) : CompositeConstant(ty) {}
    195   StructConstant(const analysis::Struct* ty,
    196                  const std::vector<const Constant*>& components)
    197       : CompositeConstant(ty, components) {}
    198   StructConstant(const analysis::Struct* ty,
    199                  std::vector<const Constant*>&& components)
    200       : CompositeConstant(ty, std::move(components)) {}
    201 
    202   StructConstant* AsStructConstant() override { return this; }
    203   const StructConstant* AsStructConstant() const override { return this; }
    204 
    205   // Make a copy of this StructConstant instance.
    206   std::unique_ptr<StructConstant> CopyStructConstant() const {
    207     return MakeUnique<StructConstant>(type_->AsStruct(), components_);
    208   }
    209   std::unique_ptr<Constant> Copy() const override {
    210     return std::unique_ptr<Constant>(CopyStructConstant().release());
    211   }
    212 };
    213 
    214 // Vector type constant.
    215 class VectorConstant : public CompositeConstant {
    216  public:
    217   VectorConstant(const analysis::Vector* ty)
    218       : CompositeConstant(ty), component_type_(ty->element_type()) {}
    219   VectorConstant(const analysis::Vector* ty,
    220                  const std::vector<const Constant*>& components)
    221       : CompositeConstant(ty, components),
    222         component_type_(ty->element_type()) {}
    223   VectorConstant(const analysis::Vector* ty,
    224                  std::vector<const Constant*>&& components)
    225       : CompositeConstant(ty, std::move(components)),
    226         component_type_(ty->element_type()) {}
    227 
    228   VectorConstant* AsVectorConstant() override { return this; }
    229   const VectorConstant* AsVectorConstant() const override { return this; }
    230 
    231   // Make a copy of this VectorConstant instance.
    232   std::unique_ptr<VectorConstant> CopyVectorConstant() const {
    233     auto another = MakeUnique<VectorConstant>(type_->AsVector());
    234     another->components_.insert(another->components_.end(), components_.begin(),
    235                                 components_.end());
    236     return another;
    237   }
    238   std::unique_ptr<Constant> Copy() const override {
    239     return std::unique_ptr<Constant>(CopyVectorConstant().release());
    240   }
    241 
    242   const analysis::Type* component_type() { return component_type_; }
    243 
    244  private:
    245   const analysis::Type* component_type_;
    246 };
    247 
    248 // Array type constant.
    249 class ArrayConstant : public CompositeConstant {
    250  public:
    251   ArrayConstant(const analysis::Array* ty) : CompositeConstant(ty) {}
    252   ArrayConstant(const analysis::Array* ty,
    253                 const std::vector<const Constant*>& components)
    254       : CompositeConstant(ty, components) {}
    255   ArrayConstant(const analysis::Array* ty,
    256                 std::vector<const Constant*>&& components)
    257       : CompositeConstant(ty, std::move(components)) {}
    258 
    259   ArrayConstant* AsArrayConstant() override { return this; }
    260   const ArrayConstant* AsArrayConstant() const override { return this; }
    261 
    262   // Make a copy of this ArrayConstant instance.
    263   std::unique_ptr<ArrayConstant> CopyArrayConstant() const {
    264     return MakeUnique<ArrayConstant>(type_->AsArray(), components_);
    265   }
    266   std::unique_ptr<Constant> Copy() const override {
    267     return std::unique_ptr<Constant>(CopyArrayConstant().release());
    268   }
    269 };
    270 
    271 // Null type constant.
    272 class NullConstant : public Constant {
    273  public:
    274   NullConstant(const analysis::Type* ty) : Constant(ty) {}
    275   NullConstant* AsNullConstant() override { return this; }
    276   const NullConstant* AsNullConstant() const override { return this; }
    277 
    278   // Make a copy of this NullConstant instance.
    279   std::unique_ptr<NullConstant> CopyNullConstant() const {
    280     return MakeUnique<NullConstant>(type_);
    281   }
    282   std::unique_ptr<Constant> Copy() const override {
    283     return std::unique_ptr<Constant>(CopyNullConstant().release());
    284   }
    285 };
    286 
    287 }  // namespace analysis
    288 }  // namespace opt
    289 }  // namespace spvtools
    290 
    291 #endif  // LIBSPIRV_OPT_CONSTANTS_H_
    292