[llvm] [LoongArch][GlobalISel] Adding initial GlobalISel infrastructure (PR #116005)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 24 18:46:32 PST 2024


https://github.com/zhaoqi5 updated https://github.com/llvm/llvm-project/pull/116005

>From 1a22a09040c442d37c02f692e1857195de21eb6b Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Wed, 13 Nov 2024 14:27:21 +0800
Subject: [PATCH 1/3] [LoongArch][GlobalISel] Adding initial GlobalISel
 infrastructure

Add an initial GlobalISel skeleton for LoongArch. It can
only run ir translator for `ret void`.
---
 llvm/lib/Target/LoongArch/CMakeLists.txt      |   7 ++
 .../LoongArch/GISel/LoongArchCallLowering.cpp |  49 +++++++++
 .../LoongArch/GISel/LoongArchCallLowering.h   |  44 ++++++++
 .../GISel/LoongArchInstructionSelector.cpp    | 102 ++++++++++++++++++
 .../GISel/LoongArchLegalizerInfo.cpp          |  24 +++++
 .../LoongArch/GISel/LoongArchLegalizerInfo.h  |  29 +++++
 .../GISel/LoongArchRegisterBankInfo.cpp       |  27 +++++
 .../GISel/LoongArchRegisterBankInfo.h         |  39 +++++++
 .../LoongArch/GISel/LoongArchRegisterBanks.td |  16 +++
 llvm/lib/Target/LoongArch/LoongArch.h         |   8 ++
 llvm/lib/Target/LoongArch/LoongArch.td        |   1 +
 .../Target/LoongArch/LoongArchSubtarget.cpp   |  31 ++++++
 .../lib/Target/LoongArch/LoongArchSubtarget.h |  17 +++
 .../LoongArch/LoongArchTargetMachine.cpp      |  30 ++++++
 .../LoongArch/GlobalISel/calllowering-ret.ll  |  17 +++
 .../GlobalISel/irtranslator-calllowering.ll   |  17 +++
 16 files changed, 458 insertions(+)
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.h
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchInstructionSelector.cpp
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.cpp
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.h
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.cpp
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.h
 create mode 100644 llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
 create mode 100644 llvm/test/CodeGen/LoongArch/GlobalISel/calllowering-ret.ll
 create mode 100644 llvm/test/CodeGen/LoongArch/GlobalISel/irtranslator-calllowering.ll

diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index 0f674b1b0fa9e2..14b414c53aab06 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -6,15 +6,21 @@ tablegen(LLVM LoongArchGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM LoongArchGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM LoongArchGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM LoongArchGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM LoongArchGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
+tablegen(LLVM LoongArchGenRegisterBank.inc -gen-register-bank)
 tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info)
 tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(LoongArchCommonTableGen)
 
 add_llvm_target(LoongArchCodeGen
+  GISel/LoongArchCallLowering.cpp
+  GISel/LoongArchInstructionSelector.cpp
+  GISel/LoongArchLegalizerInfo.cpp
+  GISel/LoongArchRegisterBankInfo.cpp
   LoongArchAsmPrinter.cpp
   LoongArchDeadRegisterDefinitions.cpp
   LoongArchExpandAtomicPseudoInsts.cpp
@@ -37,6 +43,7 @@ add_llvm_target(LoongArchCodeGen
   CodeGen
   CodeGenTypes
   Core
+  GlobalISel
   LoongArchDesc
   LoongArchInfo
   MC
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
new file mode 100644
index 00000000000000..66671b331d9461
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
@@ -0,0 +1,49 @@
+//===-- LoongArchCallLowering.cpp - Call lowering ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file implements the lowering of LLVM calls to machine code calls for
+/// GlobalISel.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchCallLowering.h"
+#include "LoongArchISelLowering.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+
+using namespace llvm;
+
+LoongArchCallLowering::LoongArchCallLowering(const LoongArchTargetLowering &TLI)
+    : CallLowering(&TLI) {}
+
+bool LoongArchCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
+                                        const Value *Val,
+                                        ArrayRef<Register> VRegs,
+                                        FunctionLoweringInfo &FLI) const {
+  MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(LoongArch::PseudoRET);
+
+  if (Val != nullptr)
+    return false;
+
+  MIRBuilder.insertInstr(Ret);
+  return true;
+}
+
+bool LoongArchCallLowering::lowerFormalArguments(
+    MachineIRBuilder &MIRBuilder, const Function &F,
+    ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const {
+  if (F.arg_empty())
+    return true;
+
+  return false;
+}
+
+bool LoongArchCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
+                                      CallLoweringInfo &Info) const {
+  return false;
+}
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.h b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.h
new file mode 100644
index 00000000000000..3200eaec2bafc5
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.h
@@ -0,0 +1,44 @@
+//===-- LoongArchCallLowering.h - Call lowering -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file describes how to lower LLVM calls to machine code calls.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHCALLLOWERING_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHCALLLOWERING_H
+
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+
+namespace llvm {
+
+class LoongArchTargetLowering;
+class MachineIRBuilder;
+
+class LoongArchCallLowering : public CallLowering {
+
+public:
+  LoongArchCallLowering(const LoongArchTargetLowering &TLI);
+
+  bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
+                   ArrayRef<Register> VRegs,
+                   FunctionLoweringInfo &FLI) const override;
+
+  bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
+                            ArrayRef<ArrayRef<Register>> VRegs,
+                            FunctionLoweringInfo &FLI) const override;
+
+  bool lowerCall(MachineIRBuilder &MIRBuilder,
+                 CallLoweringInfo &Info) const override;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHCALLLOWERING_H
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchInstructionSelector.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchInstructionSelector.cpp
new file mode 100644
index 00000000000000..1a7d2a8f60923a
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchInstructionSelector.cpp
@@ -0,0 +1,102 @@
+//===-- LoongArchInstructionSelector.cpp -------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the InstructionSelector class for
+/// LoongArch.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchRegisterBankInfo.h"
+#include "LoongArchSubtarget.h"
+#include "LoongArchTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/IR/IntrinsicsLoongArch.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "loongarch-isel"
+
+using namespace llvm;
+
+#define GET_GLOBALISEL_PREDICATE_BITSET
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATE_BITSET
+
+namespace {
+
+class LoongArchInstructionSelector : public InstructionSelector {
+public:
+  LoongArchInstructionSelector(const LoongArchTargetMachine &TM,
+                               const LoongArchSubtarget &STI,
+                               const LoongArchRegisterBankInfo &RBI);
+
+  bool select(MachineInstr &MI) override;
+
+  static const char *getName() { return DEBUG_TYPE; }
+
+private:
+  // tblgen-erated 'select' implementation, used as the initial selector for
+  // the patterns that don't require complex C++.
+  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+
+  const LoongArchSubtarget &STI;
+  const LoongArchInstrInfo &TII;
+  const LoongArchRegisterInfo &TRI;
+  const LoongArchRegisterBankInfo &RBI;
+  const LoongArchTargetMachine &TM;
+
+#define GET_GLOBALISEL_PREDICATES_DECL
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_DECL
+
+#define GET_GLOBALISEL_TEMPORARIES_DECL
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_DECL
+};
+
+} // end anonymous namespace
+
+#define GET_GLOBALISEL_IMPL
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_IMPL
+
+LoongArchInstructionSelector::LoongArchInstructionSelector(
+    const LoongArchTargetMachine &TM, const LoongArchSubtarget &STI,
+    const LoongArchRegisterBankInfo &RBI)
+    : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
+      TM(TM),
+
+#define GET_GLOBALISEL_PREDICATES_INIT
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_INIT
+#define GET_GLOBALISEL_TEMPORARIES_INIT
+#include "LoongArchGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_INIT
+{
+}
+
+bool LoongArchInstructionSelector::select(MachineInstr &MI) {
+  if (!isPreISelGenericOpcode(MI.getOpcode())) {
+    // Certain non-generic instructions also need some special handling.
+    return true;
+  }
+
+  if (selectImpl(MI, *CoverageInfo))
+    return true;
+
+  return false;
+}
+
+namespace llvm {
+InstructionSelector *
+createLoongArchInstructionSelector(const LoongArchTargetMachine &TM,
+                                   const LoongArchSubtarget &Subtarget,
+                                   const LoongArchRegisterBankInfo &RBI) {
+  return new LoongArchInstructionSelector(TM, Subtarget, RBI);
+}
+} // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.cpp
new file mode 100644
index 00000000000000..498f0920b67b08
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.cpp
@@ -0,0 +1,24 @@
+//===-- LoongArchLegalizerInfo.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the Machinelegalizer class for
+/// LoongArch.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchLegalizerInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+
+using namespace llvm;
+
+LoongArchLegalizerInfo::LoongArchLegalizerInfo(const LoongArchSubtarget &ST) {
+  getLegacyLegalizerInfo().computeTables();
+}
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.h b/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.h
new file mode 100644
index 00000000000000..666258d53f34df
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchLegalizerInfo.h
@@ -0,0 +1,29 @@
+//===-- LoongArchLegalizerInfo.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares the targeting of the Machinelegalizer class for
+/// LoongArch.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINELEGALIZER_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINELEGALIZER_H
+
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+
+namespace llvm {
+
+class LoongArchSubtarget;
+
+class LoongArchLegalizerInfo : public LegalizerInfo {
+public:
+  LoongArchLegalizerInfo(const LoongArchSubtarget &ST);
+};
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINELEGALIZER_H
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.cpp
new file mode 100644
index 00000000000000..7f8f76be7957ee
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.cpp
@@ -0,0 +1,27 @@
+//===-- LoongArchRegisterBankInfo.cpp ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the RegisterBankInfo class for
+/// LoongArch.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchRegisterBankInfo.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterBank.h"
+#include "llvm/CodeGen/RegisterBankInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+
+#define GET_TARGET_REGBANK_IMPL
+#include "LoongArchGenRegisterBank.inc"
+
+using namespace llvm;
+
+LoongArchRegisterBankInfo::LoongArchRegisterBankInfo(unsigned HwMode)
+    : LoongArchGenRegisterBankInfo(HwMode) {}
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.h b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.h
new file mode 100644
index 00000000000000..f03893f85004c6
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBankInfo.h
@@ -0,0 +1,39 @@
+//===-- LoongArchRegisterBankInfo.h -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares the targeting of the RegisterBankInfo class for
+/// LoongArch.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERBANKINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERBANKINFO_H
+
+#include "llvm/CodeGen/RegisterBankInfo.h"
+
+#define GET_REGBANK_DECLARATIONS
+#include "LoongArchGenRegisterBank.inc"
+
+namespace llvm {
+
+class TargetRegisterInfo;
+
+class LoongArchGenRegisterBankInfo : public RegisterBankInfo {
+protected:
+#define GET_TARGET_REGBANK_CLASS
+#include "LoongArchGenRegisterBank.inc"
+};
+
+/// This class provides the information for the target register banks.
+class LoongArchRegisterBankInfo final : public LoongArchGenRegisterBankInfo {
+public:
+  LoongArchRegisterBankInfo(unsigned HwMode);
+};
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERBANKINFO_H
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
new file mode 100644
index 00000000000000..d39d29c4ed1b58
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
@@ -0,0 +1,16 @@
+//=- LoongArchRegisterBank.td - Describe the LoongArch Banks -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+/// General Purpose Registers: R.
+def GPRBRegBank : RegisterBank<"GPRB", [GPR]>;
+
+/// Floating Point Registers: F.
+def FPRBRegBank : RegisterBank<"FPRB", [FPR64]>;
diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h
index db605237388809..32900db3af5ecd 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.h
+++ b/llvm/lib/Target/LoongArch/LoongArch.h
@@ -20,6 +20,9 @@
 namespace llvm {
 class AsmPrinter;
 class FunctionPass;
+class InstructionSelector;
+class LoongArchRegisterBankInfo;
+class LoongArchSubtarget;
 class LoongArchTargetMachine;
 class MCInst;
 class MCOperand;
@@ -47,6 +50,11 @@ void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &);
 void initializeLoongArchOptWInstrsPass(PassRegistry &);
 void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
 void initializeLoongArchExpandPseudoPass(PassRegistry &);
+
+InstructionSelector *
+createLoongArchInstructionSelector(const LoongArchTargetMachine &,
+                                   const LoongArchSubtarget &,
+                                   const LoongArchRegisterBankInfo &);
 } // end namespace llvm
 
 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 100bdba36c440c..324048f323d8b3 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -134,6 +134,7 @@ def TunePreferWInst
 include "LoongArchRegisterInfo.td"
 include "LoongArchCallingConv.td"
 include "LoongArchInstrInfo.td"
+include "GISel/LoongArchRegisterBanks.td"
 
 //===----------------------------------------------------------------------===//
 // LoongArch processors supported.
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
index 3acbe4992273a3..9a393ac16435e1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
@@ -11,7 +11,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "LoongArchSubtarget.h"
+#include "GISel/LoongArchCallLowering.h"
+#include "GISel/LoongArchLegalizerInfo.h"
 #include "LoongArchFrameLowering.h"
+#include "LoongArchTargetMachine.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 
 using namespace llvm;
@@ -96,3 +99,31 @@ LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU,
       FrameLowering(
           initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
       InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {}
+
+const CallLowering *LoongArchSubtarget::getCallLowering() const {
+  if (!CallLoweringInfo)
+    CallLoweringInfo.reset(new LoongArchCallLowering(*getTargetLowering()));
+  return CallLoweringInfo.get();
+}
+
+InstructionSelector *LoongArchSubtarget::getInstructionSelector() const {
+  if (!InstSelector) {
+    InstSelector.reset(createLoongArchInstructionSelector(
+        *static_cast<const LoongArchTargetMachine *>(
+            &TLInfo.getTargetMachine()),
+        *this, *getRegBankInfo()));
+  }
+  return InstSelector.get();
+}
+
+const LegalizerInfo *LoongArchSubtarget::getLegalizerInfo() const {
+  if (!Legalizer)
+    Legalizer.reset(new LoongArchLegalizerInfo(*this));
+  return Legalizer.get();
+}
+
+const LoongArchRegisterBankInfo *LoongArchSubtarget::getRegBankInfo() const {
+  if (!RegBankInfo)
+    RegBankInfo.reset(new LoongArchRegisterBankInfo(getHwMode()));
+  return RegBankInfo.get();
+}
diff --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 5e12bafebb0d52..589807ff96e979 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -13,11 +13,15 @@
 #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H
 #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H
 
+#include "GISel/LoongArchRegisterBankInfo.h"
 #include "LoongArchFrameLowering.h"
 #include "LoongArchISelLowering.h"
 #include "LoongArchInstrInfo.h"
 #include "LoongArchRegisterInfo.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
@@ -106,6 +110,19 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
   bool enableMachineScheduler() const override { return true; }
   bool useAA() const override;
+
+protected:
+  // GlobalISel related APIs.
+  mutable std::unique_ptr<CallLowering> CallLoweringInfo;
+  mutable std::unique_ptr<InstructionSelector> InstSelector;
+  mutable std::unique_ptr<LegalizerInfo> Legalizer;
+  mutable std::unique_ptr<LoongArchRegisterBankInfo> RegBankInfo;
+
+public:
+  const CallLowering *getCallLowering() const override;
+  InstructionSelector *getInstructionSelector() const override;
+  const LegalizerInfo *getLegalizerInfo() const override;
+  const LoongArchRegisterBankInfo *getRegBankInfo() const override;
 };
 } // end namespace llvm
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index b611365f608af9..4ec95dab9f6fa1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -17,9 +17,14 @@
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 #include "TargetInfo/LoongArchTargetInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
+#include "llvm/CodeGen/GlobalISel/Legalizer.h"
+#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/InitializePasses.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Transforms/Scalar.h"
@@ -34,6 +39,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
   RegisterTargetMachine<LoongArchTargetMachine> X(getTheLoongArch32Target());
   RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
   auto *PR = PassRegistry::getPassRegistry();
+  initializeGlobalISel(*PR);
   initializeLoongArchDeadRegisterDefinitionsPass(*PR);
   initializeLoongArchMergeBaseOffsetOptPass(*PR);
   initializeLoongArchOptWInstrsPass(*PR);
@@ -154,6 +160,10 @@ class LoongArchPassConfig : public TargetPassConfig {
   void addIRPasses() override;
   void addCodeGenPrepare() override;
   bool addInstSelector() override;
+  bool addIRTranslator() override;
+  bool addLegalizeMachineIR() override;
+  bool addRegBankSelect() override;
+  bool addGlobalInstructionSelect() override;
   void addPreEmitPass() override;
   void addPreEmitPass2() override;
   void addMachineSSAOptimization() override;
@@ -192,6 +202,26 @@ bool LoongArchPassConfig::addInstSelector() {
   return false;
 }
 
+bool LoongArchPassConfig::addIRTranslator() {
+  addPass(new IRTranslator(getOptLevel()));
+  return false;
+}
+
+bool LoongArchPassConfig::addLegalizeMachineIR() {
+  addPass(new Legalizer());
+  return false;
+}
+
+bool LoongArchPassConfig::addRegBankSelect() {
+  addPass(new RegBankSelect());
+  return false;
+}
+
+bool LoongArchPassConfig::addGlobalInstructionSelect() {
+  addPass(new InstructionSelect(getOptLevel()));
+  return false;
+}
+
 TargetTransformInfo
 LoongArchTargetMachine::getTargetTransformInfo(const Function &F) const {
   return TargetTransformInfo(LoongArchTTIImpl(this, F));
diff --git a/llvm/test/CodeGen/LoongArch/GlobalISel/calllowering-ret.ll b/llvm/test/CodeGen/LoongArch/GlobalISel/calllowering-ret.ll
new file mode 100644
index 00000000000000..dd436e31e6663b
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/GlobalISel/calllowering-ret.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 -global-isel -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=LA32 %s
+; RUN: llc --mtriple=loongarch64 -global-isel -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=LA64 %s
+
+define void @foo() {
+; LA32-LABEL: foo:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: foo:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    ret
+entry:
+  ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/GlobalISel/irtranslator-calllowering.ll b/llvm/test/CodeGen/LoongArch/GlobalISel/irtranslator-calllowering.ll
new file mode 100644
index 00000000000000..db9bd20039cb91
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/GlobalISel/irtranslator-calllowering.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=LA32 %s
+; RUN: llc --mtriple=loongarch64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefix=LA64 %s
+
+define void @foo() {
+  ; LA32-LABEL: name: foo
+  ; LA32: bb.1.entry:
+  ; LA32-NEXT:   PseudoRET
+  ;
+  ; LA64-LABEL: name: foo
+  ; LA64: bb.1.entry:
+  ; LA64-NEXT:   PseudoRET
+entry:
+  ret void
+}

>From 9a1715bbc2e1a7ff6e6c8b83255943cbd2c26ba7 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Thu, 14 Nov 2024 10:27:58 +0800
Subject: [PATCH 2/3] address comments

---
 llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp | 3 +--
 llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td | 6 +++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
index 66671b331d9461..efa73c47082dd6 100644
--- a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
@@ -25,11 +25,10 @@ bool LoongArchCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
                                         const Value *Val,
                                         ArrayRef<Register> VRegs,
                                         FunctionLoweringInfo &FLI) const {
-  MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(LoongArch::PseudoRET);
-
   if (Val != nullptr)
     return false;
 
+  MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(LoongArch::PseudoRET);
   MIRBuilder.insertInstr(Ret);
   return true;
 }
diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
index d39d29c4ed1b58..32bc17e0191652 100644
--- a/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchRegisterBanks.td
@@ -1,13 +1,13 @@
-//=- LoongArchRegisterBank.td - Describe the LoongArch Banks -*- tablegen -*-=//
+//=- LoongArchRegisterBanks.td - Describe the LoongArch Banks -*- tablegen -*-=//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-//===----------------------------------------------------------------------===//
+//===-----------------------------------------------------------------------===//
 //
 //
-//===----------------------------------------------------------------------===//
+//===-----------------------------------------------------------------------===//
 
 /// General Purpose Registers: R.
 def GPRBRegBank : RegisterBank<"GPRB", [GPR]>;

>From f2ddef0cc22c797b3ec756709e06d4c18ed8c31c Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Mon, 25 Nov 2024 10:37:55 +0800
Subject: [PATCH 3/3] address comments

---
 llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
index efa73c47082dd6..e26b16d54332be 100644
--- a/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
+++ b/llvm/lib/Target/LoongArch/GISel/LoongArchCallLowering.cpp
@@ -28,18 +28,14 @@ bool LoongArchCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
   if (Val != nullptr)
     return false;
 
-  MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(LoongArch::PseudoRET);
-  MIRBuilder.insertInstr(Ret);
+  MIRBuilder.buildInstr(LoongArch::PseudoRET);
   return true;
 }
 
 bool LoongArchCallLowering::lowerFormalArguments(
     MachineIRBuilder &MIRBuilder, const Function &F,
     ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const {
-  if (F.arg_empty())
-    return true;
-
-  return false;
+  return F.arg_empty();
 }
 
 bool LoongArchCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,



More information about the llvm-commits mailing list