#define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
#include "Types.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/IR/Constants.h"
// registers, but we would need to encapsulate that in a higher
// level class.
ValueToVRegs ValToVRegs;
- // Mapping of a constant to the instructions to produce
- // that constant.
// Constants are special because when we encounter one,
// we do not know at first where to insert the definition since
// this depends on all its uses.
// Thus, we will insert the sequences to materialize them when
// we know all their users.
- // In the meantime, just keep it in a map.
+ // In the meantime, just keep it in a set.
// Note: Constants that end up as immediate in the related instructions,
// do not appear in that map.
- DenseMap<const Constant *, SmallVector<MachineInstr *, 1>> ConstantToSequence;
+ SmallSetVector<const Constant *, 8> Constants;
/* A bunch of methods targeting ADD, SUB, etc. */
// Return true if the translation was successful, false
// 2 Update the ValToVReg accordingly.
// 2.alt. For constant arguments, if they are compile time constants,
// produce an immediate in the right operand and do not touch
- // ValToReg. Otherwise, update ValToVReg and register the
- // sequence to materialize the constant in ConstantToSequence.
+ // ValToReg. Actually we will go with a virtual register for each
+ // constants because it may be expensive to actually materialize the
+ // constant. Moreover, if the constant spans on several instructions,
+ // CSE may not catch them.
+ // => Update ValToVReg and remember that we saw a constant in Constants.
+ // We will materialize all the constants in finalize.
+ // Note: we would need to do something so that we can recognize such operand
+ // as constants.
// 3. Create the generic instruction.
bool translateADD(const Instruction &Inst);
// * Insert all the code needed to materialize the constants
// at the proper place. E.g., Entry block or dominator block
- // of each constant depending ob how fancy we want to be.
+ // of each constant depending on how fancy we want to be.
// * Clear the different maps.
void finalize();
public:
// Ctor, nothing fancy.
IRTranslator();
- // Instead of having the instance of the IRTranslatorToolkit
- // as an argument of the constructor of IRTranslator, we ask
- // the target the instance of the toolkit for each MachineFunction.
- // The interest is that we may have different translator for different
- // subtract or optimization. E.g., we could have a translator optimized
- // to produce small code size.
- //
// Algo:
// CallLowering = MF.subtarget.getCallLowering()
// F = MF.getParent()
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/Function.h"
+
+#define DEBUG_TYPE "irtranslator"
+
using namespace llvm;
char IRTranslator::ID = 0;
bool IRTranslator::translateADD(const Instruction &Inst) {
+ // Get or create a virtual register for each value.
+ // Unless the value is a Constant => loadimm cst?
+ // or inline constant each time?
+ // Creation of a virtual register needs to have a size.
return false;
}
-bool IRTranslator::translate(const Instruction &) {
- return false;
+bool IRTranslator::translate(const Instruction &Inst) {
+ switch(Inst.getOpcode()) {
+ case Instruction::Add: {
+ return translateADD(Inst);
+ default:
+ llvm_unreachable("Opcode not supported");
+ }
+ }
}
void IRTranslator::finalize() {
+ // Release the memory used by the different maps we
+ // needed during the translation.
+ ValToVRegs.clear();
+ Constants.clear();
}
IRTranslator::IRTranslator()
}
bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
+ const Function &F = *MF.getFunction();
+ for (const BasicBlock &BB: F) {
+ for (const Instruction &Inst: BB) {
+ bool Succeeded = translate(Inst);
+ if (!Succeeded) {
+ DEBUG(dbgs() << "Cannot translate: " << Inst << '\n');
+ report_fatal_error("Unable to translate instruction");
+ }
+ }
+ }
return false;
}