[llvm-branch-commits] [llvm] 1ef3199 - Kai's GISEL Patch 1

Amy Kwan via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 2 09:09:21 PDT 2022


Author: Amy Kwan
Date: 2022-08-30T15:04:50-05:00
New Revision: 1ef3199dcaa871f08e5707a11f82d101d7ff5e7f

URL: https://github.com/llvm/llvm-project/commit/1ef3199dcaa871f08e5707a11f82d101d7ff5e7f
DIFF: https://github.com/llvm/llvm-project/commit/1ef3199dcaa871f08e5707a11f82d101d7ff5e7f.diff

LOG: Kai's GISEL Patch 1

Added: 
    llvm/lib/Target/PowerPC/GISel/PPCGenRegisterBankInfo.def
    llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll

Modified: 
    llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
    llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
    llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
    llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp b/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
index b71d59ed79edd..270a8c9e6757a 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCCallLowering.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "PPCCallLowering.h"
+#include "PPCCallingConv.h"
 #include "PPCISelLowering.h"
 #include "PPCSubtarget.h"
 #include "PPCTargetMachine.h"
@@ -27,6 +28,35 @@
 
 using namespace llvm;
 
+namespace {
+
+struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
+  OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
+                     MachineInstrBuilder MIB)
+      : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
+
+  void assignValueToReg(Register ValVReg, Register PhysReg,
+                        CCValAssign VA) override {
+    MIB.addUse(PhysReg, RegState::Implicit);
+    Register ExtReg = extendRegister(ValVReg, VA);
+    MIRBuilder.buildCopy(PhysReg, ExtReg);
+  }
+
+  void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
+                            MachinePointerInfo &MPO, CCValAssign &VA) override {
+    llvm_unreachable("unimplemented");
+  }
+
+  Register getStackAddress(uint64_t Size, int64_t Offset,
+                           MachinePointerInfo &MPO,
+                           ISD::ArgFlagsTy Flags) override {
+    llvm_unreachable("unimplemented");
+  }
+
+  MachineInstrBuilder MIB;
+};
+}
+
 PPCCallLowering::PPCCallLowering(const PPCTargetLowering &TLI)
     : CallLowering(&TLI) {}
 
@@ -34,13 +64,35 @@ bool PPCCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
                                   const Value *Val, ArrayRef<Register> VRegs,
                                   FunctionLoweringInfo &FLI,
                                   Register SwiftErrorVReg) const {
-  assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
-         "Return value without a vreg");
-  if (VRegs.size() > 0)
-    return false;
+  auto MIB = MIRBuilder.buildInstrNoInsert(PPC::BLR8);
+  bool Success = true;
+  MachineFunction &MF = MIRBuilder.getMF();
+  const Function &F = MF.getFunction();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  auto &DL = F.getParent()->getDataLayout();
+  if (!VRegs.empty()) {
+    // Setup the information about the return value.
+    ArgInfo OrigArg{VRegs, Val->getType(), 0};
+    setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
+
+    // Split the return value into consecutive registers if needed.
+    SmallVector<ArgInfo, 8> SplitArgs;
+    splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
+
+    // Use the calling convention callback to determine type and location of
+    // return value.
+    OutgoingValueAssigner ArgAssigner(RetCC_PPC);
 
-  MIRBuilder.buildInstr(PPC::BLR8);
-  return true;
+    // Handler to move the return value into the correct location.
+    OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);
+
+    // Iterate over all return values, and move them to the assigned location.
+    Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,
+                                            MIRBuilder, F.getCallingConv(),
+                                            F.isVarArg());
+  }
+  MIRBuilder.insertInstr(MIB);
+  return Success;
 }
 
 bool PPCCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCGenRegisterBankInfo.def b/llvm/lib/Target/PowerPC/GISel/PPCGenRegisterBankInfo.def
new file mode 100644
index 0000000000000..471af5d13d80d
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/GISel/PPCGenRegisterBankInfo.def
@@ -0,0 +1,62 @@
+//===- PPCGenRegisterBankInfo.def -------------------------------*- 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 defines all the static objects used by PPCRegisterBankInfo.
+/// \todo This should be generated by TableGen, because the logic here can be
+///  derived from register bank definition. Not yet implemented.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+RegisterBankInfo::PartialMapping PPCGenRegisterBankInfo::PartMappings[]{
+    /* StartIdx, Length, RegBank */
+    // 0: GPR 64-bit value.
+    {0, 64, PPC::GPRRegBank},
+};
+
+// ValueMappings.
+// Pointers to the entries in this array are returned by getValueMapping() and
+// getCopyMapping().
+//
+// The array has the following structure:
+// - At index 0 is the invalid entry.
+// - After that, the mappings for the register types from PartialMappingIdx
+//   follow. Each mapping consists of 3 entries, which is needed to cover
+//   3-operands instructions.
+// - Last, mappings for cross-register bank moves follow. Since COPY has only
+//   2 operands, a mapping consists of 2 entries.
+RegisterBankInfo::ValueMapping PPCGenRegisterBankInfo::ValMappings[]{
+    /* BreakDown, NumBreakDowns */
+    // 0: invalid
+    {nullptr, 0},
+    // 1: GPR 64-bit value.
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
+    {&PPCGenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
+};
+
+// TODO Too simple!
+const RegisterBankInfo::ValueMapping *
+PPCGenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx) {
+  assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
+
+  unsigned ValMappingIdx = RBIdx - PMI_Min;
+
+  return &ValMappings[1 + 3 * ValMappingIdx];
+}
+
+// TODO Too simple!
+const RegisterBankInfo::ValueMapping *
+PPCGenRegisterBankInfo::getCopyMapping(unsigned DstBankID, unsigned SrcBankID,
+                                       unsigned Size) {
+  assert(DstBankID < PPC::NumRegisterBanks && "Invalid bank ID");
+  assert(SrcBankID < PPC::NumRegisterBanks && "Invalid bank ID");
+
+  return &ValMappings[1];
+}
+
+} // namespace llvm

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
index 0cd8350e3fdda..b461ca4a28e1f 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp
@@ -75,7 +75,34 @@ PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
 {
 }
 
+static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
+                       MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+                       const RegisterBankInfo &RBI) {
+  Register DstReg = I.getOperand(0).getReg();
+  Register SrcReg = I.getOperand(1).getReg();
+
+  if (!Register::isPhysicalRegister(DstReg))
+    if (!RBI.constrainGenericRegister(DstReg, PPC::G8RCRegClass, MRI))
+      return false;
+  if (!Register::isPhysicalRegister(SrcReg))
+    if (!RBI.constrainGenericRegister(SrcReg, PPC::G8RCRegClass, MRI))
+      return false;
+
+  return true;
+}
+
 bool PPCInstructionSelector::select(MachineInstr &I) {
+  auto &MBB = *I.getParent();
+  auto &MF = *MBB.getParent();
+  auto &MRI = MF.getRegInfo();
+
+  if (!isPreISelGenericOpcode(I.getOpcode())) {
+    if (I.isCopy())
+      return selectCopy(I, TII, MRI, TRI, RBI);
+
+    return true;
+  }
+
   if (selectImpl(I, *CoverageInfo))
     return true;
   return false;

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index 5d196df80d50c..be56b6fe49589 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -18,5 +18,14 @@ using namespace llvm;
 using namespace LegalizeActions;
 
 PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
+  using namespace TargetOpcode;
+  const LLT S64 = LLT::scalar(64);
+  getActionDefinitionsBuilder(G_IMPLICIT_DEF).legalFor({S64});
+  getActionDefinitionsBuilder(G_CONSTANT)
+      .legalFor({S64})
+      .clampScalar(0, S64, S64);
+  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
+      .legalFor({S64})
+      .clampScalar(0, S64, S64);
   getLegacyLegalizerInfo().computeTables();
 }

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
index 58165fcaac03f..64e6a04daabc1 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.cpp
@@ -21,6 +21,88 @@
 #define GET_TARGET_REGBANK_IMPL
 #include "PPCGenRegisterBank.inc"
 
+// This file will be TableGen'ed at some point.
+#include "PPCGenRegisterBankInfo.def"
+
 using namespace llvm;
 
 PPCRegisterBankInfo::PPCRegisterBankInfo(const TargetRegisterInfo &TRI) {}
+
+const RegisterBank &
+PPCRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
+                                            LLT Ty) const {
+  switch (RC.getID()) {
+  case PPC::G8RCRegClassID:
+  case PPC::G8RC_NOX0RegClassID:
+  case PPC::G8RC_and_G8RC_NOX0RegClassID:
+    return getRegBank(PPC::GPRRegBankID);
+  default:
+    llvm_unreachable("Unexpected register class");
+  }
+}
+
+const RegisterBankInfo::InstructionMapping &
+PPCRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
+  const unsigned Opc = MI.getOpcode();
+
+  // Try the default logic for non-generic instructions that are either copies
+  // or already have some operands assigned to banks.
+  if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) ||
+      Opc == TargetOpcode::G_PHI) {
+    const RegisterBankInfo::InstructionMapping &Mapping =
+        getInstrMappingImpl(MI);
+    if (Mapping.isValid())
+      return Mapping;
+  }
+
+  const MachineFunction &MF = *MI.getParent()->getParent();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  const TargetSubtargetInfo &STI = MF.getSubtarget();
+  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
+
+  unsigned NumOperands = MI.getNumOperands();
+  const ValueMapping *OperandsMapping = nullptr;
+  unsigned Cost = 1;
+  unsigned MappingID = DefaultMappingID;
+
+  switch (Opc) {
+    // Bitwise ops.
+  case TargetOpcode::G_AND:
+  case TargetOpcode::G_OR:
+  case TargetOpcode::G_XOR:
+    assert(NumOperands <= 3 &&
+           "This code is for instructions with 3 or less operands");
+    OperandsMapping = getValueMapping(PMI_GPR64);
+    break;
+  case TargetOpcode::G_CONSTANT:
+    OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
+    break;
+  case TargetOpcode::COPY: {
+    Register DstReg = MI.getOperand(0).getReg();
+    Register SrcReg = MI.getOperand(1).getReg();
+    const RegisterBank *DstRB = getRegBank(DstReg, MRI, TRI);
+    const RegisterBank *SrcRB = getRegBank(SrcReg, MRI, TRI);
+    if (!DstRB)
+      DstRB = SrcRB;
+    else if (!SrcRB)
+      SrcRB = DstRB;
+    assert(DstRB && SrcRB && "Both RegBank were nullptr");
+    unsigned Size = getSizeInBits(DstReg, MRI, TRI);
+    Cost = copyCost(*DstRB, *SrcRB, Size);
+    OperandsMapping = getCopyMapping(DstRB->getID(), SrcRB->getID(), Size);
+    // We only care about the mapping of the destination.
+    NumOperands = 1;
+    break;
+  }
+  default:
+    return getInvalidInstructionMapping();
+  }
+
+  return getInstructionMapping(MappingID, Cost, OperandsMapping, NumOperands);
+}
+
+RegisterBankInfo::InstructionMappings
+PPCRegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
+  // TODO Implement.
+  return RegisterBankInfo::getInstrAlternativeMappings(MI);
+}

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
index 31a4c528751f5..11bdd98cd3b52 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBankInfo.h
@@ -26,6 +26,32 @@ class TargetRegisterInfo;
 
 class PPCGenRegisterBankInfo : public RegisterBankInfo {
 protected:
+  enum PartialMappingIdx {
+    PMI_None = -1,
+    PMI_GPR64 = 1,
+    PMI_Min = PMI_GPR64,
+  };
+
+  static RegisterBankInfo::PartialMapping PartMappings[];
+  static RegisterBankInfo::ValueMapping ValMappings[];
+  static PartialMappingIdx BankIDToCopyMapIdx[];
+
+  /// Get the pointer to the ValueMapping representing the RegisterBank
+  /// at \p RBIdx.
+  ///
+  /// The returned mapping works for instructions with the same kind of
+  /// operands for up to 3 operands.
+  ///
+  /// \pre \p RBIdx != PartialMappingIdx::None
+  static const RegisterBankInfo::ValueMapping *
+  getValueMapping(PartialMappingIdx RBIdx);
+
+  /// Get the pointer to the ValueMapping of the operands of a copy
+  /// instruction from the \p SrcBankID register bank to the \p DstBankID
+  /// register bank with a size of \p Size.
+  static const RegisterBankInfo::ValueMapping *
+  getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size);
+
 #define GET_TARGET_REGBANK_CLASS
 #include "PPCGenRegisterBank.inc"
 };
@@ -33,6 +59,14 @@ class PPCGenRegisterBankInfo : public RegisterBankInfo {
 class PPCRegisterBankInfo final : public PPCGenRegisterBankInfo {
 public:
   PPCRegisterBankInfo(const TargetRegisterInfo &TRI);
+
+  const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
+                                             LLT Ty) const override;
+  const InstructionMapping &
+  getInstrMapping(const MachineInstr &MI) const override;
+
+  InstructionMappings
+  getInstrAlternativeMappings(const MachineInstr &MI) const override;
 };
 } // namespace llvm
 

diff  --git a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
index 0e8a4b7061c5a..771d33e9f3a38 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
+++ b/llvm/lib/Target/PowerPC/GISel/PPCRegisterBanks.td
@@ -12,4 +12,4 @@
 //===----------------------------------------------------------------------===//
 
 /// General Purpose Registers
-def GPRRegBank : RegisterBank<"GPR", [G8RC]>;
+def GPRRegBank : RegisterBank<"GPR", [G8RC, G8RC_NOX0]>;

diff  --git a/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
new file mode 100644
index 0000000000000..09ccc80581e50
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/GlobalISel/ppc-isel-logical.ll
@@ -0,0 +1,61 @@
+; RUN: llc -mtriple ppc64le-linux -global-isel -o - < %s | FileCheck %s -check-prefixes=CHECK,LINUX
+
+; CHECK-LABEL: test_andi64:
+; LINUX: and 3, 3, 4
+; LINUX: blr
+define i64 @test_andi64(i64 %a, i64 %b) {
+  %res = and i64 %a, %b
+  ret i64 %res
+}
+
+; CHECK-LABEL: test_nandi64:
+; LINUX: nand 3, 3, 4
+; LINUX: blr
+define i64 @test_nandi64(i64 %a, i64 %b) {
+  %and = and i64 %a, %b
+  %neg = xor i64 %and, -1
+  ret i64 %neg
+}
+
+; CHECK-LABEL: test_andci64:
+; LINUX: andc 3, 3, 4
+; LINUX: blr
+define i64 @test_andci64(i64 %a, i64 %b) {
+  %neg = xor i64 %b, -1
+  %and = and i64 %a, %neg
+  ret i64 %and
+}
+
+; CHECK-LABEL: test_ori64:
+; LINUX: or 3, 3, 4
+; LINUX: blr
+define i64 @test_ori64(i64 %a, i64 %b) {
+  %res = or i64 %a, %b
+  ret i64 %res
+}
+
+; CHECK-LABEL: test_orci64:
+; LINUX: orc 3, 3, 4
+; LINUX: blr
+define i64 @test_orci64(i64 %a, i64 %b) {
+  %neg = xor i64 %b, -1
+  %or = or i64 %a, %neg
+  ret i64 %or
+}
+
+; CHECK-LABEL: test_nori64:
+; LINUX: nor 3, 3, 4
+; LINUX: blr
+define i64 @test_nori64(i64 %a, i64 %b) {
+  %or = or i64 %a, %b
+  %neg = xor i64 %or, -1
+  ret i64 %neg
+}
+
+; CHECK-LABEL: test_xori64:
+; LINUX: xor 3, 3, 4
+; LINUX: blr
+define i64 @test_xori64(i64 %a, i64 %b) {
+  %res = xor i64 %a, %b
+  ret i64 %res
+}


        


More information about the llvm-branch-commits mailing list