Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
35266 views
1
//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
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 replaces transfer instructions by combine instructions.
9
// We walk along a basic block and look for two combinable instructions and try
10
// to move them together. If we can move them next to each other we do so and
11
// replace them with a combine instruction.
12
//===----------------------------------------------------------------------===//
13
14
#include "HexagonInstrInfo.h"
15
#include "HexagonSubtarget.h"
16
#include "llvm/ADT/DenseMap.h"
17
#include "llvm/ADT/DenseSet.h"
18
#include "llvm/CodeGen/MachineBasicBlock.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineFunctionPass.h"
21
#include "llvm/CodeGen/MachineInstr.h"
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/Passes.h"
24
#include "llvm/CodeGen/TargetRegisterInfo.h"
25
#include "llvm/Pass.h"
26
#include "llvm/Support/CodeGen.h"
27
#include "llvm/Support/CommandLine.h"
28
#include "llvm/Support/Debug.h"
29
#include "llvm/Support/raw_ostream.h"
30
#include "llvm/Target/TargetMachine.h"
31
32
using namespace llvm;
33
34
#define DEBUG_TYPE "hexagon-copy-combine"
35
36
static cl::opt<bool>
37
IsCombinesDisabled("disable-merge-into-combines", cl::Hidden,
38
39
cl::desc("Disable merging into combines"));
40
static cl::opt<bool>
41
IsConst64Disabled("disable-const64", cl::Hidden,
42
43
cl::desc("Disable generation of const64"));
44
static
45
cl::opt<unsigned>
46
MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
47
cl::Hidden, cl::init(4),
48
cl::desc("Maximum distance between a tfr feeding a store we "
49
"consider the store still to be newifiable"));
50
51
namespace llvm {
52
FunctionPass *createHexagonCopyToCombine();
53
void initializeHexagonCopyToCombinePass(PassRegistry&);
54
}
55
56
57
namespace {
58
59
class HexagonCopyToCombine : public MachineFunctionPass {
60
const HexagonInstrInfo *TII;
61
const TargetRegisterInfo *TRI;
62
const HexagonSubtarget *ST;
63
bool ShouldCombineAggressively;
64
65
DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
66
SmallVector<MachineInstr *, 8> DbgMItoMove;
67
68
public:
69
static char ID;
70
71
HexagonCopyToCombine() : MachineFunctionPass(ID) {}
72
73
void getAnalysisUsage(AnalysisUsage &AU) const override {
74
MachineFunctionPass::getAnalysisUsage(AU);
75
}
76
77
StringRef getPassName() const override {
78
return "Hexagon Copy-To-Combine Pass";
79
}
80
81
bool runOnMachineFunction(MachineFunction &Fn) override;
82
83
MachineFunctionProperties getRequiredProperties() const override {
84
return MachineFunctionProperties().set(
85
MachineFunctionProperties::Property::NoVRegs);
86
}
87
88
private:
89
MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,
90
bool AllowC64);
91
92
void findPotentialNewifiableTFRs(MachineBasicBlock &);
93
94
void combine(MachineInstr &I1, MachineInstr &I2,
95
MachineBasicBlock::iterator &MI, bool DoInsertAtI1,
96
bool OptForSize);
97
98
bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,
99
unsigned I1DestReg, unsigned I2DestReg,
100
bool &DoInsertAtI1);
101
102
void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
103
MachineOperand &HiOperand, MachineOperand &LoOperand);
104
105
void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
106
MachineOperand &HiOperand, MachineOperand &LoOperand);
107
108
void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
109
MachineOperand &HiOperand, MachineOperand &LoOperand);
110
111
void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
112
MachineOperand &HiOperand, MachineOperand &LoOperand);
113
114
void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,
115
MachineOperand &HiOperand, MachineOperand &LoOperand);
116
};
117
118
} // End anonymous namespace.
119
120
char HexagonCopyToCombine::ID = 0;
121
122
INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
123
"Hexagon Copy-To-Combine Pass", false, false)
124
125
static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,
126
bool ShouldCombineAggressively) {
127
switch (MI.getOpcode()) {
128
case Hexagon::A2_tfr: {
129
// A COPY instruction can be combined if its arguments are IntRegs (32bit).
130
const MachineOperand &Op0 = MI.getOperand(0);
131
const MachineOperand &Op1 = MI.getOperand(1);
132
assert(Op0.isReg() && Op1.isReg());
133
134
Register DestReg = Op0.getReg();
135
Register SrcReg = Op1.getReg();
136
return Hexagon::IntRegsRegClass.contains(DestReg) &&
137
Hexagon::IntRegsRegClass.contains(SrcReg);
138
}
139
140
case Hexagon::A2_tfrsi: {
141
// A transfer-immediate can be combined if its argument is a signed 8bit
142
// value.
143
const MachineOperand &Op0 = MI.getOperand(0);
144
const MachineOperand &Op1 = MI.getOperand(1);
145
assert(Op0.isReg());
146
147
Register DestReg = Op0.getReg();
148
// Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
149
// workaround for an ABI bug that prevents GOT relocations on combine
150
// instructions
151
if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)
152
return false;
153
154
// Only combine constant extended A2_tfrsi if we are in aggressive mode.
155
bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());
156
return Hexagon::IntRegsRegClass.contains(DestReg) &&
157
(ShouldCombineAggressively || NotExt);
158
}
159
160
case Hexagon::V6_vassign:
161
return true;
162
163
default:
164
break;
165
}
166
167
return false;
168
}
169
170
template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {
171
if (I.getOpcode() == Hexagon::TFRI64_V4 ||
172
I.getOpcode() == Hexagon::A2_tfrsi) {
173
const MachineOperand &Op = I.getOperand(1);
174
return !Op.isImm() || !isInt<N>(Op.getImm());
175
}
176
return false;
177
}
178
179
/// areCombinableOperations - Returns true if the two instruction can be merge
180
/// into a combine (ignoring register constraints).
181
static bool areCombinableOperations(const TargetRegisterInfo *TRI,
182
MachineInstr &HighRegInst,
183
MachineInstr &LowRegInst, bool AllowC64) {
184
unsigned HiOpc = HighRegInst.getOpcode();
185
unsigned LoOpc = LowRegInst.getOpcode();
186
187
auto verifyOpc = [](unsigned Opc) -> void {
188
switch (Opc) {
189
case Hexagon::A2_tfr:
190
case Hexagon::A2_tfrsi:
191
case Hexagon::V6_vassign:
192
break;
193
default:
194
llvm_unreachable("Unexpected opcode");
195
}
196
};
197
verifyOpc(HiOpc);
198
verifyOpc(LoOpc);
199
200
if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)
201
return HiOpc == LoOpc;
202
203
if (!AllowC64) {
204
// There is no combine of two constant extended values.
205
if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
206
isGreaterThanNBitTFRI<6>(LowRegInst))
207
return false;
208
}
209
210
// There is a combine of two constant extended values into CONST64,
211
// provided both constants are true immediates.
212
if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
213
isGreaterThanNBitTFRI<16>(LowRegInst) && !IsConst64Disabled)
214
return (HighRegInst.getOperand(1).isImm() &&
215
LowRegInst.getOperand(1).isImm());
216
217
// There is no combine of two constant extended values, unless handled above
218
// Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)
219
if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
220
isGreaterThanNBitTFRI<8>(LowRegInst))
221
return false;
222
223
return true;
224
}
225
226
static bool isEvenReg(unsigned Reg) {
227
assert(Register::isPhysicalRegister(Reg));
228
if (Hexagon::IntRegsRegClass.contains(Reg))
229
return (Reg - Hexagon::R0) % 2 == 0;
230
if (Hexagon::HvxVRRegClass.contains(Reg))
231
return (Reg - Hexagon::V0) % 2 == 0;
232
llvm_unreachable("Invalid register");
233
}
234
235
static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) {
236
for (MachineOperand &Op : MI.operands())
237
if (Op.isReg() && Op.getReg() == RegNotKilled && Op.isKill())
238
Op.setIsKill(false);
239
}
240
241
/// Returns true if it is unsafe to move a copy instruction from \p UseReg to
242
/// \p DestReg over the instruction \p MI.
243
static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg,
244
unsigned DestReg,
245
const TargetRegisterInfo *TRI) {
246
return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||
247
MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||
248
MI.hasUnmodeledSideEffects() || MI.isInlineAsm() ||
249
MI.isMetaInstruction();
250
}
251
252
static Register UseReg(const MachineOperand& MO) {
253
return MO.isReg() ? MO.getReg() : Register();
254
}
255
256
/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
257
/// that the two instructions can be paired in a combine.
258
bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
259
MachineInstr &I2,
260
unsigned I1DestReg,
261
unsigned I2DestReg,
262
bool &DoInsertAtI1) {
263
Register I2UseReg = UseReg(I2.getOperand(1));
264
265
// It is not safe to move I1 and I2 into one combine if I2 has a true
266
// dependence on I1.
267
if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))
268
return false;
269
270
bool isSafe = true;
271
272
// First try to move I2 towards I1.
273
{
274
// A reverse_iterator instantiated like below starts before I2, and I1
275
// respectively.
276
// Look at instructions I in between I2 and (excluding) I1.
277
MachineBasicBlock::reverse_iterator I = ++I2.getIterator().getReverse();
278
MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse();
279
// At 03 we got better results (dhrystone!) by being more conservative.
280
if (!ShouldCombineAggressively)
281
End = ++I1.getIterator().getReverse();
282
// If I2 kills its operand and we move I2 over an instruction that also
283
// uses I2's use reg we need to modify that (first) instruction to now kill
284
// this reg.
285
unsigned KilledOperand = 0;
286
if (I2.killsRegister(I2UseReg, /*TRI=*/nullptr))
287
KilledOperand = I2UseReg;
288
MachineInstr *KillingInstr = nullptr;
289
290
for (; I != End; ++I) {
291
// If the intervening instruction I:
292
// * modifies I2's use reg
293
// * modifies I2's def reg
294
// * reads I2's def reg
295
// * or has unmodelled side effects
296
// we can't move I2 across it.
297
if (I->isDebugInstr())
298
continue;
299
300
if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {
301
isSafe = false;
302
break;
303
}
304
305
// Update first use of the killed operand.
306
if (!KillingInstr && KilledOperand &&
307
I->readsRegister(KilledOperand, TRI))
308
KillingInstr = &*I;
309
}
310
if (isSafe) {
311
// Update the intermediate instruction to with the kill flag.
312
if (KillingInstr) {
313
bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
314
(void)Added; // suppress compiler warning
315
assert(Added && "Must successfully update kill flag");
316
removeKillInfo(I2, KilledOperand);
317
}
318
DoInsertAtI1 = true;
319
return true;
320
}
321
}
322
323
// Try to move I1 towards I2.
324
{
325
// Look at instructions I in between I1 and (excluding) I2.
326
MachineBasicBlock::iterator I(I1), End(I2);
327
// At O3 we got better results (dhrystone) by being more conservative here.
328
if (!ShouldCombineAggressively)
329
End = std::next(MachineBasicBlock::iterator(I2));
330
Register I1UseReg = UseReg(I1.getOperand(1));
331
// Track killed operands. If we move across an instruction that kills our
332
// operand, we need to update the kill information on the moved I1. It kills
333
// the operand now.
334
MachineInstr *KillingInstr = nullptr;
335
unsigned KilledOperand = 0;
336
337
while(++I != End) {
338
MachineInstr &MI = *I;
339
// If the intervening instruction MI:
340
// * modifies I1's use reg
341
// * modifies I1's def reg
342
// * reads I1's def reg
343
// * or has unmodelled side effects
344
// We introduce this special case because llvm has no api to remove a
345
// kill flag for a register (a removeRegisterKilled() analogous to
346
// addRegisterKilled) that handles aliased register correctly.
347
// * or has a killed aliased register use of I1's use reg
348
// %d4 = A2_tfrpi 16
349
// %r6 = A2_tfr %r9
350
// %r8 = KILL %r8, implicit killed %d4
351
// If we want to move R6 = across the KILL instruction we would have
352
// to remove the implicit killed %d4 operand. For now, we are
353
// conservative and disallow the move.
354
// we can't move I1 across it.
355
if (MI.isDebugInstr()) {
356
if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.
357
DbgMItoMove.push_back(&MI);
358
continue;
359
}
360
361
if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||
362
// Check for an aliased register kill. Bail out if we see one.
363
(!MI.killsRegister(I1UseReg, /*TRI=*/nullptr) &&
364
MI.killsRegister(I1UseReg, TRI)))
365
return false;
366
367
// Check for an exact kill (registers match).
368
if (I1UseReg && MI.killsRegister(I1UseReg, /*TRI=*/nullptr)) {
369
assert(!KillingInstr && "Should only see one killing instruction");
370
KilledOperand = I1UseReg;
371
KillingInstr = &MI;
372
}
373
}
374
if (KillingInstr) {
375
removeKillInfo(*KillingInstr, KilledOperand);
376
// Update I1 to set the kill flag. This flag will later be picked up by
377
// the new COMBINE instruction.
378
bool Added = I1.addRegisterKilled(KilledOperand, TRI);
379
(void)Added; // suppress compiler warning
380
assert(Added && "Must successfully update kill flag");
381
}
382
DoInsertAtI1 = false;
383
}
384
385
return true;
386
}
387
388
/// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
389
/// newified. (A use of a 64 bit register define can not be newified)
390
void
391
HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
392
DenseMap<unsigned, MachineInstr *> LastDef;
393
for (MachineInstr &MI : BB) {
394
if (MI.isDebugInstr())
395
continue;
396
397
// Mark TFRs that feed a potential new value store as such.
398
if (TII->mayBeNewStore(MI)) {
399
// Look for uses of TFR instructions.
400
for (const MachineOperand &Op : MI.operands()) {
401
// Skip over anything except register uses.
402
if (!Op.isReg() || !Op.isUse() || !Op.getReg())
403
continue;
404
405
// Look for the defining instruction.
406
Register Reg = Op.getReg();
407
MachineInstr *DefInst = LastDef[Reg];
408
if (!DefInst)
409
continue;
410
if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
411
continue;
412
413
// Only close newifiable stores should influence the decision.
414
// Ignore the debug instructions in between.
415
MachineBasicBlock::iterator It(DefInst);
416
unsigned NumInstsToDef = 0;
417
while (&*It != &MI) {
418
if (!It->isDebugInstr())
419
++NumInstsToDef;
420
++It;
421
}
422
423
if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
424
continue;
425
426
PotentiallyNewifiableTFR.insert(DefInst);
427
}
428
// Skip to next instruction.
429
continue;
430
}
431
432
// Put instructions that last defined integer or double registers into the
433
// map.
434
for (MachineOperand &Op : MI.operands()) {
435
if (Op.isReg()) {
436
if (!Op.isDef() || !Op.getReg())
437
continue;
438
Register Reg = Op.getReg();
439
if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
440
for (MCPhysReg SubReg : TRI->subregs(Reg))
441
LastDef[SubReg] = &MI;
442
} else if (Hexagon::IntRegsRegClass.contains(Reg))
443
LastDef[Reg] = &MI;
444
} else if (Op.isRegMask()) {
445
for (unsigned Reg : Hexagon::IntRegsRegClass)
446
if (Op.clobbersPhysReg(Reg))
447
LastDef[Reg] = &MI;
448
}
449
}
450
}
451
}
452
453
bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
454
if (skipFunction(MF.getFunction()))
455
return false;
456
457
if (IsCombinesDisabled) return false;
458
459
bool HasChanged = false;
460
461
// Get target info.
462
ST = &MF.getSubtarget<HexagonSubtarget>();
463
TRI = ST->getRegisterInfo();
464
TII = ST->getInstrInfo();
465
466
const Function &F = MF.getFunction();
467
bool OptForSize = F.hasFnAttribute(Attribute::OptimizeForSize);
468
469
// Combine aggressively (for code size)
470
ShouldCombineAggressively =
471
MF.getTarget().getOptLevel() <= CodeGenOptLevel::Default;
472
473
// Disable CONST64 for tiny core since it takes a LD resource.
474
if (!OptForSize && ST->isTinyCore())
475
IsConst64Disabled = true;
476
477
// Traverse basic blocks.
478
for (MachineBasicBlock &MBB : MF) {
479
PotentiallyNewifiableTFR.clear();
480
findPotentialNewifiableTFRs(MBB);
481
482
// Traverse instructions in basic block.
483
for (MachineBasicBlock::iterator MI = MBB.begin(), End = MBB.end();
484
MI != End;) {
485
MachineInstr &I1 = *MI++;
486
487
if (I1.isDebugInstr())
488
continue;
489
490
// Don't combine a TFR whose user could be newified (instructions that
491
// define double registers can not be newified - Programmer's Ref Manual
492
// 5.4.2 New-value stores).
493
if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
494
continue;
495
496
// Ignore instructions that are not combinable.
497
if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
498
continue;
499
500
// Find a second instruction that can be merged into a combine
501
// instruction. In addition, also find all the debug instructions that
502
// need to be moved along with it.
503
bool DoInsertAtI1 = false;
504
DbgMItoMove.clear();
505
MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);
506
if (I2) {
507
HasChanged = true;
508
combine(I1, *I2, MI, DoInsertAtI1, OptForSize);
509
}
510
}
511
}
512
513
return HasChanged;
514
}
515
516
/// findPairable - Returns an instruction that can be merged with \p I1 into a
517
/// COMBINE instruction or 0 if no such instruction can be found. Returns true
518
/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
519
/// false if the combine must be inserted at the returned instruction.
520
MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
521
bool &DoInsertAtI1,
522
bool AllowC64) {
523
MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1));
524
while (I2 != I1.getParent()->end() && I2->isDebugInstr())
525
++I2;
526
527
Register I1DestReg = I1.getOperand(0).getReg();
528
529
for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;
530
++I2) {
531
// Bail out early if we see a second definition of I1DestReg.
532
if (I2->modifiesRegister(I1DestReg, TRI))
533
break;
534
535
// Ignore non-combinable instructions.
536
if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
537
continue;
538
539
// Don't combine a TFR whose user could be newified.
540
if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
541
continue;
542
543
Register I2DestReg = I2->getOperand(0).getReg();
544
545
// Check that registers are adjacent and that the first destination register
546
// is even.
547
bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
548
bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
549
unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
550
if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
551
continue;
552
553
// Check that the two instructions are combinable.
554
// The order matters because in a A2_tfrsi we might can encode a int8 as
555
// the hi reg operand but only a uint6 as the low reg operand.
556
if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
557
(IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
558
break;
559
560
if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
561
return &*I2;
562
563
// Not safe. Stop searching.
564
break;
565
}
566
return nullptr;
567
}
568
569
void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
570
MachineBasicBlock::iterator &MI,
571
bool DoInsertAtI1, bool OptForSize) {
572
// We are going to delete I2. If MI points to I2 advance it to the next
573
// instruction.
574
if (MI == I2.getIterator())
575
++MI;
576
577
// Figure out whether I1 or I2 goes into the lowreg part.
578
Register I1DestReg = I1.getOperand(0).getReg();
579
Register I2DestReg = I2.getOperand(0).getReg();
580
bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
581
unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
582
unsigned SubLo;
583
584
const TargetRegisterClass *SuperRC = nullptr;
585
if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {
586
SuperRC = &Hexagon::DoubleRegsRegClass;
587
SubLo = Hexagon::isub_lo;
588
} else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) {
589
assert(ST->useHVXOps());
590
SuperRC = &Hexagon::HvxWRRegClass;
591
SubLo = Hexagon::vsub_lo;
592
} else
593
llvm_unreachable("Unexpected register class");
594
595
// Get the double word register.
596
unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);
597
assert(DoubleRegDest != 0 && "Expect a valid register");
598
599
// Setup source operands.
600
MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
601
MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
602
603
// Figure out which source is a register and which a constant.
604
bool IsHiReg = HiOperand.isReg();
605
bool IsLoReg = LoOperand.isReg();
606
607
// There is a combine of two constant extended values into CONST64.
608
bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
609
isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);
610
611
MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
612
// Emit combine.
613
if (IsHiReg && IsLoReg)
614
emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
615
else if (IsHiReg)
616
emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
617
else if (IsLoReg)
618
emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
619
else if (IsC64 && !IsConst64Disabled)
620
emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
621
else
622
emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
623
624
// Move debug instructions along with I1 if it's being
625
// moved towards I2.
626
if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
627
// Insert debug instructions at the new location before I2.
628
MachineBasicBlock *BB = InsertPt->getParent();
629
for (auto *NewMI : DbgMItoMove) {
630
// If iterator MI is pointing to DEBUG_VAL, make sure
631
// MI now points to next relevant instruction.
632
if (NewMI == MI)
633
++MI;
634
BB->splice(InsertPt, BB, NewMI);
635
}
636
}
637
638
I1.eraseFromParent();
639
I2.eraseFromParent();
640
}
641
642
void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
643
unsigned DoubleDestReg,
644
MachineOperand &HiOperand,
645
MachineOperand &LoOperand) {
646
LLVM_DEBUG(dbgs() << "Found a CONST64\n");
647
648
DebugLoc DL = InsertPt->getDebugLoc();
649
MachineBasicBlock *BB = InsertPt->getParent();
650
assert(LoOperand.isImm() && HiOperand.isImm() &&
651
"Both operands must be immediate");
652
653
int64_t V = HiOperand.getImm();
654
V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
655
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)
656
.addImm(V);
657
}
658
659
void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
660
unsigned DoubleDestReg,
661
MachineOperand &HiOperand,
662
MachineOperand &LoOperand) {
663
DebugLoc DL = InsertPt->getDebugLoc();
664
MachineBasicBlock *BB = InsertPt->getParent();
665
666
// Handle globals.
667
if (HiOperand.isGlobal()) {
668
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
669
.addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
670
HiOperand.getTargetFlags())
671
.addImm(LoOperand.getImm());
672
return;
673
}
674
if (LoOperand.isGlobal()) {
675
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
676
.addImm(HiOperand.getImm())
677
.addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
678
LoOperand.getTargetFlags());
679
return;
680
}
681
682
// Handle block addresses.
683
if (HiOperand.isBlockAddress()) {
684
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
685
.addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
686
HiOperand.getTargetFlags())
687
.addImm(LoOperand.getImm());
688
return;
689
}
690
if (LoOperand.isBlockAddress()) {
691
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
692
.addImm(HiOperand.getImm())
693
.addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
694
LoOperand.getTargetFlags());
695
return;
696
}
697
698
// Handle jump tables.
699
if (HiOperand.isJTI()) {
700
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
701
.addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
702
.addImm(LoOperand.getImm());
703
return;
704
}
705
if (LoOperand.isJTI()) {
706
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
707
.addImm(HiOperand.getImm())
708
.addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
709
return;
710
}
711
712
// Handle constant pools.
713
if (HiOperand.isCPI()) {
714
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
715
.addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
716
HiOperand.getTargetFlags())
717
.addImm(LoOperand.getImm());
718
return;
719
}
720
if (LoOperand.isCPI()) {
721
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
722
.addImm(HiOperand.getImm())
723
.addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
724
LoOperand.getTargetFlags());
725
return;
726
}
727
728
// First preference should be given to Hexagon::A2_combineii instruction
729
// as it can include U6 (in Hexagon::A4_combineii) as well.
730
// In this instruction, HiOperand is const extended, if required.
731
if (isInt<8>(LoOperand.getImm())) {
732
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
733
.addImm(HiOperand.getImm())
734
.addImm(LoOperand.getImm());
735
return;
736
}
737
738
// In this instruction, LoOperand is const extended, if required.
739
if (isInt<8>(HiOperand.getImm())) {
740
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
741
.addImm(HiOperand.getImm())
742
.addImm(LoOperand.getImm());
743
return;
744
}
745
746
// Insert new combine instruction.
747
// DoubleRegDest = combine #HiImm, #LoImm
748
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
749
.addImm(HiOperand.getImm())
750
.addImm(LoOperand.getImm());
751
}
752
753
void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
754
unsigned DoubleDestReg,
755
MachineOperand &HiOperand,
756
MachineOperand &LoOperand) {
757
Register LoReg = LoOperand.getReg();
758
unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
759
760
DebugLoc DL = InsertPt->getDebugLoc();
761
MachineBasicBlock *BB = InsertPt->getParent();
762
763
// Handle globals.
764
if (HiOperand.isGlobal()) {
765
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
766
.addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
767
HiOperand.getTargetFlags())
768
.addReg(LoReg, LoRegKillFlag);
769
return;
770
}
771
// Handle block addresses.
772
if (HiOperand.isBlockAddress()) {
773
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
774
.addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
775
HiOperand.getTargetFlags())
776
.addReg(LoReg, LoRegKillFlag);
777
return;
778
}
779
// Handle jump tables.
780
if (HiOperand.isJTI()) {
781
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
782
.addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
783
.addReg(LoReg, LoRegKillFlag);
784
return;
785
}
786
// Handle constant pools.
787
if (HiOperand.isCPI()) {
788
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
789
.addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
790
HiOperand.getTargetFlags())
791
.addReg(LoReg, LoRegKillFlag);
792
return;
793
}
794
// Insert new combine instruction.
795
// DoubleRegDest = combine #HiImm, LoReg
796
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
797
.addImm(HiOperand.getImm())
798
.addReg(LoReg, LoRegKillFlag);
799
}
800
801
void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
802
unsigned DoubleDestReg,
803
MachineOperand &HiOperand,
804
MachineOperand &LoOperand) {
805
unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
806
Register HiReg = HiOperand.getReg();
807
808
DebugLoc DL = InsertPt->getDebugLoc();
809
MachineBasicBlock *BB = InsertPt->getParent();
810
811
// Handle global.
812
if (LoOperand.isGlobal()) {
813
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
814
.addReg(HiReg, HiRegKillFlag)
815
.addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
816
LoOperand.getTargetFlags());
817
return;
818
}
819
// Handle block addresses.
820
if (LoOperand.isBlockAddress()) {
821
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
822
.addReg(HiReg, HiRegKillFlag)
823
.addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
824
LoOperand.getTargetFlags());
825
return;
826
}
827
// Handle jump tables.
828
if (LoOperand.isJTI()) {
829
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
830
.addReg(HiOperand.getReg(), HiRegKillFlag)
831
.addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
832
return;
833
}
834
// Handle constant pools.
835
if (LoOperand.isCPI()) {
836
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
837
.addReg(HiOperand.getReg(), HiRegKillFlag)
838
.addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
839
LoOperand.getTargetFlags());
840
return;
841
}
842
843
// Insert new combine instruction.
844
// DoubleRegDest = combine HiReg, #LoImm
845
BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
846
.addReg(HiReg, HiRegKillFlag)
847
.addImm(LoOperand.getImm());
848
}
849
850
void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
851
unsigned DoubleDestReg,
852
MachineOperand &HiOperand,
853
MachineOperand &LoOperand) {
854
unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
855
unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
856
Register LoReg = LoOperand.getReg();
857
Register HiReg = HiOperand.getReg();
858
859
DebugLoc DL = InsertPt->getDebugLoc();
860
MachineBasicBlock *BB = InsertPt->getParent();
861
862
// Insert new combine instruction.
863
// DoubleRegDest = combine HiReg, LoReg
864
unsigned NewOpc;
865
if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {
866
NewOpc = Hexagon::A2_combinew;
867
} else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) {
868
assert(ST->useHVXOps());
869
NewOpc = Hexagon::V6_vcombine;
870
} else
871
llvm_unreachable("Unexpected register");
872
873
BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
874
.addReg(HiReg, HiRegKillFlag)
875
.addReg(LoReg, LoRegKillFlag);
876
}
877
878
FunctionPass *llvm::createHexagonCopyToCombine() {
879
return new HexagonCopyToCombine();
880
}
881
882