1 // Copyright (c) 2019 Google LLC 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_OPT_WRAP_OPKILL_H_ 16 #define SOURCE_OPT_WRAP_OPKILL_H_ 17 18 #include "source/opt/pass.h" 19 20 namespace spvtools { 21 namespace opt { 22 23 // Documented in optimizer.hpp 24 class WrapOpKill : public Pass { 25 public: WrapOpKill()26 WrapOpKill() : void_type_id_(0) {} 27 name()28 const char* name() const override { return "wrap-opkill"; } 29 30 Status Process() override; 31 GetPreservedAnalyses()32 IRContext::Analysis GetPreservedAnalyses() override { 33 return IRContext::kAnalysisDefUse | 34 IRContext::kAnalysisInstrToBlockMapping | 35 IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | 36 IRContext::kAnalysisNameMap | IRContext::kAnalysisBuiltinVarId | 37 IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; 38 } 39 40 private: 41 // Replaces the OpKill or OpTerminateInvocation instruction |inst| with a 42 // function call to a function that contains a single instruction, a clone of 43 // |inst|. An OpUnreachable instruction will be placed after the function 44 // call. Return true if successful. 45 bool ReplaceWithFunctionCall(Instruction* inst); 46 47 // Returns the id of the void type. 48 uint32_t GetVoidTypeId(); 49 50 // Returns the id of the function type for a void function with no parameters. 51 uint32_t GetVoidFunctionTypeId(); 52 53 // Return the id of a function that has return type void, has no parameters, 54 // and contains a single instruction, which is |opcode|, either OpKill or 55 // OpTerminateInvocation. Returns 0 if the function could not be generated. 56 uint32_t GetKillingFuncId(SpvOp opcode); 57 58 // Returns the id of the return type for the function that contains |inst|. 59 // Returns 0 if |inst| is not in a function. 60 uint32_t GetOwningFunctionsReturnType(Instruction* inst); 61 62 // The id of the void type. If its value is 0, then the void type has not 63 // been found or created yet. 64 uint32_t void_type_id_; 65 66 // The function that is a single instruction, which is an OpKill. The 67 // function has a void return type and takes no parameters. If the function is 68 // |nullptr|, then the function has not been generated. 69 std::unique_ptr<Function> opkill_function_; 70 // The function that is a single instruction, which is an 71 // OpTerminateInvocation. The function has a void return type and takes no 72 // parameters. If the function is |nullptr|, then the function has not been 73 // generated. 74 std::unique_ptr<Function> opterminateinvocation_function_; 75 }; 76 77 } // namespace opt 78 } // namespace spvtools 79 80 #endif // SOURCE_OPT_WRAP_OPKILL_H_ 81