Home | History | Annotate | Download | only in source
      1 // Copyright (c) 2015-2016 The Khronos Group 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 SOURCE_OPERAND_H_
     16 #define SOURCE_OPERAND_H_
     17 
     18 #include <functional>
     19 #include <vector>
     20 
     21 #include "source/table.h"
     22 #include "spirv-tools/libspirv.h"
     23 
     24 // A sequence of operand types.
     25 //
     26 // A SPIR-V parser uses an operand pattern to describe what is expected
     27 // next on the input.
     28 //
     29 // As we parse an instruction in text or binary form from left to right,
     30 // we pop and push at the end of the pattern vector. Symbols later in the
     31 // pattern vector are matched against the input before symbols earlier in the
     32 // pattern vector are matched.
     33 
     34 // Using a vector in this way reduces memory traffic, which is good for
     35 // performance.
     36 using spv_operand_pattern_t = std::vector<spv_operand_type_t>;
     37 
     38 // Finds the named operand in the table. The type parameter specifies the
     39 // operand's group. A handle of the operand table entry for this operand will
     40 // be written into *entry.
     41 spv_result_t spvOperandTableNameLookup(spv_target_env,
     42                                        const spv_operand_table table,
     43                                        const spv_operand_type_t type,
     44                                        const char* name,
     45                                        const size_t name_length,
     46                                        spv_operand_desc* entry);
     47 
     48 // Finds the operand with value in the table. The type parameter specifies the
     49 // operand's group. A handle of the operand table entry for this operand will
     50 // be written into *entry.
     51 spv_result_t spvOperandTableValueLookup(spv_target_env,
     52                                         const spv_operand_table table,
     53                                         const spv_operand_type_t type,
     54                                         const uint32_t value,
     55                                         spv_operand_desc* entry);
     56 
     57 // Gets the name string of the non-variable operand type.
     58 const char* spvOperandTypeStr(spv_operand_type_t type);
     59 
     60 // Returns true if the given type is concrete.
     61 bool spvOperandIsConcrete(spv_operand_type_t type);
     62 
     63 // Returns true if the given type is concrete and also a mask.
     64 bool spvOperandIsConcreteMask(spv_operand_type_t type);
     65 
     66 // Returns true if an operand of the given type is optional.
     67 bool spvOperandIsOptional(spv_operand_type_t type);
     68 
     69 // Returns true if an operand type represents zero or more logical operands.
     70 //
     71 // Note that a single logical operand may still be a variable number of words.
     72 // For example, a literal string may be many words, but is just one logical
     73 // operand.
     74 bool spvOperandIsVariable(spv_operand_type_t type);
     75 
     76 // Append a list of operand types to the end of the pattern vector.
     77 // The types parameter specifies the source array of types, ending with
     78 // SPV_OPERAND_TYPE_NONE.
     79 void spvPushOperandTypes(const spv_operand_type_t* types,
     80                          spv_operand_pattern_t* pattern);
     81 
     82 // Appends the operands expected after the given typed mask onto the
     83 // end of the given pattern.
     84 //
     85 // Each set bit in the mask represents zero or more operand types that should
     86 // be appended onto the pattern.  Operands for a less significant bit always
     87 // appear after operands for a more significant bit.
     88 //
     89 // If a set bit is unknown, then we assume it has no operands.
     90 void spvPushOperandTypesForMask(spv_target_env,
     91                                 const spv_operand_table operand_table,
     92                                 const spv_operand_type_t mask_type,
     93                                 const uint32_t mask,
     94                                 spv_operand_pattern_t* pattern);
     95 
     96 // Expands an operand type representing zero or more logical operands,
     97 // exactly once.
     98 //
     99 // If the given type represents potentially several logical operands,
    100 // then prepend the given pattern with the first expansion of the logical
    101 // operands, followed by original type.  Otherwise, don't modify the pattern.
    102 //
    103 // For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
    104 // IDs.  In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
    105 // followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
    106 //
    107 // This also applies to zero or more tuples of logical operands.  In that case
    108 // we prepend pattern with for the members of the tuple, followed by the
    109 // original type argument.  The pattern must encode the fact that if any part
    110 // of the tuple is present, then all tuple members should be.  So the first
    111 // member of the tuple must be optional, and the remaining members
    112 // non-optional.
    113 //
    114 // Returns true if we modified the pattern.
    115 bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
    116                                   spv_operand_pattern_t* pattern);
    117 
    118 // Expands the first element in the pattern until it is a matchable operand
    119 // type, then pops it off the front and returns it.  The pattern must not be
    120 // empty.
    121 //
    122 // A matchable operand type is anything other than a zero-or-more-items
    123 // operand type.
    124 spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);
    125 
    126 // Calculates the corresponding post-immediate alternate pattern, which allows
    127 // a limited set of operand types.
    128 spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
    129     const spv_operand_pattern_t& pattern);
    130 
    131 // Is the operand an ID?
    132 bool spvIsIdType(spv_operand_type_t type);
    133 
    134 // Is the operand an input ID?
    135 bool spvIsInIdType(spv_operand_type_t type);
    136 
    137 // Takes the opcode of an instruction and returns
    138 // a function object that will return true if the index
    139 // of the operand can be forward declared. This function will
    140 // used in the SSA validation stage of the pipeline
    141 std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
    142     SpvOp opcode);
    143 
    144 #endif  // SOURCE_OPERAND_H_
    145