LLVM 24.0.0git
HLXExpandPseudos.cpp
Go to the documentation of this file.
1//===- HLXExpandPseudos.cpp - Expand HLX load/store pseudos ---------------===//
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//
9// This pass expands the HLX load/store pseudo instructions into their final
10// two-instruction bundled form. It runs after packetization so the resulting
11// bundles are not seen by the post-RA scheduler.
12//
13// LX_L16b_pseudo -> { Ld.tmp = mem(Rs); Ld = Ld } (LX_L16b_tmp; LX_assign)
14// LX_S16b_pseudo -> { Lx = Lx; mem(Rs) = Lx.new } (LX_assign; LX_S16b_new)
15//
16//===----------------------------------------------------------------------===//
17
18#include "Hexagon.h"
19#include "HexagonInstrInfo.h"
20#include "HexagonSubtarget.h"
26#include "llvm/Support/Debug.h"
27
28#define DEBUG_TYPE "hlx-expand-pseudos"
29
30using namespace llvm;
31
33 "disable-hlx-expand-pseudos", cl::init(false), cl::Hidden,
34 cl::desc("Disable expansion of HLX pseudo instructions"));
35
36namespace llvm {
39} // namespace llvm
40
42 unsigned Opc = MI.getOpcode();
43 return Opc == Hexagon::LX_L16b_pseudo || Opc == Hexagon::LX_S16b_pseudo;
44}
45
46namespace {
47
48struct HLXExpandPseudos : public MachineFunctionPass {
49 static char ID;
50
51 HLXExpandPseudos() : MachineFunctionPass(ID) {}
52
53 StringRef getPassName() const override { return "HLX Expand Pseudos"; }
54
55 MachineFunctionProperties getRequiredProperties() const override {
56 return MachineFunctionProperties().set(
57 MachineFunctionProperties::Property::NoVRegs);
58 }
59
60 bool runOnMachineFunction(MachineFunction &MF) override;
61
62private:
63 const HexagonInstrInfo *HII = nullptr;
64
65 bool expandPseudos(MachineInstr &MI);
66 bool expandPseudosInBundle(MachineInstr &MI);
67};
68
69} // end anonymous namespace
70
71char HLXExpandPseudos::ID = 0;
72
73INITIALIZE_PASS(HLXExpandPseudos, "hlx-expand-pseudos", "HLX Expand Pseudos",
74 false, false)
75
76bool HLXExpandPseudos::expandPseudos(MachineInstr &MI) {
77 bool IsBundled = MI.isBundled();
78 MachineBasicBlock *MBB = MI.getParent();
79 DebugLoc DL = MI.getDebugLoc();
80
81 auto ExpandLoad = [&](unsigned AssignOpc, unsigned LoadOpc) {
82 MachineOperand Op0 = MI.getOperand(0);
83 MachineOperand Op1 = MI.getOperand(1);
84 Register Reg0 = Op0.getReg();
85 MachineInstr *Start = BuildMI(*MBB, MI, DL, HII->get(LoadOpc), Reg0)
86 .add(Op1)
89 .getInstr();
91 BuildMI(*MBB, MI, DL, HII->get(AssignOpc), Reg0)
93 .getInstr();
94 if (IsBundled)
95 return true;
96 End->bundleWithPred();
97 finalizeBundle(*MBB, Start->getIterator(), MI.getIterator());
98 MBB->erase(MI);
99 return true;
100 };
101
102 auto ExpandStore = [&](unsigned AssignOpc, unsigned StoreOpc) {
103 MachineOperand Op0 = MI.getOperand(0);
104 MachineOperand Op1 = MI.getOperand(1);
105 Register Reg1 = Op1.getReg();
106 MachineInstr *Start = BuildMI(*MBB, MI, DL, HII->get(AssignOpc), Reg1)
107 .addReg(Reg1, RegState::Kill)
108 .getInstr();
109 Op1.setIsInternalRead();
110 MachineInstr *End = BuildMI(*MBB, MI, DL, HII->get(StoreOpc))
111 .add(Op0)
112 .add(Op1)
115 .getInstr();
116 if (IsBundled)
117 return true;
118 End->bundleWithPred();
119 finalizeBundle(*MBB, Start->getIterator(), MI.getIterator());
120 MBB->erase(MI);
121 return true;
122 };
123
124 switch (MI.getOpcode()) {
125 default:
126 return false;
127 case Hexagon::LX_L16b_pseudo:
128 return ExpandLoad(Hexagon::LX_assign, Hexagon::LX_L16b_tmp);
129 case Hexagon::LX_S16b_pseudo:
130 return ExpandStore(Hexagon::LX_assign, Hexagon::LX_S16b_new);
131 }
132}
133
134bool HLXExpandPseudos::expandPseudosInBundle(MachineInstr &MI) {
135 MachineBasicBlock::instr_iterator MII = MI.getIterator();
136 MachineBasicBlock::instr_iterator MIE = MI.getParent()->instr_end();
138 bool MadeChange = false;
139 for (++MII; MII != MIE && MII->isInsideBundle() && !MII->isBundle(); ++MII) {
140 if (isHLXLoadStorePseudo(*MII) && expandPseudos(*MII)) {
141 EraseList.push_back(MII);
142 MadeChange = true;
143 }
144 }
145 for (auto It : EraseList)
146 It->eraseFromBundle();
147 return MadeChange;
148}
149
150bool HLXExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
151 auto &HST = MF.getSubtarget<HexagonSubtarget>();
152 if (!HST.useHLXOps() || DisableHLXExpandPseudos)
153 return false;
154
155 HII = static_cast<const HexagonInstrInfo *>(HST.getInstrInfo());
156
157 bool MadeChange = false;
158 for (MachineBasicBlock &MBB : MF) {
159 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
160 if (MI.isBundle())
161 MadeChange |= expandPseudosInBundle(MI);
162 else if (isHLXLoadStorePseudo(MI))
163 MadeChange |= expandPseudos(MI);
164 }
165 }
166 return MadeChange;
167}
168
169FunctionPass *llvm::createHLXExpandPseudos() { return new HLXExpandPseudos(); }
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< bool > DisableHLXExpandPseudos("disable-hlx-expand-pseudos", cl::init(false), cl::Hidden, cl::desc("Disable expansion of HLX pseudo instructions"))
static bool isHLXLoadStorePseudo(const MachineInstr &MI)
IRTranslator LLVM IR MI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
Instructions::iterator instr_iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void setIsInternalRead(bool Val=true)
Register getReg() const
getReg - Returns the register number.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
void push_back(const T &Elt)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
FunctionPass * createHLXExpandPseudos()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
@ InternalRead
Register reads a value that is defined inside the same instruction or bundle.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
void initializeHLXExpandPseudosPass(PassRegistry &)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320