LLVM  9.0.0svn
HexagonVExtract.cpp
Go to the documentation of this file.
1 //===- HexagonVExtract.cpp ------------------------------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This pass will replace multiple occurrences of V6_extractw from the same
9 // vector register with a combination of a vector store and scalar loads.
10 //===----------------------------------------------------------------------===//
11 
12 #include "Hexagon.h"
13 #include "HexagonInstrInfo.h"
14 #include "HexagonRegisterInfo.h"
15 #include "HexagonSubtarget.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/PassSupport.h"
24 
25 #include <map>
26 
27 using namespace llvm;
28 
29 static cl::opt<unsigned> VExtractThreshold("hexagon-vextract-threshold",
31  cl::desc("Threshold for triggering vextract replacement"));
32 
33 namespace llvm {
36 }
37 
38 namespace {
39  class HexagonVExtract : public MachineFunctionPass {
40  public:
41  static char ID;
42  HexagonVExtract() : MachineFunctionPass(ID) {}
43 
44  StringRef getPassName() const override {
45  return "Hexagon optimize vextract";
46  }
47  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  }
50  bool runOnMachineFunction(MachineFunction &MF) override;
51 
52  private:
53  const HexagonSubtarget *HST = nullptr;
54  const HexagonInstrInfo *HII = nullptr;
55 
56  unsigned genElemLoad(MachineInstr *ExtI, unsigned BaseR,
58  };
59 
60  char HexagonVExtract::ID = 0;
61 }
62 
63 INITIALIZE_PASS(HexagonVExtract, "hexagon-vextract",
64  "Hexagon optimize vextract", false, false)
65 
66 unsigned HexagonVExtract::genElemLoad(MachineInstr *ExtI, unsigned BaseR,
68  MachineBasicBlock &ExtB = *ExtI->getParent();
69  DebugLoc DL = ExtI->getDebugLoc();
70  unsigned ElemR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
71 
72  unsigned ExtIdxR = ExtI->getOperand(2).getReg();
73  unsigned ExtIdxS = ExtI->getOperand(2).getSubReg();
74 
75  // Simplified check for a compile-time constant value of ExtIdxR.
76  if (ExtIdxS == 0) {
77  MachineInstr *DI = MRI.getVRegDef(ExtIdxR);
78  if (DI->getOpcode() == Hexagon::A2_tfrsi) {
79  unsigned V = DI->getOperand(1).getImm();
80  V &= (HST->getVectorLength()-1) & -4u;
81 
82  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::L2_loadri_io), ElemR)
83  .addReg(BaseR)
84  .addImm(V);
85  return ElemR;
86  }
87  }
88 
89  unsigned IdxR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
90  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::A2_andir), IdxR)
91  .add(ExtI->getOperand(2))
92  .addImm(-4);
93  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::L4_loadri_rr), ElemR)
94  .addReg(BaseR)
95  .addReg(IdxR)
96  .addImm(0);
97  return ElemR;
98 }
99 
100 bool HexagonVExtract::runOnMachineFunction(MachineFunction &MF) {
101  HST = &MF.getSubtarget<HexagonSubtarget>();
102  HII = HST->getInstrInfo();
103  const auto &HRI = *HST->getRegisterInfo();
105  MachineFrameInfo &MFI = MF.getFrameInfo();
106  std::map<unsigned, SmallVector<MachineInstr*,4>> VExtractMap;
107  bool Changed = false;
108 
109  for (MachineBasicBlock &MBB : MF) {
110  for (MachineInstr &MI : MBB) {
111  unsigned Opc = MI.getOpcode();
112  if (Opc != Hexagon::V6_extractw)
113  continue;
114  unsigned VecR = MI.getOperand(1).getReg();
115  VExtractMap[VecR].push_back(&MI);
116  }
117  }
118 
119  for (auto &P : VExtractMap) {
120  unsigned VecR = P.first;
121  if (P.second.size() <= VExtractThreshold)
122  continue;
123 
124  const auto &VecRC = *MRI.getRegClass(VecR);
125  int FI = MFI.CreateSpillStackObject(HRI.getSpillSize(VecRC),
126  HRI.getSpillAlignment(VecRC));
127  MachineInstr *DefI = MRI.getVRegDef(VecR);
128  MachineBasicBlock::iterator At = std::next(DefI->getIterator());
129  MachineBasicBlock &DefB = *DefI->getParent();
130  unsigned StoreOpc = VecRC.getID() == Hexagon::HvxVRRegClassID
131  ? Hexagon::V6_vS32b_ai
132  : Hexagon::PS_vstorerw_ai;
133  BuildMI(DefB, At, DefI->getDebugLoc(), HII->get(StoreOpc))
134  .addFrameIndex(FI)
135  .addImm(0)
136  .addReg(VecR);
137 
138  unsigned VecSize = HRI.getRegSizeInBits(VecRC) / 8;
139 
140  for (MachineInstr *ExtI : P.second) {
141  assert(ExtI->getOpcode() == Hexagon::V6_extractw);
142  unsigned SR = ExtI->getOperand(1).getSubReg();
143  assert(ExtI->getOperand(1).getReg() == VecR);
144 
145  MachineBasicBlock &ExtB = *ExtI->getParent();
146  DebugLoc DL = ExtI->getDebugLoc();
147  unsigned BaseR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
148  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::PS_fi), BaseR)
149  .addFrameIndex(FI)
150  .addImm(SR == 0 ? 0 : VecSize/2);
151 
152  unsigned ElemR = genElemLoad(ExtI, BaseR, MRI);
153  unsigned ExtR = ExtI->getOperand(0).getReg();
154  MRI.replaceRegWith(ExtR, ElemR);
155  ExtB.erase(ExtI);
156  Changed = true;
157  }
158  }
159 
160  return Changed;
161 }
162 
164  return new HexagonVExtract();
165 }
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:382
unsigned getReg() const
getReg - Returns the register number.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:44
unsigned getSubReg() const
A debug info location.
Definition: DebugLoc.h:33
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1068
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
static cl::opt< unsigned > VExtractThreshold("hexagon-vextract-threshold", cl::Hidden, cl::ZeroOrMore, cl::init(1), cl::desc("Threshold for triggering vextract replacement"))
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
INITIALIZE_PASS(HexagonVExtract, "hexagon-vextract", "Hexagon optimize vextract", false, false) unsigned HexagonVExtract
void initializeHexagonVExtractPass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1165
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:422
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
int CreateSpillStackObject(uint64_t Size, unsigned Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
FunctionPass * createHexagonVExtract()
int64_t getImm() const
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:253
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const HexagonInstrInfo * getInstrInfo() const override
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...