Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HEXAGON] Utilize new mask instruction #92365

Merged
merged 3 commits into from
Aug 5, 2024

Conversation

quic-asaravan
Copy link
Contributor

This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek

@quic-asaravan
Copy link
Contributor Author

@iajbar @SundeepKushwaha Can you please review this?

@xgupta
Copy link
Contributor

xgupta commented May 17, 2024

It does LGTM but someone more qualified should accept the PR.

@quic-asaravan
Copy link
Contributor Author

@kparzysz Can you please review this? Thank you.

@xgupta
Copy link
Contributor

xgupta commented Jun 15, 2024

@pgodeq might know about Qualcomm Hexagon and can accept this PR.

@pgodeq
Copy link

pgodeq commented Jun 17, 2024

@pgodeq might know about Qualcomm Hexagon and can accept this PR.

Let me check with folks.

@iajbar
Copy link
Contributor

iajbar commented Jun 28, 2024

LGTM.

@iajbar iajbar self-assigned this Jun 28, 2024

#if defined(_MSC_VER)
#include <intrin.h>
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need intrin.h here?

HII = HST.getInstrInfo();
const Function &F = MF.getFunction();

if (!F.hasFnAttribute(Attribute::OptimizeForSize))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment explaining the reasoning behind this heuristic might be helpful.

@androm3da
Copy link
Member

I have removed some unrelated reviewers caused by unintentional commits added (then removed) recently.

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-backend-hexagon

Author: Abinaya Saravanan (quic-asaravan)

Changes

This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek


Full diff: https://github.com/llvm/llvm-project/pull/92365.diff

4 Files Affected:

  • (modified) llvm/lib/Target/Hexagon/CMakeLists.txt (+1)
  • (added) llvm/lib/Target/Hexagon/HexagonMask.cpp (+111)
  • (modified) llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp (+11)
  • (added) llvm/test/CodeGen/Hexagon/mask.ll (+17)
diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index 9e4ca08aea40d..e8ec93dd5ee63 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -48,6 +48,7 @@ add_llvm_target(HexagonCodeGen
   HexagonLoopIdiomRecognition.cpp
   HexagonMachineFunctionInfo.cpp
   HexagonMachineScheduler.cpp
+  HexagonMask.cpp
   HexagonMCInstLower.cpp
   HexagonNewValueJump.cpp
   HexagonOptAddrMode.cpp
diff --git a/llvm/lib/Target/Hexagon/HexagonMask.cpp b/llvm/lib/Target/Hexagon/HexagonMask.cpp
new file mode 100644
index 0000000000000..e9ed237a4f115
--- /dev/null
+++ b/llvm/lib/Target/Hexagon/HexagonMask.cpp
@@ -0,0 +1,111 @@
+//===-- HexagonMask.cpp - replace const ext tfri with mask ------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "mask"
+
+#include "HexagonMachineFunctionInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetMachine.h"
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+using namespace llvm;
+
+namespace llvm {
+FunctionPass *createHexagonMask();
+void initializeHexagonMaskPass(PassRegistry &);
+
+class HexagonMask : public MachineFunctionPass {
+public:
+  static char ID;
+  HexagonMask() : MachineFunctionPass(ID) {
+    PassRegistry &Registry = *PassRegistry::getPassRegistry();
+    initializeHexagonMaskPass(Registry);
+  }
+
+  StringRef getPassName() const override {
+    return "Hexagon replace const ext tfri with mask";
+  }
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+  const HexagonInstrInfo *HII;
+  void replaceConstExtTransferImmWithMask(MachineFunction &MF);
+};
+
+char HexagonMask::ID = 0;
+
+void HexagonMask::replaceConstExtTransferImmWithMask(MachineFunction &MF) {
+  for (auto &MBB : MF) {
+    for (auto &MI : llvm::make_early_inc_range(MBB)) {
+      if (MI.getOpcode() != Hexagon::A2_tfrsi)
+        continue;
+
+      const MachineOperand &Op0 = MI.getOperand(0);
+      const MachineOperand &Op1 = MI.getOperand(1);
+      if (!Op1.isImm())
+        continue;
+      int32_t V = Op1.getImm();
+      if (isInt<16>(V))
+        continue;
+
+      unsigned Idx, Len;
+      if (!isShiftedMask_32(V, Idx, Len))
+        continue;
+      if (!isUInt<5>(Idx) || !isUInt<5>(Len))
+        continue;
+
+      BuildMI(MBB, MI, MI.getDebugLoc(), HII->get(Hexagon::S2_mask),
+              Op0.getReg())
+          .addImm(Len)
+          .addImm(Idx);
+      MBB.erase(MI);
+    }
+  }
+}
+
+bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
+  auto &HST = MF.getSubtarget<HexagonSubtarget>();
+  HII = HST.getInstrInfo();
+  const Function &F = MF.getFunction();
+
+  if (!F.hasFnAttribute(Attribute::OptimizeForSize))
+    return false;
+
+  replaceConstExtTransferImmWithMask(MF);
+
+  return true;
+}
+
+} // namespace llvm
+
+//===----------------------------------------------------------------------===//
+//                         Public Constructor Functions
+//===----------------------------------------------------------------------===//
+
+INITIALIZE_PASS(HexagonMask, "hexagon-mask", "Hexagon mask", false, false)
+
+FunctionPass *llvm::createHexagonMask() { return new HexagonMask(); }
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index b362285d4f16e..803b9b81045c6 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -59,6 +59,10 @@ static cl::opt<bool>
     DisableHCP("disable-hcp", cl::Hidden,
                cl::desc("Disable Hexagon constant propagation"));
 
