LLVM 24.0.0git
HexagonCopyToCombine.cpp
Go to the documentation of this file.
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"
23#include "llvm/CodeGen/Passes.h"
25#include "llvm/Pass.h"
28#include "llvm/Support/Debug.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "hexagon-copy-combine"
35
36static cl::opt<bool>
37 IsCombinesDisabled("disable-merge-into-combines", cl::Hidden,
38
39 cl::desc("Disable merging into combines"));
40static cl::opt<bool>
41 IsConst64Disabled("disable-const64", cl::Hidden,
42
43 cl::desc("Disable generation of const64"));
44static
46MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
48 cl::desc("Maximum distance between a tfr feeding a store we "
49 "consider the store still to be newifiable"));
50
51namespace {
52
53class HexagonCopyToCombine : public MachineFunctionPass {
54 const HexagonInstrInfo *TII;
56 const HexagonSubtarget *ST;
58
59 DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
61
62public:
63 static char ID;
64
65 HexagonCopyToCombine() : MachineFunctionPass(ID) {}
66
67 void getAnalysisUsage(AnalysisUsage &AU) const override {
69 }
70
71 StringRef getPassName() const override {
72 return "Hexagon Copy-To-Combine Pass";
73 }
74
75 bool runOnMachineFunction(MachineFunction &Fn) override;
76
77 MachineFunctionProperties getRequiredProperties() const override {
78 return MachineFunctionProperties().setNoVRegs();
79 }
80
81private:
82 MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,
83 bool AllowC64);
84
85 void findPotentialNewifiableTFRs(MachineBasicBlock &);
86
87 void combine(MachineInstr &I1, MachineInstr &I2,
88 MachineBasicBlock::iterator &MI, bool DoInsertAtI1,
89 bool OptForSize);
90
91 bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,
92 unsigned I1DestReg, unsigned I2DestReg,
93 bool &DoInsertAtI1);
94
95 void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
96 MachineOperand &HiOperand, MachineOperand &LoOperand);
97
98 void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
99 MachineOperand &HiOperand, MachineOperand &LoOperand);
100
101 void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
102 MachineOperand &HiOperand, MachineOperand &LoOperand);
103
104 void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
105 MachineOperand &HiOperand, MachineOperand &LoOperand);
106
107 void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,
108 MachineOperand &HiOperand, MachineOperand &LoOperand);
109};
110
111} // End anonymous namespace.
112
113char HexagonCopyToCombine::ID = 0;
114
115INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
116 "Hexagon Copy-To-Combine Pass", false, false)
117
118static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,
120 switch (MI.getOpcode()) {
121 case Hexagon::A2_tfr: {
122 // A COPY instruction can be combined if its arguments are IntRegs (32bit).
123 const MachineOperand &Op0 = MI.getOperand(0);
124 const MachineOperand &Op1 = MI.getOperand(1);
125 assert(Op0.isReg() && Op1.isReg());
126
127 Register DestReg = Op0.getReg();
128 Register SrcReg = Op1.getReg();
129 return Hexagon::IntRegsRegClass.contains(DestReg) &&
130 Hexagon::IntRegsRegClass.contains(SrcReg);
131 }
132
133 case Hexagon::A2_tfrsi: {
134 // A transfer-immediate can be combined if its argument is a signed 8bit
135 // value.
136 const MachineOperand &Op0 = MI.getOperand(0);
137 const MachineOperand &Op1 = MI.getOperand(1);
138 assert(Op0.isReg());
139
140 Register DestReg = Op0.getReg();
141 // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
142 // workaround for an ABI bug that prevents GOT relocations on combine
143 // instructions
144 if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)
145 return false;
146
147 // Only combine constant extended A2_tfrsi if we are in aggressive mode.
148 bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());
149 return Hexagon::IntRegsRegClass.contains(DestReg) &&
150 (ShouldCombineAggressively || NotExt);
151 }
152
153 case Hexagon::V6_vassign:
154 case Hexagon::LX_assign:
155 return true;
156
157 default:
158 break;
159 }
160
161 return false;
162}
163
164template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {
165 if (I.getOpcode() == Hexagon::TFRI64_V4 ||
166 I.getOpcode() == Hexagon::A2_tfrsi) {
167 const MachineOperand &Op = I.getOperand(1);
168 return !Op.isImm() || !isInt<N>(Op.getImm());
169 }
170 return false;
171}
172
173/// areCombinableOperations - Returns true if the two instruction can be merge
174/// into a combine (ignoring register constraints).
176 MachineInstr &HighRegInst,
177 MachineInstr &LowRegInst, bool AllowC64) {
178 unsigned HiOpc = HighRegInst.getOpcode();
179 unsigned LoOpc = LowRegInst.getOpcode();
180
181 auto verifyOpc = [](unsigned Opc) -> void {
182 switch (Opc) {
183 case Hexagon::A2_tfr:
184 case Hexagon::A2_tfrsi:
185 case Hexagon::V6_vassign:
186 case Hexagon::LX_assign:
187 break;
188 default:
189 llvm_unreachable("Unexpected opcode");
190 }
191 };
192 verifyOpc(HiOpc);
193 verifyOpc(LoOpc);
194
195 if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)
196 return HiOpc == LoOpc;
197
198 if (HiOpc == Hexagon::LX_assign || LoOpc == Hexagon::LX_assign)
199 return HiOpc == LoOpc;
200
201 if (!AllowC64) {
202 // There is no combine of two constant extended values.
203 if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
204 isGreaterThanNBitTFRI<6>(LowRegInst))
205 return false;
206 }
207
208 // There is a combine of two constant extended values into CONST64,
209 // provided both constants are true immediates.
210 if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
212 return (HighRegInst.getOperand(1).isImm() &&
213 LowRegInst.getOperand(1).isImm());
214
215 // There is no combine of two constant extended values, unless handled above
216 // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)
217 if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
218 isGreaterThanNBitTFRI<8>(LowRegInst))
219 return false;
220
221 return true;
222}
223
224static bool isEvenReg(unsigned Reg) {
226 if (Hexagon::IntRegsRegClass.contains(Reg))
227 return (Reg - Hexagon::R0) % 2 == 0;
228 if (Hexagon::HvxVRRegClass.contains(Reg))
229 return (Reg - Hexagon::V0) % 2 == 0;
230 if (Hexagon::HlxLRRegClass.contains(Reg))
231 return (Reg - Hexagon::L0) % 2 == 0;
232 llvm_unreachable("Invalid register");
233}
234
235static 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.
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
252static 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.
258bool 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.
278 MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse();
279 // At 03 we got better results (dhrystone!) by being more conservative.
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.
327 // At O3 we got better results (dhrystone) by being more conservative here.
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 transfers that feed stores that could be
389/// newified. (A use of a 64 bit register define can not be newified)
390void
391HexagonCopyToCombine::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
453bool 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.hasOptSize();
468
469 // Combine aggressively (for code size)
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.
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.
520MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
521 bool &DoInsertAtI1,
522 bool AllowC64) {
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
569void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
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 if (Hexagon::HlxLRRegClass.contains(LoRegDef)) {
593 assert(ST->useHLXOps());
594 SuperRC = &Hexagon::HlxLLRRegClass;
595 SubLo = Hexagon::vsub_lo;
596 } else
597 llvm_unreachable("Unexpected register class");
598
599 // Get the double word register.
600 MCRegister DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);
601 assert(DoubleRegDest.isValid() && "Expect a valid register");
602
603 // Setup source operands.
604 MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
605 MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
606
607 // Figure out which source is a register and which a constant.
608 bool IsHiReg = HiOperand.isReg();
609 bool IsLoReg = LoOperand.isReg();
610
611 // There is a combine of two constant extended values into CONST64.
612 bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
614
615 MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
616 // Emit combine.
617 if (IsHiReg && IsLoReg)
618 emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
619 else if (IsHiReg)
620 emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
621 else if (IsLoReg)
622 emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
623 else if (IsC64 && !IsConst64Disabled)
624 emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
625 else
626 emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
627
628 // Move debug instructions along with I1 if it's being
629 // moved towards I2.
630 if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
631 // Insert debug instructions at the new location before I2.
632 MachineBasicBlock *BB = InsertPt->getParent();
633 for (auto *NewMI : DbgMItoMove) {
634 // If iterator MI is pointing to DEBUG_VAL, make sure
635 // MI now points to next relevant instruction.
636 if (NewMI == MI)
637 ++MI;
638 BB->splice(InsertPt, BB, NewMI);
639 }
640 }
641
642 I1.eraseFromParent();
643 I2.eraseFromParent();
644}
645
646void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
647 unsigned DoubleDestReg,
648 MachineOperand &HiOperand,
649 MachineOperand &LoOperand) {
650 LLVM_DEBUG(dbgs() << "Found a CONST64\n");
651
652 DebugLoc DL = InsertPt->getDebugLoc();
653 MachineBasicBlock *BB = InsertPt->getParent();
654 assert(LoOperand.isImm() && HiOperand.isImm() &&
655 "Both operands must be immediate");
656
657 int64_t V = HiOperand.getImm();
658 V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
659 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)
660 .addImm(V);
661}
662
663void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
664 unsigned DoubleDestReg,
665 MachineOperand &HiOperand,
666 MachineOperand &LoOperand) {
667 DebugLoc DL = InsertPt->getDebugLoc();
668 MachineBasicBlock *BB = InsertPt->getParent();
669
670 // Handle globals.
671 if (HiOperand.isGlobal()) {
672 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
673 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
674 HiOperand.getTargetFlags())
675 .addImm(LoOperand.getImm());
676 return;
677 }
678 if (LoOperand.isGlobal()) {
679 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
680 .addImm(HiOperand.getImm())
681 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
682 LoOperand.getTargetFlags());
683 return;
684 }
685
686 // Handle block addresses.
687 if (HiOperand.isBlockAddress()) {
688 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
689 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
690 HiOperand.getTargetFlags())
691 .addImm(LoOperand.getImm());
692 return;
693 }
694 if (LoOperand.isBlockAddress()) {
695 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
696 .addImm(HiOperand.getImm())
697 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
698 LoOperand.getTargetFlags());
699 return;
700 }
701
702 // Handle jump tables.
703 if (HiOperand.isJTI()) {
704 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
705 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
706 .addImm(LoOperand.getImm());
707 return;
708 }
709 if (LoOperand.isJTI()) {
710 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
711 .addImm(HiOperand.getImm())
712 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
713 return;
714 }
715
716 // Handle constant pools.
717 if (HiOperand.isCPI()) {
718 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
719 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
720 HiOperand.getTargetFlags())
721 .addImm(LoOperand.getImm());
722 return;
723 }
724 if (LoOperand.isCPI()) {
725 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
726 .addImm(HiOperand.getImm())
727 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
728 LoOperand.getTargetFlags());
729 return;
730 }
731
732 // First preference should be given to Hexagon::A2_combineii instruction
733 // as it can include U6 (in Hexagon::A4_combineii) as well.
734 // In this instruction, HiOperand is const extended, if required.
735 if (isInt<8>(LoOperand.getImm())) {
736 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
737 .addImm(HiOperand.getImm())
738 .addImm(LoOperand.getImm());
739 return;
740 }
741
742 // In this instruction, LoOperand is const extended, if required.
743 if (isInt<8>(HiOperand.getImm())) {
744 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
745 .addImm(HiOperand.getImm())
746 .addImm(LoOperand.getImm());
747 return;
748 }
749
750 // Insert new combine instruction.
751 // DoubleRegDest = combine #HiImm, #LoImm
752 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
753 .addImm(HiOperand.getImm())
754 .addImm(LoOperand.getImm());
755}
756
757void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
758 unsigned DoubleDestReg,
759 MachineOperand &HiOperand,
760 MachineOperand &LoOperand) {
761 Register LoReg = LoOperand.getReg();
762 RegState LoRegKillFlag = getKillRegState(LoOperand.isKill());
763
764 DebugLoc DL = InsertPt->getDebugLoc();
765 MachineBasicBlock *BB = InsertPt->getParent();
766
767 // Handle globals.
768 if (HiOperand.isGlobal()) {
769 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
770 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
771 HiOperand.getTargetFlags())
772 .addReg(LoReg, LoRegKillFlag);
773 return;
774 }
775 // Handle block addresses.
776 if (HiOperand.isBlockAddress()) {
777 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
778 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
779 HiOperand.getTargetFlags())
780 .addReg(LoReg, LoRegKillFlag);
781 return;
782 }
783 // Handle jump tables.
784 if (HiOperand.isJTI()) {
785 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
786 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
787 .addReg(LoReg, LoRegKillFlag);
788 return;
789 }
790 // Handle constant pools.
791 if (HiOperand.isCPI()) {
792 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
793 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
794 HiOperand.getTargetFlags())
795 .addReg(LoReg, LoRegKillFlag);
796 return;
797 }
798 // Insert new combine instruction.
799 // DoubleRegDest = combine #HiImm, LoReg
800 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
801 .addImm(HiOperand.getImm())
802 .addReg(LoReg, LoRegKillFlag);
803}
804
805void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
806 unsigned DoubleDestReg,
807 MachineOperand &HiOperand,
808 MachineOperand &LoOperand) {
809 RegState HiRegKillFlag = getKillRegState(HiOperand.isKill());
810 Register HiReg = HiOperand.getReg();
811
812 DebugLoc DL = InsertPt->getDebugLoc();
813 MachineBasicBlock *BB = InsertPt->getParent();
814
815 // Handle global.
816 if (LoOperand.isGlobal()) {
817 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
818 .addReg(HiReg, HiRegKillFlag)
819 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
820 LoOperand.getTargetFlags());
821 return;
822 }
823 // Handle block addresses.
824 if (LoOperand.isBlockAddress()) {
825 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
826 .addReg(HiReg, HiRegKillFlag)
827 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
828 LoOperand.getTargetFlags());
829 return;
830 }
831 // Handle jump tables.
832 if (LoOperand.isJTI()) {
833 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
834 .addReg(HiOperand.getReg(), HiRegKillFlag)
835 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
836 return;
837 }
838 // Handle constant pools.
839 if (LoOperand.isCPI()) {
840 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
841 .addReg(HiOperand.getReg(), HiRegKillFlag)
842 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
843 LoOperand.getTargetFlags());
844 return;
845 }
846
847 // Insert new combine instruction.
848 // DoubleRegDest = combine HiReg, #LoImm
849 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
850 .addReg(HiReg, HiRegKillFlag)
851 .addImm(LoOperand.getImm());
852}
853
854void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
855 unsigned DoubleDestReg,
856 MachineOperand &HiOperand,
857 MachineOperand &LoOperand) {
858 RegState LoRegKillFlag = getKillRegState(LoOperand.isKill());
859 RegState HiRegKillFlag = getKillRegState(HiOperand.isKill());
860 Register LoReg = LoOperand.getReg();
861 Register HiReg = HiOperand.getReg();
862
863 DebugLoc DL = InsertPt->getDebugLoc();
864 MachineBasicBlock *BB = InsertPt->getParent();
865
866 // Insert new combine instruction.
867 // DoubleRegDest = combine HiReg, LoReg
868 unsigned NewOpc;
869 if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {
870 NewOpc = Hexagon::A2_combinew;
871 } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) {
872 assert(ST->useHVXOps());
873 NewOpc = Hexagon::V6_vcombine;
874 } else if (Hexagon::HlxLLRRegClass.contains(DoubleDestReg)) {
875 assert(ST->useHLXOps());
876 NewOpc = Hexagon::LX_combine_w;
877 } else
878 llvm_unreachable("Unexpected register");
879
880 BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
881 .addReg(HiReg, HiRegKillFlag)
882 .addReg(LoReg, LoRegKillFlag);
883}
884
886 return new HexagonCopyToCombine();
887}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
static cl::opt< bool > IsConst64Disabled("disable-const64", cl::Hidden, cl::desc("Disable generation of const64"))
static bool isEvenReg(unsigned Reg)
static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg, unsigned DestReg, const TargetRegisterInfo *TRI)
Returns true if it is unsafe to move a copy instruction from UseReg to DestReg over the instruction M...
static cl::opt< bool > IsCombinesDisabled("disable-merge-into-combines", cl::Hidden, cl::desc("Disable merging into combines"))
const HexagonInstrInfo bool ShouldCombineAggressively
static bool areCombinableOperations(const TargetRegisterInfo *TRI, MachineInstr &HighRegInst, MachineInstr &LowRegInst, bool AllowC64)
areCombinableOperations - Returns true if the two instruction can be merge into a combine (ignoring r...
static cl::opt< unsigned > MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", cl::Hidden, cl::init(4), cl::desc("Maximum distance between a tfr feeding a store we " "consider the store still to be newifiable"))
static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled)
static bool isGreaterThanNBitTFRI(const MachineInstr &I)
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:479
#define LLVM_DEBUG(...)
Definition Debug.h:119
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition Function.h:708
bool mayBeNewStore(const MachineInstr &MI) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
constexpr bool isValid() const
Definition MCRegister.h:84
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addBlockAddress(const BlockAddress *BA, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
int64_t getOffset() const
Return the offset from the symbol in this operand.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition Register.h:60
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:188
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
RegState
Flags to represent properties of register accesses.
constexpr RegState getKillRegState(bool B)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionPass * createHexagonCopyToCombine()
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58