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