+static cl::opt<bool> DisableHexagonMask(
+    "disable-mask", cl::Hidden,
+    cl::desc("Disable Hexagon specific Mask generation pass"));
+
 static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,
                                           cl::init(false),
                                           cl::desc("Disable store widening"));
@@ -180,6 +184,8 @@ void initializeHexagonGenMuxPass(PassRegistry &);
 void initializeHexagonHardwareLoopsPass(PassRegistry &);
 void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
 void initializeHexagonLoopAlignPass(PassRegistry &);
+void initializeHexagonMaskPass(PassRegistry &);
+void initializeHexagonMergeActivateWeightPass(PassRegistry &);
 void initializeHexagonNewValueJumpPass(PassRegistry &);
 void initializeHexagonOptAddrModePass(PassRegistry &);
 void initializeHexagonPacketizerPass(PassRegistry &);
@@ -213,6 +219,8 @@ FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
                                    CodeGenOptLevel OptLevel);
 FunctionPass *createHexagonLoopAlign();
 FunctionPass *createHexagonLoopRescheduling();
+FunctionPass *createHexagonMask();
+FunctionPass *createHexagonMergeActivateWeight();
 FunctionPass *createHexagonNewValueJump();
 FunctionPass *createHexagonOptAddrMode();
 FunctionPass *createHexagonOptimizeSZextends();
@@ -474,10 +482,13 @@ void HexagonPassConfig::addPostRegAlloc() {
 }
 
 void HexagonPassConfig::addPreSched2() {
+  bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
   addPass(createHexagonCopyToCombine());
   if (getOptLevel() != CodeGenOptLevel::None)
     addPass(&IfConverterID);
   addPass(createHexagonSplitConst32AndConst64());
+  if (!NoOpt && !DisableHexagonMask)
+    addPass(createHexagonMask());
 }
 
 void HexagonPassConfig::addPreEmitPass() {
diff --git a/llvm/test/CodeGen/Hexagon/mask.ll b/llvm/test/CodeGen/Hexagon/mask.ll
new file mode 100644
index 0000000000000..698d1ac26d248
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/mask.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=hexagon -mcpu=hexagonv73 < %s | FileCheck %s
+
+target triple = "hexagon"
+
+; CHECK-LABEL: test1:
+; CHECK: r0 = mask(#25,#2)
+; Function Attrs: optsize
+define i32 @test1() #1 {
+entry:
+  %0 = call i32 @llvm.hexagon.A2.tfr(i32 134217724)
+  ret i32 %0
+}
+
+declare i32 @llvm.hexagon.A2.tfr(i32) #0
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { optsize }

Copy link

github-actions bot commented Jul 29, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff a8e1c3e1239604ac787b6a2d39b5278ddec8aa8a fed67f7151518d35afcacd7a3da61ff2701fcc05 --extensions cpp -- llvm/lib/Target/Hexagon/HexagonMask.cpp llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
View the diff from clang-format here.
diff --git a/llvm/lib/Target/Hexagon/HexagonMask.cpp b/llvm/lib/Target/Hexagon/HexagonMask.cpp
index 6a06efd307..ac9abfa6c1 100644
--- a/llvm/lib/Target/Hexagon/HexagonMask.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonMask.cpp
@@ -90,9 +90,10 @@ bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
 
   if (!F.hasFnAttribute(Attribute::OptimizeForSize))
     return false;
-  // The mask instruction available in v66 can be used to generate values in registers using 2 immediates
-  // Eg. to form 0x07fffffc in R0, you would write "R0 = mask(#25,#2)"
-  // Since it is a single-word instruction, it takes less code size than a constant-extended transfer at Os
+  // The mask instruction available in v66 can be used to generate values in
+  // registers using 2 immediates Eg. to form 0x07fffffc in R0, you would write
+  // "R0 = mask(#25,#2)" Since it is a single-word instruction, it takes less
+  // code size than a constant-extended transfer at Os
   replaceConstExtTransferImmWithMask(MF);
 
   return true;

Co-authored-by: Harsha Jagasia <harsha.jagasia@gmail.com>
Co-authored-by: Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com>
@quic-asaravan quic-asaravan merged commit c04857c into llvm:main Aug 5, 2024
7 checks passed
banach-space pushed a commit to banach-space/llvm-project that referenced this pull request Aug 7, 2024
This pass utilizes the new Hexagon Mask Instruction.
Authored by : Harsha Jagasia, Krzysztof Parzyszek

Co-authored-by: Harsha Jagasia <harsha.jagasia@gmail.com>
Co-authored-by: Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants