/*
* 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 <vector>
#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<uint32_t> 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<Instruction *>(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<WordStream> mStreamFunctions;
std::unique_ptr<WordStream> mStreamFinal;
WordStream *mStream;
};
} // namespace spirit
} // namespace android
#endif // TRANSFORMER_H