LLVM  8.0.1
HexagonVExtract.cpp
Go to the documentation of this file.
1 //===- HexagonVExtract.cpp ------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // This pass will replace multiple occurrences of V6_extractw from the same
10 // vector register with a combination of a vector store and scalar loads.
11 //===----------------------------------------------------------------------===//
12 
13 #include "Hexagon.h"
14 #include "HexagonInstrInfo.h"
15 #include "HexagonRegisterInfo.h"
16 #include "HexagonSubtarget.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/PassSupport.h"
25 
26 #include <map>
27 
28 using namespace llvm;
29 
30 static cl::opt<unsigned> VExtractThreshold("hexagon-vextract-threshold",
32  cl::desc("Threshold for triggering vextract replacement"));
33 
34 namespace llvm {
37 }
38 
39 namespace {
40  class HexagonVExtract : public MachineFunctionPass {
41  public:
42  static char ID;
43  HexagonVExtract() : MachineFunctionPass(ID) {}
44 
45  StringRef getPassName() const override {
46  return "Hexagon optimize vextract";
47  }
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
50  }
51  bool runOnMachineFunction(MachineFunction &MF) override;
52 
53  private:
54  const HexagonSubtarget *HST = nullptr;
55  const HexagonInstrInfo *HII = nullptr;
56 
57  unsigned genElemLoad(MachineInstr *ExtI, unsigned BaseR,
59  };
60 
61  char HexagonVExtract::ID = 0;
62 }
63 
64 INITIALIZE_PASS(HexagonVExtract, "hexagon-vextract",
65  "Hexagon optimize vextract", false, false)
66 
67 unsigned HexagonVExtract::genElemLoad(MachineInstr *ExtI, unsigned BaseR,
69  MachineBasicBlock &ExtB = *ExtI->getParent();
70  DebugLoc DL = ExtI->getDebugLoc();
71  unsigned ElemR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
72 
73  unsigned ExtIdxR = ExtI->getOperand(2).getReg();
74  unsigned ExtIdxS = ExtI->getOperand(2).getSubReg();
75 
76  // Simplified check for a compile-time constant value of ExtIdxR.
77  if (ExtIdxS == 0) {
78  MachineInstr *DI = MRI.getVRegDef(ExtIdxR);
79  if (DI->getOpcode() == Hexagon::A2_tfrsi) {
80  unsigned V = DI->getOperand(1).getImm();
81  V &= (HST->getVectorLength()-1) & -4u;
82 
83  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::L2_loadri_io), ElemR)
84  .addReg(BaseR)
85  .addImm(V);
86  return ElemR;
87  }
88  }
89 
90  unsigned IdxR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
91  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::A2_andir), IdxR)
92  .add(ExtI->getOperand(2))
93  .addImm(-4);
94  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::L4_loadri_rr), ElemR)
95  .addReg(BaseR)
96  .addReg(IdxR)
97  .addImm(0);
98  return ElemR;
99 }
100 
101 bool HexagonVExtract::runOnMachineFunction(MachineFunction &MF) {
102  HST = &MF.getSubtarget<HexagonSubtarget>();
103  HII = HST->getInstrInfo();
104  const auto &HRI = *HST->getRegisterInfo();
106  MachineFrameInfo &MFI = MF.getFrameInfo();
107  std::map<unsigned, SmallVector<MachineInstr*,4>> VExtractMap;
108  bool Changed = false;
109 
110  for (MachineBasicBlock &MBB : MF) {
111  for (MachineInstr &MI : MBB) {
112  unsigned Opc = MI.getOpcode();
113  if (Opc != Hexagon::V6_extractw)
114  continue;
115  unsigned VecR = MI.getOperand(1).getReg();
116  VExtractMap[VecR].push_back(&MI);
117  }
118  }
119 
120  for (auto &P : VExtractMap) {
121  unsigned VecR = P.first;
122  if (P.second.size() <= VExtractThreshold)
123  continue;
124 
125  const auto &VecRC = *MRI.getRegClass(VecR);
126  int FI = MFI.CreateSpillStackObject(HRI.getSpillSize(VecRC),
127  HRI.getSpillAlignment(VecRC));
128  MachineInstr *DefI = MRI.getVRegDef(VecR);
129  MachineBasicBlock::iterator At = std::next(DefI->getIterator());
130  MachineBasicBlock &DefB = *DefI->getParent();
131  unsigned StoreOpc = VecRC.getID() == Hexagon::HvxVRRegClassID
132  ? Hexagon::V6_vS32b_ai
133  : Hexagon::PS_vstorerw_ai;
134  BuildMI(DefB, At, DefI->getDebugLoc(), HII->get(StoreOpc))
135  .addFrameIndex(FI)
136  .addImm(0)
137  .addReg(VecR);
138 
139  unsigned VecSize = HRI.getRegSizeInBits(VecRC) / 8;
140 
141  for (MachineInstr *ExtI : P.second) {
142  assert(ExtI->getOpcode() == Hexagon::V6_extractw);
143  unsigned SR = ExtI->getOperand(1).getSubReg();
144  assert(ExtI->getOperand(1).getReg() == VecR);
145 
146  MachineBasicBlock &ExtB = *ExtI->getParent();
147  DebugLoc DL = ExtI->getDebugLoc();
148  unsigned BaseR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
149  BuildMI(ExtB, ExtI, DL, HII->get(Hexagon::PS_fi), BaseR)
150  .addFrameIndex(FI)
151  .addImm(SR == 0 ? 0 : VecSize/2);
152 
153  unsigned ElemR = genElemLoad(ExtI, BaseR, MRI);
154  unsigned ExtR = ExtI->getOperand(0).getReg();
155  MRI.replaceRegWith(ExtR, ElemR);
156  ExtB.erase(ExtI);
157  Changed = true;
158  }
159  }
160 
161  return Changed;
162 }
163 
165  return new HexagonVExtract();
166 }
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:24
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
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:45
unsigned getSubReg() const
A debug info location.
Definition: DebugLoc.h:34
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1069
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:409
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:1166
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:423
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:285
self_iterator getIterator()
Definition: ilist_node.h:82
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:254
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:64
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:49
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:39
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...