/* * Copyright 2017, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TRANSFORMER_H #define TRANSFORMER_H #include #include "instructions.h" #include "pass.h" #include "visitor.h" #include "word_stream.h" namespace android { namespace spirit { // Transformer is the base class for a transformation that transforms a Module. // An instance of a derived class can be added to a PassQueue and applied to a // Module. class Transformer : public Pass, public DoNothingVisitor { public: Transformer() : mStreamFunctions(WordStream::Create()), mStreamFinal(WordStream::Create()) {} virtual ~Transformer() {} Module *run(Module *m, int *error = nullptr) override; std::vector runAndSerialize(Module *module, int *error = nullptr) override; // Returns the module being transformed Module *getModule() const { return mModule; } // Inserts a new instruction before the current instruction. // Call this from a transform() method in a derived class. void insert(Instruction *); void visit(FunctionDefinition *fdef) override { mShouldRecord = (mVisit == 0); DoNothingVisitor::visit(fdef); } // Transforms the current instruction into a new instruction as specified by // the return value. If returns nullptr, deletes the current instruction. // Override this in a derived class for desired behavior. #define HANDLE_INSTRUCTION(OPCODE, INST_CLASS) \ virtual Instruction *transform(INST_CLASS *inst) { \ return static_cast(inst); \ } \ virtual void visit(INST_CLASS *inst) { \ if (!mShouldRecord) { \ return; \ } \ if (Instruction *transformed = transform(inst)) { \ transformed->Serialize(*mStream); \ } \ } #include "instruction_dispatches_generated.h" #undef HANDLE_INSTRUCTION private: Module *mModule; int mVisit; bool mShouldRecord; std::unique_ptr mStreamFunctions; std::unique_ptr mStreamFinal; WordStream *mStream; }; } // namespace spirit } // namespace android #endif // TRANSFORMER_H