forked from OSchip/llvm-project
[GlobalISel] Teach the IRTranslator how to lower returns.
llvm-svn: 260562
This commit is contained in:
parent
d077c29c80
commit
74d7d2f00b
|
@ -34,6 +34,7 @@ class MachineBasicBlock;
|
|||
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.
|
||||
|
@ -49,7 +50,7 @@ public:
|
|||
|
||||
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
|
||||
|
@ -92,6 +93,8 @@ private:
|
|||
// 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
|
||||
|
|
|
@ -84,13 +84,41 @@ public:
|
|||
/// 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.
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#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"
|
||||
|
@ -50,6 +53,9 @@ namespace llvm {
|
|||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
#ifdef LLVM_BUILD_GLOBAL_ISEL
|
||||
class MachineIRBuilder;
|
||||
#endif
|
||||
class MachineJumpTableInfo;
|
||||
class MachineLoop;
|
||||
class Mangler;
|
||||
|
@ -2506,6 +2512,13 @@ public:
|
|||
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.
|
||||
///
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
|
||||
#define DEBUG_TYPE "irtranslator"
|
||||
|
||||
|
@ -65,18 +66,30 @@ bool IRTranslator::translateADD(const Instruction &Inst) {
|
|||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +103,7 @@ void IRTranslator::finalize() {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -54,8 +54,30 @@ MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() {
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue