[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