Add Simple return instruction to Mips fast-isel
authorReed Kotler <rkotler@mips.com>
Tue, 29 Apr 2014 17:57:50 +0000 (17:57 +0000)
committerReed Kotler <rkotler@mips.com>
Tue, 29 Apr 2014 17:57:50 +0000 (17:57 +0000)
Reviewers: dsanders

Reviewed by: dsanders

Differential Revision: http://reviews.llvm.org/D3430

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207565 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsFastISel.cpp
test/CodeGen/Mips/Fast-ISel/nullvoid.ll [new file with mode: 0644]

index 70579bd270f05fe4b9e4ef2f66d6f584ce48498c..c85be1e553c9e6db0fabf9ca44ccc7569bac535a 100644 (file)
@@ -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 @@ namespace {
 
 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<Module &>(*funcInfo.Fn->getParent())),
+        TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()),
+        TLI(*TM.getTargetLowering()) {
+    Subtarget = &TM.getSubtarget<MipsSubtarget>();
+    MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();
+    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<ReturnInst>(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 {
diff --git a/test/CodeGen/Mips/Fast-ISel/nullvoid.ll b/test/CodeGen/Mips/Fast-ISel/nullvoid.ll
new file mode 100644 (file)
index 0000000..eeaff87
--- /dev/null
@@ -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
+}