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