Index: lib/Target/Mips/MipsFastISel.cpp =================================================================== --- lib/Target/Mips/MipsFastISel.cpp +++ lib/Target/Mips/MipsFastISel.cpp @@ -3,8 +3,13 @@ #include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/FastISel.h" + +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLibraryInfo.h" #include "MipsISelLowering.h" +#include "MipsMachineFunction.h" +#include "MipsSubtarget.h" using namespace llvm; @@ -12,12 +17,63 @@ class MipsFastISel final : public FastISel { + /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can + /// make the right decision when generating code for different targets. + const MipsSubtarget *Subtarget; + Module &M; + const TargetMachine &TM; + const TargetInstrInfo &TII; + const TargetLowering &TLI; + MipsFunctionInfo *MFI; + + // Convenience variables to avoid some queries. + LLVMContext *Context; + + bool TargetSupported; + public: explicit MipsFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) - : FastISel(funcInfo, libInfo) {} - bool TargetSelectInstruction(const Instruction *I) override { return false; } + : FastISel(funcInfo, libInfo), + M(const_cast(*funcInfo.Fn->getParent())), + TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()), + TLI(*TM.getTargetLowering()) { + Subtarget = &TM.getSubtarget(); + MFI = funcInfo.MF->getInfo(); + Context = &funcInfo.Fn->getContext(); + TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && + (Subtarget->hasMips32r2() && (Subtarget->isABI_O32()))); + } + + bool TargetSelectInstruction(const Instruction *I) override; + + bool SelectRet(const Instruction *I); }; + +bool MipsFastISel::SelectRet(const Instruction *I) { + const ReturnInst *Ret = cast(I); + + if (!FuncInfo.CanLowerReturn) + return false; + if (Ret->getNumOperands() > 0) { + return false; + } + unsigned RetOpc = Mips::RetRA; + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(RetOpc)); + return true; +} + +bool MipsFastISel::TargetSelectInstruction(const Instruction *I) { + if (!TargetSupported) + return false; + switch (I->getOpcode()) { + default: + break; + case Instruction::Ret: + return SelectRet(I); + } + return false; +} } namespace llvm { Index: test/CodeGen/Mips/Fast-ISel/nullvoid.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/Fast-ISel/nullvoid.ll @@ -0,0 +1,9 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +; Function Attrs: nounwind +define void @foo() { +entry: + ret void +; CHECK: jr $ra +}