LLVM: lib/Target/Sparc/LeonPasses.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
19
20using namespace llvm;
21
23
27
29 false, false)
30
31
32
33
35
37
38 do {
39 I++;
40
42 if (MBB->getFallThrough() == nullptr)
43 return false;
44 MBB = MBB->getFallThrough();
46 }
47 } while (I->isMetaInstruction() || I->isInlineAsm());
48
49 return true;
50}
51
53 BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(SP::NOP));
54}
55
57 if (I->getNumOperands() == 0)
58 return false;
59
60 if (->getOperand(0).isReg())
61 return false;
62
63 unsigned reg = I->getOperand(0).getReg();
64
65 if (!SP::FPRegsRegClass.contains(reg) && !SP::DFPRegsRegClass.contains(reg))
66 return false;
67
68 return true;
69}
70
72 switch (I->getOpcode()) {
73 case SP::FDIVS:
74 case SP::FDIVD:
75 case SP::FSQRTS:
76 case SP::FSQRTD:
77 return true;
78 }
79 return false;
80}
81
82
83
84
85
87 switch (I->getOpcode()) {
88 case SP::STrr:
89 case SP::STri:
90 case SP::STBrr:
91 case SP::STBri:
92 case SP::STHrr:
93 case SP::STHri:
94 case SP::STFrr:
95 case SP::STFri:
96 break;
97 default:
98 return false;
99 }
100
103 return false;
104
105 if (MI->mayStore() || MI->mayLoad())
106 return false;
107
109
111 return false;
112
113 if (->mayStore())
114 return false;
115
117 return true;
118}
119
120
121
122
123
125
126 switch (I->getOpcode()) {
127 case SP::STDrr:
128 case SP::STDri:
129 case SP::STDFrr:
130 case SP::STDFri:
131 break;
132 default:
133 return false;
134 }
135
137
139 return false;
140
141 if (->mayStore())
142 return false;
143
145 return true;
146}
147
148
149
150
152
153
154 if (->mayLoad())
155 return false;
156
157
158 if (I->isBranch()) {
161
162 while (MI != TargetMBB->end() && MI->isMetaInstruction())
163 MI++;
164
165 if (MI == TargetMBB->end())
166 return false;
167
168 switch (MI->getOpcode()) {
169 case SP::SWAPrr:
170 case SP::SWAPri:
171 case SP::CASArr:
173 break;
174 default:
175 break;
176 }
177 }
178
179
182 return false;
183
184 switch (MI->getOpcode()) {
185 case SP::SWAPrr:
186 case SP::SWAPri:
187 case SP::CASArr:
188 break;
189 default:
190 return false;
191 }
193 return true;
194}
195
196
199 while (I != MBB.end() && I->isMetaInstruction())
200 I++;
201 switch (I->getOpcode()) {
202 case SP::SWAPrr:
203 case SP::SWAPri:
204 case SP::CASArr:
205 break;
206 default:
207 return false;
208 }
210 return true;
211}
212
213
214
216
217 if (I->getOpcode() != SP::BCOND && I->getOpcode() != SP::BCONDA)
218 return false;
219
222
223 while (MI != TargetMBB->end() && MI->isMetaInstruction())
224 MI++;
225
226 if (MI == TargetMBB->end())
227 return false;
228
229 if ((MI) && MI->getOpcode() != SP::FBCOND)
230 return false;
231
233 return true;
234}
235
236
237
238
239
240
241
242
243
244
246
248 return false;
249
250 unsigned dstReg = I->getOperand(0).getReg();
251
254 return false;
255
256 if (MI->isBranch()) {
258 return true;
259 }
260
262
263 unsigned fpFound = 0;
264 for (unsigned i = 0; i < 4; i++) {
265
268 return false;
269 continue;
270 }
271
272 if (MI->readsRegister(dstReg, TRI))
273 return false;
274
276 if (i < 2)
277 return false;
278 if (fpFound < 2)
279 return false;
280
282 if (i == 2)
284 return true;
285 }
286
287 fpFound++;
289 return false;
290 }
291
292 return false;
293}
294
298
299 if (!(ST->fixTN0009() || ST->fixTN0010() || ST->fixTN0012() ||
300 ST->fixTN0013()))
301 return false;
302
304 TRI = ST->getRegisterInfo();
305
306 if (ST->fixTN0010())
308
309 for (auto &MBB : MF) {
311 if (ST->fixTN0009()) {
314 }
315 if (ST->fixTN0010())
317 if (ST->fixTN0012())
319 if (ST->fixTN0013())
321 }
322 }
324}
325
328
329
330
331
332
333
334
335
336
337
338
340
342
346 return false;
347
350
355 unsigned Opcode = MI.getOpcode();
356 if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
360 }
361 }
362 }
363
365}
366
367
368
369
370
371
372
373
374
375
376
377
379
381
384 if (->detectRoundChange())
385 return false;
386
390 unsigned Opcode = MI.getOpcode();
391 if (Opcode == SP::CALL && MI.getNumOperands() > 0) {
393
397 errs() << "Error: You are using the detectroundchange "
398 "option to detect rounding changes that will "
399 "cause LEON errata. The only way to fix this "
400 "is to remove the call to fesetround from "
401 "the source code.\n";
402 }
403 }
404 }
405 }
406 }
407
409}
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
429
431
434 if (->fixAllFDIVSQRT())
435 return false;
436
439
444 unsigned Opcode = MI.getOpcode();
445
446
447
448
449
450 if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
451 for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
453
455 for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
457
459 }
460 }
461 }
462
464}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition LeonPasses.cpp:382
DetectRoundChange()
Definition LeonPasses.cpp:380
bool checkSeqTN0009A(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:86
bool checkSeqTN0013(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:245
ErrataWorkaround()
Definition LeonPasses.cpp:24
bool checkSeqTN0010First(MachineBasicBlock &MBB)
Definition LeonPasses.cpp:197
bool moveNext(MachineBasicBlock::iterator &I)
const SparcSubtarget * ST
bool checkSeqTN0012(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:215
bool checkSeqTN0010(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:151
bool checkSeqTN0009B(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:124
const TargetInstrInfo * TII
bool isDivSqrt(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:71
bool isFloat(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:56
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition LeonPasses.cpp:295
const TargetRegisterInfo * TRI
void insertNop(MachineBasicBlock::iterator I)
Definition LeonPasses.cpp:52
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition LeonPasses.cpp:432
FixAllFDIVSQRT()
Definition LeonPasses.cpp:430
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition LeonPasses.cpp:343
InsertNOPLoad()
Definition LeonPasses.cpp:341
LEONMachineFunctionPass(char &ID)
Definition LeonPasses.cpp:326
const SparcSubtarget * Subtarget
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass(char &ID)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineBasicBlock & front() const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
StringRef - Represent a constant reference to a string, i.e.
LLVM_ABI int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeErrataWorkaroundPass(PassRegistry &)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.