[llvm] [LoongArch] Add machine function pass to merge base + offset (PR #101139)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 7 23:08:12 PDT 2024


================
@@ -0,0 +1,633 @@
+//===---- LoongArchMergeBaseOffset.cpp - Optimise address calculations ----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Merge the offset of address calculation into the offset field
+// of instructions in a global address lowering sequence.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArch.h"
+#include "LoongArchTargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetOptions.h"
+#include <optional>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-merge-base-offset"
+#define LoongArch_MERGE_BASE_OFFSET_NAME "LoongArch Merge Base Offset"
+
+namespace {
+
+class LoongArchMergeBaseOffsetOpt : public MachineFunctionPass {
+  const LoongArchSubtarget *ST = nullptr;
+  MachineRegisterInfo *MRI;
+
+public:
+  static char ID;
+  bool runOnMachineFunction(MachineFunction &Fn) override;
+  bool detectFoldable(MachineInstr &Hi20, MachineInstr *&Lo12,
+                      MachineInstr *&Lo20, MachineInstr *&Hi12,
+                      MachineInstr *&Last);
+
+  bool detectAndFoldOffset(MachineInstr &Hi20, MachineInstr &Lo12,
+                           MachineInstr *&Lo20, MachineInstr *&Hi12,
+                           MachineInstr *&Last);
+  void foldOffset(MachineInstr &Hi20, MachineInstr &Lo12, MachineInstr *&Lo20,
+                  MachineInstr *&Hi12, MachineInstr *&Last, MachineInstr &Tail,
+                  int64_t Offset);
+  bool foldLargeOffset(MachineInstr &Hi20, MachineInstr &Lo12,
+                       MachineInstr *&Lo20, MachineInstr *&Hi12,
+                       MachineInstr *&Last, MachineInstr &TailAdd,
+                       Register GAReg);
+
+  bool foldIntoMemoryOps(MachineInstr &Hi20, MachineInstr &Lo12,
+                         MachineInstr *&Lo20, MachineInstr *&Hi12,
+                         MachineInstr *&Last);
+
+  LoongArchMergeBaseOffsetOpt() : MachineFunctionPass(ID) {}
+
+  MachineFunctionProperties getRequiredProperties() const override {
+    return MachineFunctionProperties().set(
+        MachineFunctionProperties::Property::IsSSA);
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesCFG();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  StringRef getPassName() const override {
+    return LoongArch_MERGE_BASE_OFFSET_NAME;
+  }
+};
+} // end anonymous namespace
+
+char LoongArchMergeBaseOffsetOpt::ID = 0;
+INITIALIZE_PASS(LoongArchMergeBaseOffsetOpt, DEBUG_TYPE,
+                LoongArch_MERGE_BASE_OFFSET_NAME, false, false)
+
+// Detect either of the patterns:
+//
+// 1. (small/medium):
+//   pcalau12i vreg1, %pc_hi20(s)
+//   addi.d    vreg2, vreg1, %pc_lo12(s)
+//
+// 2. (large):
+//   pcalau12i vreg1, %pc_hi20(s)
+//   addi.d    vreg2, $zero, %pc_lo12(s)
+//   lu32i.d   vreg3, vreg2, %pc64_lo20(s)
+//   lu52i.d   vreg4, vreg3, %pc64_hi12(s)
+//   add.d     vreg5, vreg4, vreg1
+
+// The pattern is only accepted if:
+//    1) For small and medium pattern, the first instruction has only one use,
+//       which is the ADDI.
+//    2) For large pattern, the first four instructions each have only one use,
+//       and the user of the fourth instruction is ADD.
+//    3) The address operands have the appropriate type, reflecting the
+//       lowering of a global address or constant pool using the pattern.
+//    4) The offset value in the Global Address or Constant Pool is 0.
+bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
+                                                 MachineInstr *&Lo12,
+                                                 MachineInstr *&Lo20,
+                                                 MachineInstr *&Hi12,
+                                                 MachineInstr *&Last) {
+  if (Hi20.getOpcode() != LoongArch::PCALAU12I)
+    return false;
+
+  const MachineOperand &Hi20Op1 = Hi20.getOperand(1);
+  if (Hi20Op1.getTargetFlags() != LoongArchII::MO_PCREL_HI)
+    return false;
+
+  if (!(Hi20Op1.isGlobal() || Hi20Op1.isCPI() || Hi20Op1.isBlockAddress()) ||
+      Hi20Op1.getOffset() != 0)
----------------
heiher wrote:

Done. Thanks.

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


More information about the llvm-commits mailing list