1 //===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
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
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 //===----------------------------------------------------------------------===//
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"
34 #define DEBUG_TYPE "hexagon-copy-combine"
37 IsCombinesDisabled("disable-merge-into-combines", cl::Hidden
,
39 cl::desc("Disable merging into combines"));
41 IsConst64Disabled("disable-const64", cl::Hidden
,
43 cl::desc("Disable generation of const64"));
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"));
52 FunctionPass
*createHexagonCopyToCombine();
53 void initializeHexagonCopyToCombinePass(PassRegistry
&);
59 class HexagonCopyToCombine
: public MachineFunctionPass
{
60 const HexagonInstrInfo
*TII
;
61 const TargetRegisterInfo
*TRI
;
62 const HexagonSubtarget
*ST
;
63 bool ShouldCombineAggressively
;
65 DenseSet
<MachineInstr
*> PotentiallyNewifiableTFR
;
66 SmallVector
<MachineInstr
*, 8> DbgMItoMove
;
71 HexagonCopyToCombine() : MachineFunctionPass(ID
) {}
73 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
74 MachineFunctionPass::getAnalysisUsage(AU
);
77 StringRef
getPassName() const override
{
78 return "Hexagon Copy-To-Combine Pass";
81 bool runOnMachineFunction(MachineFunction
&Fn
) override
;
83 MachineFunctionProperties
getRequiredProperties() const override
{
84 return MachineFunctionProperties().set(
85 MachineFunctionProperties::Property::NoVRegs
);
89 MachineInstr
*findPairable(MachineInstr
&I1
, bool &DoInsertAtI1
,
92 void findPotentialNewifiableTFRs(MachineBasicBlock
&);
94 void combine(MachineInstr
&I1
, MachineInstr
&I2
,
95 MachineBasicBlock::iterator
&MI
, bool DoInsertAtI1
,
98 bool isSafeToMoveTogether(MachineInstr
&I1
, MachineInstr
&I2
,
99 unsigned I1DestReg
, unsigned I2DestReg
,
102 void emitCombineRR(MachineBasicBlock::iterator
&Before
, unsigned DestReg
,
103 MachineOperand
&HiOperand
, MachineOperand
&LoOperand
);
105 void emitCombineRI(MachineBasicBlock::iterator
&Before
, unsigned DestReg
,
106 MachineOperand
&HiOperand
, MachineOperand
&LoOperand
);
108 void emitCombineIR(MachineBasicBlock::iterator
&Before
, unsigned DestReg
,
109 MachineOperand
&HiOperand
, MachineOperand
&LoOperand
);
111 void emitCombineII(MachineBasicBlock::iterator
&Before
, unsigned DestReg
,
112 MachineOperand
&HiOperand
, MachineOperand
&LoOperand
);
114 void emitConst64(MachineBasicBlock::iterator
&Before
, unsigned DestReg
,
115 MachineOperand
&HiOperand
, MachineOperand
&LoOperand
);
118 } // End anonymous namespace.
120 char HexagonCopyToCombine::ID
= 0;
122 INITIALIZE_PASS(HexagonCopyToCombine
, "hexagon-copy-combine",
123 "Hexagon Copy-To-Combine Pass", false, false)
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());
134 Register DestReg
= Op0
.getReg();
135 Register SrcReg
= Op1
.getReg();
136 return Hexagon::IntRegsRegClass
.contains(DestReg
) &&
137 Hexagon::IntRegsRegClass
.contains(SrcReg
);
140 case Hexagon::A2_tfrsi
: {
141 // A transfer-immediate can be combined if its argument is a signed 8bit
143 const MachineOperand
&Op0
= MI
.getOperand(0);
144 const MachineOperand
&Op1
= MI
.getOperand(1);
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
151 if (!Op1
.isImm() && Op1
.getTargetFlags() != HexagonII::MO_NO_FLAG
)
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
);
160 case Hexagon::V6_vassign
:
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());
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();
187 auto verifyOpc
= [](unsigned Opc
) -> void {
189 case Hexagon::A2_tfr
:
190 case Hexagon::A2_tfrsi
:
191 case Hexagon::V6_vassign
:
194 llvm_unreachable("Unexpected opcode");
200 if (HiOpc
== Hexagon::V6_vassign
|| LoOpc
== Hexagon::V6_vassign
)
201 return HiOpc
== LoOpc
;
204 // There is no combine of two constant extended values.
205 if (isGreaterThanNBitTFRI
<8>(HighRegInst
) &&
206 isGreaterThanNBitTFRI
<6>(LowRegInst
))
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());
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
))
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");
235 static void removeKillInfo(MachineInstr
&MI
, unsigned RegNotKilled
) {
236 for (MachineOperand
&Op
: MI
.operands())
237 if (Op
.isReg() && Op
.getReg() == RegNotKilled
&& Op
.isKill())
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
,
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();
252 static Register
UseReg(const MachineOperand
& MO
) {
253 return MO
.isReg() ? MO
.getReg() : Register();
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
,
262 bool &DoInsertAtI1
) {
263 Register I2UseReg
= UseReg(I2
.getOperand(1));
265 // It is not safe to move I1 and I2 into one combine if I2 has a true
267 if (I2UseReg
&& I1
.modifiesRegister(I2UseReg
, TRI
))
272 // First try to move I2 towards I1.
274 // A reverse_iterator instantiated like below starts before I2, and I1
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
285 unsigned KilledOperand
= 0;
286 if (I2
.killsRegister(I2UseReg
, /*TRI=*/nullptr))
287 KilledOperand
= I2UseReg
;
288 MachineInstr
*KillingInstr
= nullptr;
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())
300 if (isUnsafeToMoveAcross(*I
, I2UseReg
, I2DestReg
, TRI
)) {
305 // Update first use of the killed operand.
306 if (!KillingInstr
&& KilledOperand
&&
307 I
->readsRegister(KilledOperand
, TRI
))
311 // Update the intermediate instruction to with the kill flag.
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
);
323 // Try to move I1 towards I2.
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
334 MachineInstr
*KillingInstr
= nullptr;
335 unsigned KilledOperand
= 0;
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
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
);
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
)))
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
;
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");
382 DoInsertAtI1
= false;
388 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
389 /// newified. (A use of a 64 bit register define can not be newified)
391 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock
&BB
) {
392 DenseMap
<unsigned, MachineInstr
*> LastDef
;
393 for (MachineInstr
&MI
: BB
) {
394 if (MI
.isDebugInstr())
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())
405 // Look for the defining instruction.
406 Register Reg
= Op
.getReg();
407 MachineInstr
*DefInst
= LastDef
[Reg
];
410 if (!isCombinableInstType(*DefInst
, TII
, ShouldCombineAggressively
))
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())
423 if (NumInstsToDef
> MaxNumOfInstsBetweenNewValueStoreAndTFR
)
426 PotentiallyNewifiableTFR
.insert(DefInst
);
428 // Skip to next instruction.
432 // Put instructions that last defined integer or double registers into the
434 for (MachineOperand
&Op
: MI
.operands()) {
436 if (!Op
.isDef() || !Op
.getReg())
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
))
444 } else if (Op
.isRegMask()) {
445 for (unsigned Reg
: Hexagon::IntRegsRegClass
)
446 if (Op
.clobbersPhysReg(Reg
))
453 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction
&MF
) {
454 if (skipFunction(MF
.getFunction()))
457 if (IsCombinesDisabled
) return false;
459 bool HasChanged
= false;
462 ST
= &MF
.getSubtarget
<HexagonSubtarget
>();
463 TRI
= ST
->getRegisterInfo();
464 TII
= ST
->getInstrInfo();
466 const Function
&F
= MF
.getFunction();
467 bool OptForSize
= F
.hasFnAttribute(Attribute::OptimizeForSize
);
469 // Combine aggressively (for code size)
470 ShouldCombineAggressively
=
471 MF
.getTarget().getOptLevel() <= CodeGenOptLevel::Default
;
473 // Disable CONST64 for tiny core since it takes a LD resource.
474 if (!OptForSize
&& ST
->isTinyCore())
475 IsConst64Disabled
= true;
477 // Traverse basic blocks.
478 for (MachineBasicBlock
&MBB
: MF
) {
479 PotentiallyNewifiableTFR
.clear();
480 findPotentialNewifiableTFRs(MBB
);
482 // Traverse instructions in basic block.
483 for (MachineBasicBlock::iterator MI
= MBB
.begin(), End
= MBB
.end();
485 MachineInstr
&I1
= *MI
++;
487 if (I1
.isDebugInstr())
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
))
496 // Ignore instructions that are not combinable.
497 if (!isCombinableInstType(I1
, TII
, ShouldCombineAggressively
))
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;
505 MachineInstr
*I2
= findPairable(I1
, DoInsertAtI1
, OptForSize
);
508 combine(I1
, *I2
, MI
, DoInsertAtI1
, OptForSize
);
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
,
523 MachineBasicBlock::iterator I2
= std::next(MachineBasicBlock::iterator(I1
));
524 while (I2
!= I1
.getParent()->end() && I2
->isDebugInstr())
527 Register I1DestReg
= I1
.getOperand(0).getReg();
529 for (MachineBasicBlock::iterator End
= I1
.getParent()->end(); I2
!= End
;
531 // Bail out early if we see a second definition of I1DestReg.
532 if (I2
->modifiesRegister(I1DestReg
, TRI
))
535 // Ignore non-combinable instructions.
536 if (!isCombinableInstType(*I2
, TII
, ShouldCombineAggressively
))
539 // Don't combine a TFR whose user could be newified.
540 if (ShouldCombineAggressively
&& PotentiallyNewifiableTFR
.count(&*I2
))
543 Register I2DestReg
= I2
->getOperand(0).getReg();
545 // Check that registers are adjacent and that the first destination register
547 bool IsI1LowReg
= (I2DestReg
- I1DestReg
) == 1;
548 bool IsI2LowReg
= (I1DestReg
- I2DestReg
) == 1;
549 unsigned FirstRegIndex
= IsI1LowReg
? I1DestReg
: I2DestReg
;
550 if ((!IsI1LowReg
&& !IsI2LowReg
) || !isEvenReg(FirstRegIndex
))
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
)))
560 if (isSafeToMoveTogether(I1
, *I2
, I1DestReg
, I2DestReg
, DoInsertAtI1
))
563 // Not safe. Stop searching.
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
574 if (MI
== I2
.getIterator())
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
;
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
;
593 llvm_unreachable("Unexpected register class");
595 // Get the double word register.
596 unsigned DoubleRegDest
= TRI
->getMatchingSuperReg(LoRegDef
, SubLo
, SuperRC
);
597 assert(DoubleRegDest
!= 0 && "Expect a valid register");
599 // Setup source operands.
600 MachineOperand
&LoOperand
= IsI1Loreg
? I1
.getOperand(1) : I2
.getOperand(1);
601 MachineOperand
&HiOperand
= IsI1Loreg
? I2
.getOperand(1) : I1
.getOperand(1);
603 // Figure out which source is a register and which a constant.
604 bool IsHiReg
= HiOperand
.isReg();
605 bool IsLoReg
= LoOperand
.isReg();
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
);
611 MachineBasicBlock::iterator
InsertPt(DoInsertAtI1
? I1
: I2
);
613 if (IsHiReg
&& IsLoReg
)
614 emitCombineRR(InsertPt
, DoubleRegDest
, HiOperand
, LoOperand
);
616 emitCombineRI(InsertPt
, DoubleRegDest
, HiOperand
, LoOperand
);
618 emitCombineIR(InsertPt
, DoubleRegDest
, HiOperand
, LoOperand
);
619 else if (IsC64
&& !IsConst64Disabled
)
620 emitConst64(InsertPt
, DoubleRegDest
, HiOperand
, LoOperand
);
622 emitCombineII(InsertPt
, DoubleRegDest
, HiOperand
, LoOperand
);
624 // Move debug instructions along with I1 if it's being
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.
634 BB
->splice(InsertPt
, BB
, NewMI
);
638 I1
.eraseFromParent();
639 I2
.eraseFromParent();
642 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator
&InsertPt
,
643 unsigned DoubleDestReg
,
644 MachineOperand
&HiOperand
,
645 MachineOperand
&LoOperand
) {
646 LLVM_DEBUG(dbgs() << "Found a CONST64\n");
648 DebugLoc DL
= InsertPt
->getDebugLoc();
649 MachineBasicBlock
*BB
= InsertPt
->getParent();
650 assert(LoOperand
.isImm() && HiOperand
.isImm() &&
651 "Both operands must be immediate");
653 int64_t V
= HiOperand
.getImm();
654 V
= (V
<< 32) | (0x0ffffffffLL
& LoOperand
.getImm());
655 BuildMI(*BB
, InsertPt
, DL
, TII
->get(Hexagon::CONST64
), DoubleDestReg
)
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();
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
760 DebugLoc DL
= InsertPt
->getDebugLoc();
761 MachineBasicBlock
*BB
= InsertPt
->getParent();
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
);
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
);
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
);
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
);
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
);
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();
808 DebugLoc DL
= InsertPt
->getDebugLoc();
809 MachineBasicBlock
*BB
= InsertPt
->getParent();
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());
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());
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());
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());
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());
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();
859 DebugLoc DL
= InsertPt
->getDebugLoc();
860 MachineBasicBlock
*BB
= InsertPt
->getParent();
862 // Insert new combine instruction.
863 // DoubleRegDest = combine HiReg, LoReg
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
;
871 llvm_unreachable("Unexpected register");
873 BuildMI(*BB
, InsertPt
, DL
, TII
->get(NewOpc
), DoubleDestReg
)
874 .addReg(HiReg
, HiRegKillFlag
)
875 .addReg(LoReg
, LoRegKillFlag
);
878 FunctionPass
*llvm::createHexagonCopyToCombine() {
879 return new HexagonCopyToCombine();