class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
+class TargetLowering;
// Technically the pass should run on an hypothetical MachineModule,
// since it should translate Global into some sort of MachineGlobal.
private:
// Interface used to lower the everything related to calls.
- // TargetLowering *CallLowering;
+ const TargetLowering *TLI;
// Mapping of the values of the current LLVM IR function
// to the related virtual registers.
// We need several virtual registers for the lowering of things
// 3. Create the generic instruction.
bool translateADD(const Instruction &Inst);
+ bool translateReturn(const Instruction &Inst);
+
// Builder for machine instruction a la IRBuilder.
// I.e., compared to regular MIBuilder, this one also inserts the instruction
// in the current block, it can creates block, etc., basically a kind of
/// Set the debug location to \p DL for all the next build instructions.
void setDebugLoc(const DebugLoc &DL) { this->DL = DL; }
+ /// Build and insert \p Res<def> = \p Opcode [\p Ty] \p Op0, \p Op1.
+ /// \p Ty is the type of the instruction if \p Opcode describes
+ /// a generic machine instruction. \p Ty must be nullptr if \p Opcode
+ /// does not describe a generic instruction.
+ /// The insertion point is the one set by the last call of either
+ /// setBasicBlock or setMI.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildInstr(unsigned Opcode, Type *Ty, unsigned Res,
+ unsigned Op0, unsigned Op1);
+
/// Build and insert \p Res<def> = \p Opcode \p Op0, \p Op1.
+ /// I.e., instruction with a non-generic opcode.
///
/// \pre setBasicBlock or setMI must have been called.
///
/// \return The newly created instruction.
MachineInstr *buildInstr(unsigned Opcode, unsigned Res, unsigned Op0,
unsigned Op1);
+
+ /// Build and insert \p Res<def> = \p Opcode \p Op0.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildInstr(unsigned Opcode, unsigned Res, unsigned Op0);
+
+ /// Build and insert = \p Opcode.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildInstr(unsigned Opcode);
};
} // End namespace llvm.
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/DAGCombine.h"
+#ifdef LLVM_BUILD_GLOBAL_ISEL
+#include "llvm/CodeGen/GlobalISel/Types.h"
+#endif
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/IR/Attributes.h"
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
+#ifdef LLVM_BUILD_GLOBAL_ISEL
+ class MachineIRBuilder;
+#endif
class MachineJumpTableInfo;
class MachineLoop;
class Mangler;
llvm_unreachable("Not Implemented");
}
+#ifdef LLVM_BUILD_GLOBAL_ISEL
+ virtual bool LowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
+ unsigned VReg) const {
+ return false;
+ }
+#endif
+
/// Return true if result of the specified node is used by a return node
/// only. It also compute and return the input chain for the tail call.
///
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
+#include "llvm/Target/TargetLowering.h"
#define DEBUG_TYPE "irtranslator"
unsigned Op0 = *getOrCreateVRegs(Inst.getOperand(0)).begin();
unsigned Op1 = *getOrCreateVRegs(Inst.getOperand(1)).begin();
unsigned Res = *getOrCreateVRegs(&Inst).begin();
- MIRBuilder.buildInstr(TargetOpcode::G_ADD, Res, Op0, Op1);
+ MIRBuilder.buildInstr(TargetOpcode::G_ADD, Inst.getType(), Res, Op0, Op1);
return true;
}
+bool IRTranslator::translateReturn(const Instruction &Inst) {
+ assert(isa<ReturnInst>(Inst) && "Return expected");
+ const Value *Ret = cast<ReturnInst>(Inst).getReturnValue();
+ // The target may mess up with the insertion point, but
+ // this is not important as a return is the last instruction
+ // of the block anyway.
+ return TLI->LowerReturn(MIRBuilder, Ret,
+ !Ret ? 0 : *getOrCreateVRegs(Ret).begin());
+}
+
bool IRTranslator::translate(const Instruction &Inst) {
MIRBuilder.setDebugLoc(Inst.getDebugLoc());
switch(Inst.getOpcode()) {
- case Instruction::Add: {
- return translateADD(Inst);
- default:
- llvm_unreachable("Opcode not supported");
- }
+ case Instruction::Add:
+ return translateADD(Inst);
+ case Instruction::Ret:
+ return translateReturn(Inst);
+
+ default:
+ llvm_unreachable("Opcode not supported");
}
}
bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
const Function &F = *MF.getFunction();
+ TLI = MF.getSubtarget().getTargetLowering();
MIRBuilder.setFunction(MF);
MRI = &MF.getRegInfo();
for (const BasicBlock &BB: F) {
MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
unsigned Op0, unsigned Op1) {
+ return buildInstr(Opcode, nullptr, Res, Op0, Op1);
+}
+
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
+ unsigned Res, unsigned Op0,
+ unsigned Op1) {
MachineInstr *NewMI =
BuildMI(getMF(), DL, getTII().get(Opcode), Res).addReg(Op0).addReg(Op1);
+ if (Ty)
+ NewMI->setType(Ty);
+ getMBB().insert(getInsertPt(), NewMI);
+ return NewMI;
+}
+
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
+ unsigned Op0) {
+ MachineInstr *NewMI =
+ BuildMI(getMF(), DL, getTII().get(Opcode), Res).addReg(Op0);
+ getMBB().insert(getInsertPt(), NewMI);
+ return NewMI;
+}
+
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) {
+ MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
getMBB().insert(getInsertPt(), NewMI);
return NewMI;
}