xref: /llvm-project/llvm/lib/Target/Hexagon/HexagonMask.cpp (revision 7e8bc5cf77bdda9e32b984b3fa91953361f24abb)
1c04857cbSAbinaya Saravanan //===-- HexagonMask.cpp - replace const ext tfri with mask ------===//
2c04857cbSAbinaya Saravanan //
3c04857cbSAbinaya Saravanan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c04857cbSAbinaya Saravanan // See https://llvm.org/LICENSE.txt for license information.
5c04857cbSAbinaya Saravanan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c04857cbSAbinaya Saravanan //
7c04857cbSAbinaya Saravanan //===----------------------------------------------------------------------===//
8c04857cbSAbinaya Saravanan //
9c04857cbSAbinaya Saravanan //===----------------------------------------------------------------------===//
10c04857cbSAbinaya Saravanan 
11c04857cbSAbinaya Saravanan #define DEBUG_TYPE "mask"
12c04857cbSAbinaya Saravanan 
13c04857cbSAbinaya Saravanan #include "HexagonSubtarget.h"
14c04857cbSAbinaya Saravanan #include "llvm/ADT/Statistic.h"
15c04857cbSAbinaya Saravanan #include "llvm/CodeGen/MachineFunction.h"
16c04857cbSAbinaya Saravanan #include "llvm/CodeGen/MachineFunctionPass.h"
17c04857cbSAbinaya Saravanan #include "llvm/CodeGen/MachineInstrBuilder.h"
18c04857cbSAbinaya Saravanan #include "llvm/CodeGen/Passes.h"
19c04857cbSAbinaya Saravanan #include "llvm/IR/Function.h"
20c04857cbSAbinaya Saravanan #include "llvm/Support/MathExtras.h"
21c04857cbSAbinaya Saravanan #include "llvm/Target/TargetMachine.h"
22c04857cbSAbinaya Saravanan 
23c04857cbSAbinaya Saravanan using namespace llvm;
24c04857cbSAbinaya Saravanan 
25c04857cbSAbinaya Saravanan namespace llvm {
26c04857cbSAbinaya Saravanan FunctionPass *createHexagonMask();
27c04857cbSAbinaya Saravanan void initializeHexagonMaskPass(PassRegistry &);
28c04857cbSAbinaya Saravanan 
29c04857cbSAbinaya Saravanan class HexagonMask : public MachineFunctionPass {
30c04857cbSAbinaya Saravanan public:
31c04857cbSAbinaya Saravanan   static char ID;
32c04857cbSAbinaya Saravanan   HexagonMask() : MachineFunctionPass(ID) {
33c04857cbSAbinaya Saravanan     PassRegistry &Registry = *PassRegistry::getPassRegistry();
34c04857cbSAbinaya Saravanan     initializeHexagonMaskPass(Registry);
35c04857cbSAbinaya Saravanan   }
36c04857cbSAbinaya Saravanan 
37c04857cbSAbinaya Saravanan   StringRef getPassName() const override {
38c04857cbSAbinaya Saravanan     return "Hexagon replace const ext tfri with mask";
39c04857cbSAbinaya Saravanan   }
40c04857cbSAbinaya Saravanan   bool runOnMachineFunction(MachineFunction &MF) override;
41c04857cbSAbinaya Saravanan 
42c04857cbSAbinaya Saravanan private:
43c04857cbSAbinaya Saravanan   const HexagonInstrInfo *HII;
44c04857cbSAbinaya Saravanan   void replaceConstExtTransferImmWithMask(MachineFunction &MF);
45c04857cbSAbinaya Saravanan };
46c04857cbSAbinaya Saravanan 
47c04857cbSAbinaya Saravanan char HexagonMask::ID = 0;
48c04857cbSAbinaya Saravanan 
49c04857cbSAbinaya Saravanan void HexagonMask::replaceConstExtTransferImmWithMask(MachineFunction &MF) {
50c04857cbSAbinaya Saravanan   for (auto &MBB : MF) {
51c04857cbSAbinaya Saravanan     for (auto &MI : llvm::make_early_inc_range(MBB)) {
52c04857cbSAbinaya Saravanan       if (MI.getOpcode() != Hexagon::A2_tfrsi)
53c04857cbSAbinaya Saravanan         continue;
54c04857cbSAbinaya Saravanan 
55c04857cbSAbinaya Saravanan       const MachineOperand &Op0 = MI.getOperand(0);
56c04857cbSAbinaya Saravanan       const MachineOperand &Op1 = MI.getOperand(1);
57c04857cbSAbinaya Saravanan       if (!Op1.isImm())
58c04857cbSAbinaya Saravanan         continue;
59c04857cbSAbinaya Saravanan       int32_t V = Op1.getImm();
60c04857cbSAbinaya Saravanan       if (isInt<16>(V))
61c04857cbSAbinaya Saravanan         continue;
62c04857cbSAbinaya Saravanan 
63c04857cbSAbinaya Saravanan       unsigned Idx, Len;
64c04857cbSAbinaya Saravanan       if (!isShiftedMask_32(V, Idx, Len))
65c04857cbSAbinaya Saravanan         continue;
66c04857cbSAbinaya Saravanan       if (!isUInt<5>(Idx) || !isUInt<5>(Len))
67c04857cbSAbinaya Saravanan         continue;
68c04857cbSAbinaya Saravanan 
69c04857cbSAbinaya Saravanan       BuildMI(MBB, MI, MI.getDebugLoc(), HII->get(Hexagon::S2_mask),
70c04857cbSAbinaya Saravanan               Op0.getReg())
71c04857cbSAbinaya Saravanan           .addImm(Len)
72c04857cbSAbinaya Saravanan           .addImm(Idx);
73c04857cbSAbinaya Saravanan       MBB.erase(MI);
74c04857cbSAbinaya Saravanan     }
75c04857cbSAbinaya Saravanan   }
76c04857cbSAbinaya Saravanan }
77c04857cbSAbinaya Saravanan 
78c04857cbSAbinaya Saravanan bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
79c04857cbSAbinaya Saravanan   auto &HST = MF.getSubtarget<HexagonSubtarget>();
80c04857cbSAbinaya Saravanan   HII = HST.getInstrInfo();
81c04857cbSAbinaya Saravanan   const Function &F = MF.getFunction();
82c04857cbSAbinaya Saravanan 
83c04857cbSAbinaya Saravanan   if (!F.hasFnAttribute(Attribute::OptimizeForSize))
84c04857cbSAbinaya Saravanan     return false;
85*86ef9ee6SAbinaya Saravanan   // Mask instruction is available only from v66
86*86ef9ee6SAbinaya Saravanan   if (!HST.hasV66Ops())
87*86ef9ee6SAbinaya Saravanan     return false;
88c04857cbSAbinaya Saravanan   // The mask instruction available in v66 can be used to generate values in
89c04857cbSAbinaya Saravanan   // registers using 2 immediates Eg. to form 0x07fffffc in R0, you would write
90c04857cbSAbinaya Saravanan   // "R0 = mask(#25,#2)" Since it is a single-word instruction, it takes less
91c04857cbSAbinaya Saravanan   // code size than a constant-extended transfer at Os
92c04857cbSAbinaya Saravanan   replaceConstExtTransferImmWithMask(MF);
93c04857cbSAbinaya Saravanan 
94c04857cbSAbinaya Saravanan   return true;
95c04857cbSAbinaya Saravanan }
96c04857cbSAbinaya Saravanan 
97c04857cbSAbinaya Saravanan } // namespace llvm
98c04857cbSAbinaya Saravanan 
99c04857cbSAbinaya Saravanan //===----------------------------------------------------------------------===//
100c04857cbSAbinaya Saravanan //                         Public Constructor Functions
101c04857cbSAbinaya Saravanan //===----------------------------------------------------------------------===//
102c04857cbSAbinaya Saravanan 
103c04857cbSAbinaya Saravanan INITIALIZE_PASS(HexagonMask, "hexagon-mask", "Hexagon mask", false, false)
104c04857cbSAbinaya Saravanan 
105c04857cbSAbinaya Saravanan FunctionPass *llvm::createHexagonMask() { return new HexagonMask(); }
106