[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: RBLegalize (PR #112864)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Oct 19 08:06:19 PDT 2024


================
@@ -0,0 +1,334 @@
+//===-- AMDGPURBLegalizeRules.cpp -----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+/// Definitions of RBLegalize Rules for all opcodes.
+/// Implementation of container for all the Rules and search.
+/// Fast search for most common case when Rule.Predicate checks LLT and
+/// uniformity of register in operand 0.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPURBLegalizeRules.h"
+#include "GCNSubtarget.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
+#include "llvm/IR/IntrinsicsAMDGPU.h"
+
+using namespace llvm;
+using namespace AMDGPU;
+
+RegBankLLTMapping::RegBankLLTMapping(
+    std::initializer_list<RegBankLLTMapingApplyID> DstOpMappingList,
+    std::initializer_list<RegBankLLTMapingApplyID> SrcOpMappingList,
+    LoweringMethodID LoweringMethod)
+    : DstOpMapping(DstOpMappingList), SrcOpMapping(SrcOpMappingList),
+      LoweringMethod(LoweringMethod) {}
+
+PredicateMapping::PredicateMapping(
+    std::initializer_list<UniformityLLTOpPredicateID> OpList,
+    std::function<bool(const MachineInstr &)> TestFunc)
+    : OpUniformityAndTypes(OpList), TestFunc(TestFunc) {}
+
+bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID,
+                           const MachineUniformityInfo &MUI,
+                           const MachineRegisterInfo &MRI) {
+  switch (UniID) {
+  case S1:
+    return MRI.getType(Reg) == LLT::scalar(1);
+  case S16:
+    return MRI.getType(Reg) == LLT::scalar(16);
+  case S32:
+    return MRI.getType(Reg) == LLT::scalar(32);
+  case S64:
+    return MRI.getType(Reg) == LLT::scalar(64);
+  case P1:
+    return MRI.getType(Reg) == LLT::pointer(1, 64);
+
+  case UniS1:
+    return MRI.getType(Reg) == LLT::scalar(1) && MUI.isUniform(Reg);
+  case UniS16:
+    return MRI.getType(Reg) == LLT::scalar(16) && MUI.isUniform(Reg);
+  case UniS32:
+    return MRI.getType(Reg) == LLT::scalar(32) && MUI.isUniform(Reg);
+  case UniS64:
+    return MRI.getType(Reg) == LLT::scalar(64) && MUI.isUniform(Reg);
+
+  case DivS1:
+    return MRI.getType(Reg) == LLT::scalar(1) && MUI.isDivergent(Reg);
+  case DivS32:
+    return MRI.getType(Reg) == LLT::scalar(32) && MUI.isDivergent(Reg);
+  case DivS64:
+    return MRI.getType(Reg) == LLT::scalar(64) && MUI.isDivergent(Reg);
+  case DivP1:
+    return MRI.getType(Reg) == LLT::pointer(1, 64) && MUI.isDivergent(Reg);
+
+  case _:
+    return true;
+  default:
+    llvm_unreachable("missing matchUniformityAndLLT\n");
+  }
+}
+
+bool PredicateMapping::match(const MachineInstr &MI,
+                             const MachineUniformityInfo &MUI,
+                             const MachineRegisterInfo &MRI) const {
+  // Check LLT signature.
+  for (unsigned i = 0; i < OpUniformityAndTypes.size(); ++i) {
+    if (OpUniformityAndTypes[i] == _) {
+      if (MI.getOperand(i).isReg() &&
+          MI.getOperand(i).getReg() != AMDGPU::NoRegister)
+        return false;
+      continue;
+    }
+
+    // Remaining IDs check registers.
+    if (!MI.getOperand(i).isReg())
+      return false;
+
+    if (!matchUniformityAndLLT(MI.getOperand(i).getReg(),
+                               OpUniformityAndTypes[i], MUI, MRI))
+      return false;
+  }
+
+  // More complex check.
+  if (TestFunc)
+    return TestFunc(MI);
+
+  return true;
+}
+
+SetOfRulesForOpcode::SetOfRulesForOpcode() {}
+
+SetOfRulesForOpcode::SetOfRulesForOpcode(FastRulesTypes FastTypes)
+    : FastTypes(FastTypes) {}
+
+UniformityLLTOpPredicateID LLTToId(LLT Ty) {
+  if (Ty == LLT::scalar(16))
+    return S16;
+  if (Ty == LLT::scalar(32))
+    return S32;
+  if (Ty == LLT::scalar(64))
+    return S64;
+  if (Ty == LLT::fixed_vector(2, 16))
+    return V2S16;
+  if (Ty == LLT::fixed_vector(2, 32))
+    return V2S32;
+  if (Ty == LLT::fixed_vector(3, 32))
+    return V3S32;
+  if (Ty == LLT::fixed_vector(4, 32))
+    return V4S32;
+  return _;
+}
+
+const RegBankLLTMapping &
+SetOfRulesForOpcode::findMappingForMI(const MachineInstr &MI,
+                                      const MachineRegisterInfo &MRI,
+                                      const MachineUniformityInfo &MUI) const {
+  // Search in "Fast Rules".
+  // Note: if fast rules are enabled, RegBankLLTMapping must be added in each
+  // slot that could "match fast Predicate". If not, Invalid Mapping is
+  // returned which results in failure, does not search "Slow Rules".
+  if (FastTypes != No) {
+    Register Reg = MI.getOperand(0).getReg();
+    int Slot = getFastPredicateSlot(LLTToId(MRI.getType(Reg)));
+    if (Slot != -1) {
+      if (MUI.isUniform(Reg))
+        return Uni[Slot];
+      else
----------------
arsenm wrote:

No else after return 

https://github.com/llvm/llvm-project/pull/112864


More information about the llvm-branch-commits mailing list