LLVM  14.0.0git
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"
15 #include "HexagonRegisterInfo.h"
16 #include "HexagonSubtarget.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Pass.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  Register ElemR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
72 
73  Register 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  Register 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  Register AR =
108  MF.getInfo<HexagonMachineFunctionInfo>()->getStackAlignBaseVReg();
109  std::map<unsigned, SmallVector<MachineInstr*,4>> VExtractMap;
110  MaybeAlign MaxAlign;
111  bool Changed = false;
112 
113  for (MachineBasicBlock &MBB : MF) {
114  for (MachineInstr &MI : MBB) {
115  unsigned Opc = MI.getOpcode();
116  if (Opc != Hexagon::V6_extractw)
117  continue;
118  Register VecR = MI.getOperand(1).getReg();
119  VExtractMap[VecR].push_back(&MI);
120  }
121  }
122 
123  auto EmitAddr = [&] (MachineBasicBlock &BB, MachineBasicBlock::iterator At,
124  DebugLoc dl, int FI, unsigned Offset) {
125  Register AddrR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
126  unsigned FiOpc = AR != 0 ? Hexagon::PS_fia : Hexagon::PS_fi;
127  auto MIB = BuildMI(BB, At, dl, HII->get(FiOpc), AddrR);
128  if (AR)
129  MIB.addReg(AR);
130  MIB.addFrameIndex(FI).addImm(Offset);
131  return AddrR;
132  };
133 
134  for (auto &P : VExtractMap) {
135  unsigned VecR = P.first;
136  if (P.second.size() <= VExtractThreshold)
137  continue;
138 
139  const auto &VecRC = *MRI.getRegClass(VecR);
140  Align Alignment = HRI.getSpillAlign(VecRC);
141  MaxAlign = max(MaxAlign, Alignment);
142  // Make sure this is not a spill slot: spill slots cannot be aligned
143  // if there are variable-sized objects on the stack. They must be
144  // accessible via FP (which is not aligned), because SP is unknown,
145  // and AP may not be available at the location of the load/store.
146  int FI = MFI.CreateStackObject(HRI.getSpillSize(VecRC), Alignment,
147  /*isSpillSlot*/ false);
148 
149  MachineInstr *DefI = MRI.getVRegDef(VecR);
150  MachineBasicBlock::iterator At = std::next(DefI->getIterator());
151  MachineBasicBlock &DefB = *DefI->getParent();
152  unsigned StoreOpc = VecRC.getID() == Hexagon::HvxVRRegClassID
153  ? Hexagon::V6_vS32b_ai
154  : Hexagon::PS_vstorerw_ai;
155  Register AddrR = EmitAddr(DefB, At, DefI->getDebugLoc(), FI, 0);
156  BuildMI(DefB, At, DefI->getDebugLoc(), HII->get(StoreOpc))
157  .addReg(AddrR)
158  .addImm(0)
159  .addReg(VecR);
160 
161  unsigned VecSize = HRI.getRegSizeInBits(VecRC) / 8;
162 
163  for (MachineInstr *ExtI : P.second) {
164  assert(ExtI->getOpcode() == Hexagon::V6_extractw);
165  unsigned SR = ExtI->getOperand(1).getSubReg();
166  assert(ExtI->getOperand(1).getReg() == VecR);
167 
168  MachineBasicBlock &ExtB = *ExtI->getParent();
169  DebugLoc DL = ExtI->getDebugLoc();
170  Register BaseR = EmitAddr(ExtB, ExtI, ExtI->getDebugLoc(), FI,
171  SR == 0 ? 0 : VecSize/2);
172 
173  unsigned ElemR = genElemLoad(ExtI, BaseR, MRI);
174  Register ExtR = ExtI->getOperand(0).getReg();
175  MRI.replaceRegWith(ExtR, ElemR);
176  ExtB.erase(ExtI);
177  Changed = true;
178  }
179  }
180 
181  if (AR && MaxAlign) {
182  // Update the required stack alignment.
183  MachineInstr *AlignaI = MRI.getVRegDef(AR);
184  assert(AlignaI->getOpcode() == Hexagon::PS_aligna);
185  MachineOperand &Op = AlignaI->getOperand(1);
186  if (*MaxAlign > Op.getImm())
187  Op.setImm(MaxAlign->value());
188  }
189 
190  return Changed;
191 }
192 
194  return new HexagonVExtract();
195 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
Pass.h
HexagonSubtarget.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
MachineRegisterInfo.h
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1299
VExtractThreshold
static cl::opt< unsigned > VExtractThreshold("hexagon-vextract-threshold", cl::Hidden, cl::ZeroOrMore, cl::init(1), cl::desc("Threshold for triggering vextract replacement"))
CommandLine.h
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
llvm::HexagonMachineFunctionInfo
Hexagon target-specific information for each MachineFunction.
Definition: HexagonMachineFunctionInfo.h:25
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:724
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
llvm::createHexagonVExtract
FunctionPass * createHexagonVExtract()
Definition: HexagonVExtract.cpp:193
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:109
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
HexagonInstrInfo.h
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:400
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
Hexagon.h
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::cl::ZeroOrMore
@ ZeroOrMore
Definition: CommandLine.h:120
llvm::HexagonSubtarget::getInstrInfo
const HexagonInstrInfo * getInstrInfo() const override
Definition: HexagonSubtarget.h:120
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::cl::opt
Definition: CommandLine.h:1434
llvm::MachineInstr::getDebugLoc
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:418
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
MachineFunctionPass.h
HexagonRegisterInfo.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:642
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::HexagonInstrInfo
Definition: HexagonInstrInfo.h:38
llvm::MachineFrameInfo::CreateStackObject
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
Definition: MachineFrameInfo.cpp:51
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:81
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:286
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:365
llvm::MachineRegisterInfo::replaceRegWith
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Definition: MachineRegisterInfo.cpp:380
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
llvm::Registry
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:44
SmallVector.h
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::HexagonSubtarget
Definition: HexagonSubtarget.h:43
HexagonMachineFunctionInfo.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::cl::desc
Definition: CommandLine.h:414
MachineFunction.h
INITIALIZE_PASS
INITIALIZE_PASS(HexagonVExtract, "hexagon-vextract", "Hexagon optimize vextract", false, false) unsigned HexagonVExtract
Definition: HexagonVExtract.cpp:64
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::initializeHexagonVExtractPass
void initializeHexagonVExtractPass(PassRegistry &)
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37