LLVM: lib/Target/ARM/MVEVPTBlockPass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
25#include
26#include
27
28using namespace llvm;
29
30#define DEBUG_TYPE "arm-mve-vpt"
31
32namespace {
34public:
35 static char ID;
38
40
42
45 }
46
47 StringRef getPassName() const override {
48 return "MVE VPT block insertion pass";
49 }
50
51private:
53};
54
55char MVEVPTBlock::ID = 0;
56
57}
58
60
63 unsigned &NewOpcode) {
64
65
66
68 while (CmpMI != MI->getParent()->begin()) {
69 --CmpMI;
70 if (CmpMI->modifiesRegister(ARM::VPR, TRI))
71 break;
72 if (CmpMI->readsRegister(ARM::VPR, TRI))
73 break;
74 }
75
77 return nullptr;
79 if (NewOpcode == 0)
80 return nullptr;
81
82
85 return nullptr;
88 return nullptr;
89 return &*CmpMI;
90}
91
92
93
94
95
99 unsigned &NumInstrsSteppedOver) {
102 NumInstrsSteppedOver = 0;
103
104 while (Iter != EndIter) {
105 if (Iter->isDebugInstr()) {
106
107 ++Iter;
108 continue;
109 }
110
113 "VPT block pass does not expect Else preds");
115 break;
117 ++Iter;
118 ++NumInstrsSteppedOver;
119 };
120
121 return NumInstrsSteppedOver != 0 &&
122 (NextPred == ARMVCC::None || Iter == EndIter);
123}
124
125
126
129 for (; Iter != End; ++Iter)
130 if (Iter->definesRegister(ARM::VPR, nullptr) ||
131 Iter->killsRegister(ARM::VPR, nullptr))
132 return true;
133 return false;
134}
135
136
139 case 1:
141 case 2:
143 case 3:
145 case 4:
147 default:
149 }
150}
151
152
153
154
155
156
157
163 (void)BlockBeg;
165 "Expected a Predicated Instruction");
166
167 LLVM_DEBUG(dbgs() << "VPT block created for: "; Iter->dump());
168
171
173 std::next(BlockBeg);
174 AddedInstIter != Iter; ++AddedInstIter) {
175 if (AddedInstIter->isDebugInstr())
176 continue;
177 dbgs() << " adding: ";
178 AddedInstIter->dump();
179 });
180
181
183
184
185
187 while (BlockSize < 4 && Iter != EndIter &&
188 Iter->getOpcode() == ARM::MVE_VPNOT) {
189
190
191
192 unsigned ElseInstCnt = 0;
195 ElseInstCnt))
196 break;
197
198
199
200
202 break;
203
204 LLVM_DEBUG(dbgs() << " removing VPNOT: "; Iter->dump());
205
206
209
210
211 DeadInstructions.push_back(&*Iter);
212 ++Iter;
213
214
215
216
217 for (; Iter != VPNOTBlockEndIter; ++Iter) {
218 if (Iter->isDebugInstr())
219 continue;
220
221
224
225
226 Iter->getOperand(OpIdx).setImm(CurrentPredicate);
228
230 }
231
232 CurrentPredicate =
234 }
235 return BlockMask;
236}
237
242
243 SmallVector<MachineInstr *, 4> DeadInstructions;
244
245 while (MBIter != EndIter) {
246 MachineInstr *MI = &*MBIter;
249
251
252
253
254
255
256
257
258 assert(Pred != ARMVCC::Else && "VPT block pass does not expect Else preds");
259
261 ++MBIter;
262 continue;
263 }
264
267
268
269
270 MachineInstrBuilder MIBuilder;
271 unsigned NewOpcode;
272 LLVM_DEBUG(dbgs() << " final block mask: " << (unsigned)BlockMask << "\n");
274 LLVM_DEBUG(dbgs() << " folding VCMP into VPST: "; VCMP->dump());
276 MIBuilder.addImm((uint64_t)BlockMask);
277 MIBuilder.add(VCMP->getOperand(1));
278 MIBuilder.add(VCMP->getOperand(2));
279 MIBuilder.add(VCMP->getOperand(3));
280
281
282
283 for (MachineInstr &MII :
284 make_range(VCMP->getIterator(), MI->getIterator())) {
285 MII.clearRegisterKills(VCMP->getOperand(1).getReg(), TRI);
286 MII.clearRegisterKills(VCMP->getOperand(2).getReg(), TRI);
287 }
288
290 } else {
292 MIBuilder.addImm((uint64_t)BlockMask);
293 }
294
295
296
297 for (MachineInstr *DeadMI : DeadInstructions)
298 DeadMI->eraseFromParent();
299 DeadInstructions.clear();
300
303
305 }
306
308}
309
310bool MVEVPTBlock::runOnMachineFunction(MachineFunction &Fn) {
311 const ARMSubtarget &STI = Fn.getSubtarget();
312
313 if (!STI.isThumb2() || !STI.hasMVEIntegerOps())
314 return false;
315
316 TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
318
319 LLVM_DEBUG(dbgs() << "********** ARM MVE VPT BLOCKS **********\n"
320 << "********** Function: " << Fn.getName() << '\n');
321
323 for (MachineBasicBlock &MBB : Fn)
325
326 LLVM_DEBUG(dbgs() << "**************************************\n");
328}
329
330
331
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static ARM::PredBlockMask GetInitialBlockMask(unsigned BlockSize)
Definition MVEVPTBlockPass.cpp:137
static ARM::PredBlockMask CreateVPTBlock(MachineBasicBlock::instr_iterator &Iter, MachineBasicBlock::instr_iterator EndIter, SmallVectorImpl< MachineInstr * > &DeadInstructions)
Definition MVEVPTBlockPass.cpp:159
static bool StepOverPredicatedInstrs(MachineBasicBlock::instr_iterator &Iter, MachineBasicBlock::instr_iterator EndIter, unsigned MaxSteps, unsigned &NumInstrsSteppedOver)
Definition MVEVPTBlockPass.cpp:96
static bool IsVPRDefinedOrKilledByBlock(MachineBasicBlock::iterator Iter, MachineBasicBlock::iterator End)
Definition MVEVPTBlockPass.cpp:127
static MachineInstr * findVCMPToFoldIntoVPST(MachineBasicBlock::iterator MI, const TargetRegisterInfo *TRI, unsigned &NewOpcode)
Definition MVEVPTBlockPass.cpp:61
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static const int BlockSize
const ARMBaseInstrInfo * getInstrInfo() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
FunctionPass class - This class is used to implement most global optimizations.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
PredBlockMask
Mask values for IT and VPT Blocks, to be used by MCOperands.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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...
int findFirstVPTPredOperandIdx(const MachineInstr &MI)
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, const TargetRegisterInfo *TRI)
Return true if Reg is defd between From and To.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask, ARMVCC::VPTCodes Kind)
static unsigned VCMPOpcodeToVPT(unsigned Opcode)
FunctionPass * createMVEVPTBlockPass()
createMVEVPTBlock - Returns an instance of the MVE VPT block insertion pass.
Definition MVEVPTBlockPass.cpp:332