1 // Copyright (c) 2017 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 SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ 16 #define SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ 17 18 #include "source/opt/ir_context.h" 19 #include "source/opt/pass.h" 20 21 namespace spvtools { 22 namespace opt { 23 24 // This pass implements total redundancy elimination. This is the same as 25 // local redundancy elimination except it looks across basic block boundaries. 26 // An instruction, inst, is totally redundant if there is another instruction 27 // that dominates inst, and also computes the same value. 28 class PrivateToLocalPass : public Pass { 29 public: name()30 const char* name() const override { return "private-to-local"; } 31 Status Process() override; 32 GetPreservedAnalyses()33 IRContext::Analysis GetPreservedAnalyses() override { 34 return IRContext::kAnalysisDefUse | 35 IRContext::kAnalysisInstrToBlockMapping | 36 IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | 37 IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | 38 IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | 39 IRContext::kAnalysisTypes; 40 } 41 42 private: 43 // Moves |variable| from the private storage class to the function storage 44 // class of |function|. Returns false if the variable could not be moved. 45 bool MoveVariable(Instruction* variable, Function* function); 46 47 // |inst| is an instruction declaring a varible. If that variable is 48 // referenced in a single function and all of uses are valid as defined by 49 // |IsValidUse|, then that function is returned. Otherwise, the return 50 // value is |nullptr|. 51 Function* FindLocalFunction(const Instruction& inst) const; 52 53 // Returns true is |inst| is a valid use of a pointer. In this case, a 54 // valid use is one where the transformation is able to rewrite the type to 55 // match a change in storage class of the original variable. 56 bool IsValidUse(const Instruction* inst) const; 57 58 // Given the result id of a pointer type, |old_type_id|, this function 59 // returns the id of a the same pointer type except the storage class has 60 // been changed to function. If the type does not already exist, it will be 61 // created. Returns 0 if the new type could not be found or generated. 62 uint32_t GetNewType(uint32_t old_type_id); 63 64 // Updates |inst|, and any instruction dependent on |inst|, to reflect the 65 // change of the base pointer now pointing to the function storage class. 66 bool UpdateUse(Instruction* inst, Instruction* user); 67 bool UpdateUses(Instruction* inst); 68 }; 69 70 } // namespace opt 71 } // namespace spvtools 72 73 #endif // SOURCE_OPT_PRIVATE_TO_LOCAL_PASS_H_ 74