| 889 | } |
| 890 | |
| 891 | opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id, |
| 892 | uint32_t type_id, |
| 893 | spv::StorageClass storage_class, |
| 894 | uint32_t initializer_id) { |
| 895 | // Check various preconditions. |
| 896 | assert(result_id != 0 && "Result id can't be 0"); |
| 897 | |
| 898 | assert((storage_class == spv::StorageClass::Private || |
| 899 | storage_class == spv::StorageClass::Workgroup) && |
| 900 | "Variable's storage class must be either Private or Workgroup"); |
| 901 | |
| 902 | auto* type_inst = context->get_def_use_mgr()->GetDef(type_id); |
| 903 | (void)type_inst; // Variable becomes unused in release mode. |
| 904 | assert(type_inst && type_inst->opcode() == spv::Op::OpTypePointer && |
| 905 | GetStorageClassFromPointerType(type_inst) == storage_class && |
| 906 | "Variable's type is invalid"); |
| 907 | |
| 908 | if (storage_class == spv::StorageClass::Workgroup) { |
| 909 | assert(initializer_id == 0); |
| 910 | } |
| 911 | |
| 912 | if (initializer_id != 0) { |
| 913 | const auto* constant_inst = |
| 914 | context->get_def_use_mgr()->GetDef(initializer_id); |
| 915 | (void)constant_inst; // Variable becomes unused in release mode. |
| 916 | assert(constant_inst && spvOpcodeIsConstant(constant_inst->opcode()) && |
| 917 | GetPointeeTypeIdFromPointerType(type_inst) == |
| 918 | constant_inst->type_id() && |
| 919 | "Initializer is invalid"); |
| 920 | } |
| 921 | |
| 922 | opt::Instruction::OperandList operands = { |
| 923 | {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast<uint32_t>(storage_class)}}}; |
| 924 | |
| 925 | if (initializer_id) { |
| 926 | operands.push_back({SPV_OPERAND_TYPE_ID, {initializer_id}}); |
| 927 | } |
| 928 | |
| 929 | auto new_instruction = MakeUnique<opt::Instruction>( |
| 930 | context, spv::Op::OpVariable, type_id, result_id, std::move(operands)); |
| 931 | auto result = new_instruction.get(); |
| 932 | context->module()->AddGlobalValue(std::move(new_instruction)); |
| 933 | |
| 934 | AddVariableIdToEntryPointInterfaces(context, result_id); |
| 935 | UpdateModuleIdBound(context, result_id); |
| 936 | |
| 937 | return result; |
| 938 | } |
| 939 | |
| 940 | opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id, |
| 941 | uint32_t type_id, uint32_t function_id, |
no test coverage detected