LLVM 20.0.0git
XtensaInstrInfo.cpp
Go to the documentation of this file.
1//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// This file contains the Xtensa implementation of the TargetInstrInfo class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "XtensaInstrInfo.h"
18#include "XtensaTargetMachine.h"
24
25#define GET_INSTRINFO_CTOR_DTOR
26#include "XtensaGenInstrInfo.inc"
27
28using namespace llvm;
29
30static const MachineInstrBuilder &
32 MachineInstr *MI = MIB;
33 MachineFunction &MF = *MI->getParent()->getParent();
34 MachineFrameInfo &MFFrame = MF.getFrameInfo();
35 const MCInstrDesc &MCID = MI->getDesc();
37 if (MCID.mayLoad())
39 if (MCID.mayStore())
41 int64_t Offset = 0;
42 Align Alignment = MFFrame.getObjectAlign(FI);
43
46 Flags, MFFrame.getObjectSize(FI), Alignment);
47 return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
48}
49
51 : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
52 RI(STI), STI(STI) {}
53
55 int &FrameIndex) const {
56 if (MI.getOpcode() == Xtensa::L32I) {
57 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
58 MI.getOperand(2).getImm() == 0) {
59 FrameIndex = MI.getOperand(1).getIndex();
60 return MI.getOperand(0).getReg();
61 }
62 }
63 return Register();
64}
65
67 int &FrameIndex) const {
68 if (MI.getOpcode() == Xtensa::S32I) {
69 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
70 MI.getOperand(2).getImm() == 0) {
71 FrameIndex = MI.getOperand(1).getIndex();
72 return MI.getOperand(0).getReg();
73 }
74 }
75 return Register();
76}
77
78/// Adjust SP by Amount bytes.
79void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
82 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
83
84 if (Amount == 0)
85 return;
86
88 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
89
90 // create virtual reg to store immediate
91 unsigned Reg = RegInfo.createVirtualRegister(RC);
92
93 if (isInt<8>(Amount)) { // addi sp, sp, amount
94 BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
95 } else { // Expand immediate that doesn't fit in 8-bit.
96 unsigned Reg1;
97 loadImmediate(MBB, I, &Reg1, Amount);
98 BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
99 .addReg(SP)
100 .addReg(Reg1, RegState::Kill);
101 }
102
103 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
105 .addReg(Reg, RegState::Kill);
106}
107
110 const DebugLoc &DL, MCRegister DestReg,
111 MCRegister SrcReg, bool KillSrc,
112 bool RenamableDest, bool RenamableSrc) const {
113 // The MOV instruction is not present in core ISA,
114 // so use OR instruction.
115 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
116 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
117 .addReg(SrcReg, getKillRegState(KillSrc))
118 .addReg(SrcReg, getKillRegState(KillSrc));
119 else
120 report_fatal_error("Impossible reg-to-reg copy");
121}
122
125 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
126 const TargetRegisterInfo *TRI, Register VReg) const {
127 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
128 unsigned LoadOpcode, StoreOpcode;
129 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
130 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
131 .addReg(SrcReg, getKillRegState(isKill));
132 addFrameReference(MIB, FrameIdx);
133}
134
137 Register DestReg, int FrameIdx,
138 const TargetRegisterClass *RC,
139 const TargetRegisterInfo *TRI,
140 Register VReg) const {
141 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
142 unsigned LoadOpcode, StoreOpcode;
143 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
144 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
145}
146
148 unsigned &LoadOpcode,
149 unsigned &StoreOpcode,
150 int64_t offset) const {
151 assert((RC == &Xtensa::ARRegClass) &&
152 "Unsupported regclass to load or store");
153
154 LoadOpcode = Xtensa::L32I;
155 StoreOpcode = Xtensa::S32I;
156}
157
160 unsigned *Reg, int64_t Value) const {
161 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
163 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
164
165 // create virtual reg to store immediate
166 *Reg = RegInfo.createVirtualRegister(RC);
167 if (Value >= -2048 && Value <= 2047) {
168 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
169 } else if (Value >= -32768 && Value <= 32767) {
170 int Low = Value & 0xFF;
171 int High = Value & ~0xFF;
172
173 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
174 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
175 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
176 // 32 bit arbitrary constant
178 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
179 const Constant *CVal = ConstantInt::get(
181 false);
182 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
183 // MCSymbol MSym
184 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
185 } else {
186 // use L32R to let assembler load immediate best
187 // TODO replace to L32R
188 report_fatal_error("Unsupported load immediate value");
189 }
190}
191
193 switch (MI.getOpcode()) {
194 case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
195 const MachineFunction *MF = MI.getParent()->getParent();
196 const char *AsmStr = MI.getOperand(0).getSymbolName();
197 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
198 }
199 default:
200 return MI.getDesc().getSize();
201 }
202}
203
206 assert(Cond.size() <= 4 && "Invalid branch condition!");
207
208 switch (Cond[0].getImm()) {
209 case Xtensa::BEQ:
210 Cond[0].setImm(Xtensa::BNE);
211 return false;
212 case Xtensa::BNE:
213 Cond[0].setImm(Xtensa::BEQ);
214 return false;
215 case Xtensa::BLT:
216 Cond[0].setImm(Xtensa::BGE);
217 return false;
218 case Xtensa::BGE:
219 Cond[0].setImm(Xtensa::BLT);
220 return false;
221 case Xtensa::BLTU:
222 Cond[0].setImm(Xtensa::BGEU);
223 return false;
224 case Xtensa::BGEU:
225 Cond[0].setImm(Xtensa::BLTU);
226 return false;
227 case Xtensa::BEQI:
228 Cond[0].setImm(Xtensa::BNEI);
229 return false;
230 case Xtensa::BNEI:
231 Cond[0].setImm(Xtensa::BEQI);
232 return false;
233 case Xtensa::BGEI:
234 Cond[0].setImm(Xtensa::BLTI);
235 return false;
236 case Xtensa::BLTI:
237 Cond[0].setImm(Xtensa::BGEI);
238 return false;
239 case Xtensa::BGEUI:
240 Cond[0].setImm(Xtensa::BLTUI);
241 return false;
242 case Xtensa::BLTUI:
243 Cond[0].setImm(Xtensa::BGEUI);
244 return false;
245 case Xtensa::BEQZ:
246 Cond[0].setImm(Xtensa::BNEZ);
247 return false;
248 case Xtensa::BNEZ:
249 Cond[0].setImm(Xtensa::BEQZ);
250 return false;
251 case Xtensa::BLTZ:
252 Cond[0].setImm(Xtensa::BGEZ);
253 return false;
254 case Xtensa::BGEZ:
255 Cond[0].setImm(Xtensa::BLTZ);
256 return false;
257 default:
258 report_fatal_error("Invalid branch condition!");
259 }
260}
261
264 unsigned OpCode = MI.getOpcode();
265 switch (OpCode) {
266 case Xtensa::BR_JT:
267 case Xtensa::JX:
268 return nullptr;
269 case Xtensa::J:
270 return MI.getOperand(0).getMBB();
271 case Xtensa::BEQ:
272 case Xtensa::BNE:
273 case Xtensa::BLT:
274 case Xtensa::BLTU:
275 case Xtensa::BGE:
276 case Xtensa::BGEU:
277 return MI.getOperand(2).getMBB();
278 case Xtensa::BEQI:
279 case Xtensa::BNEI:
280 case Xtensa::BLTI:
281 case Xtensa::BLTUI:
282 case Xtensa::BGEI:
283 case Xtensa::BGEUI:
284 return MI.getOperand(2).getMBB();
285 case Xtensa::BEQZ:
286 case Xtensa::BNEZ:
287 case Xtensa::BLTZ:
288 case Xtensa::BGEZ:
289 return MI.getOperand(1).getMBB();
290 default:
291 llvm_unreachable("Unknown branch opcode");
292 }
293}
294
296 int64_t BrOffset) const {
297 switch (BranchOp) {
298 case Xtensa::J:
299 BrOffset -= 4;
300 return isIntN(18, BrOffset);
301 case Xtensa::JX:
302 return true;
303 case Xtensa::BR_JT:
304 return true;
305 case Xtensa::BEQ:
306 case Xtensa::BNE:
307 case Xtensa::BLT:
308 case Xtensa::BLTU:
309 case Xtensa::BGE:
310 case Xtensa::BGEU:
311 case Xtensa::BEQI:
312 case Xtensa::BNEI:
313 case Xtensa::BLTI:
314 case Xtensa::BLTUI:
315 case Xtensa::BGEI:
316 case Xtensa::BGEUI:
317 BrOffset -= 4;
318 return isIntN(8, BrOffset);
319 case Xtensa::BEQZ:
320 case Xtensa::BNEZ:
321 case Xtensa::BLTZ:
322 case Xtensa::BGEZ:
323 BrOffset -= 4;
324 return isIntN(12, BrOffset);
325 default:
326 llvm_unreachable("Unknown branch opcode");
327 }
328}
329
332 MachineBasicBlock *&FBB,
334 bool AllowModify = false) const {
335 // Most of the code and comments here are boilerplate.
336
337 // Start from the bottom of the block and work up, examining the
338 // terminator instructions.
340 while (I != MBB.begin()) {
341 --I;
342 if (I->isDebugValue())
343 continue;
344
345 // Working from the bottom, when we see a non-terminator instruction, we're
346 // done.
347 if (!isUnpredicatedTerminator(*I))
348 break;
349
350 // A terminator that isn't a branch can't easily be handled by this
351 // analysis.
354 const MachineOperand *ThisTarget;
355 if (!isBranch(I, ThisCond, ThisTarget))
356 return true;
357
358 // Can't handle indirect branches.
359 if (!ThisTarget->isMBB())
360 return true;
361
362 if (ThisCond[0].getImm() == Xtensa::J) {
363 // Handle unconditional branches.
364 if (!AllowModify) {
365 TBB = ThisTarget->getMBB();
366 continue;
367 }
368
369 // If the block has any instructions after a JMP, delete them.
370 while (std::next(I) != MBB.end())
371 std::next(I)->eraseFromParent();
372
373 Cond.clear();
374 FBB = 0;
375
376 // TBB is used to indicate the unconditinal destination.
377 TBB = ThisTarget->getMBB();
378 continue;
379 }
380
381 // Working from the bottom, handle the first conditional branch.
382 if (Cond.empty()) {
383 // FIXME: add X86-style branch swap
384 FBB = TBB;
385 TBB = ThisTarget->getMBB();
386 Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
387
388 // push remaining operands
389 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
390 Cond.push_back(I->getOperand(i));
391
392 continue;
393 }
394
395 // Handle subsequent conditional branches.
396 assert(Cond.size() <= 4);
397 assert(TBB);
398
399 // Only handle the case where all conditional branches branch to the same
400 // destination.
401 if (TBB != ThisTarget->getMBB())
402 return true;
403
404 // If the conditions are the same, we can leave them alone.
405 unsigned OldCond = Cond[0].getImm();
406 if (OldCond == ThisCond[0].getImm())
407 continue;
408 }
409
410 return false;
411}
412
414 int *BytesRemoved) const {
415 // Most of the code and comments here are boilerplate.
417 unsigned Count = 0;
418 if (BytesRemoved)
419 *BytesRemoved = 0;
420
421 while (I != MBB.begin()) {
422 --I;
424 Cond.push_back(MachineOperand::CreateImm(0));
425 const MachineOperand *Target;
426 if (!isBranch(I, Cond, Target))
427 break;
428 if (!Target->isMBB())
429 break;
430 // Remove the branch.
431 if (BytesRemoved)
432 *BytesRemoved += getInstSizeInBytes(*I);
433 I->eraseFromParent();
434 I = MBB.end();
435 ++Count;
436 }
437 return Count;
438}
439
442 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
443 unsigned Count = 0;
444 if (BytesAdded)
445 *BytesAdded = 0;
446 if (FBB) {
447 // Need to build two branches then
448 // one to branch to TBB on Cond
449 // and a second one immediately after to unconditionally jump to FBB
450 Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
451 auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
452 Count++;
453 if (BytesAdded)
454 *BytesAdded += getInstSizeInBytes(MI);
455 return Count;
456 }
457 // This function inserts the branch at the end of the MBB
458 Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
459 return Count;
460}
461
463 MachineBasicBlock &DestBB,
464 MachineBasicBlock &RestoreBB,
465 const DebugLoc &DL, int64_t BrOffset,
466 RegScavenger *RS) const {
467 assert(RS && "RegScavenger required for long branching");
468 assert(MBB.empty() &&
469 "new block should be inserted for expanding unconditional branch");
470 assert(MBB.pred_size() == 1);
471
475 auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
476 MachineBasicBlock *JumpToMBB = &DestBB;
477
478 if (!isInt<32>(BrOffset))
480 "Branch offsets outside of the signed 32-bit range not supported");
481
482 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
483 auto II = MBB.end();
484
485 // Create l32r without last operand. We will add this operand later when
486 // JumpToMMB will be calculated and placed to the ConstantPool.
487 MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
488 BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
489
491 Register ScavRegister =
492 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
493 /*RestoreAfter=*/false, /*SpAdj=*/0,
494 /*AllowSpill=*/false);
495 if (ScavRegister != Xtensa::NoRegister)
496 RS->setRegUsed(ScavRegister);
497 else {
498 // The case when there is no scavenged register needs special handling.
499 // Pick A8 because it doesn't make a difference
500 ScavRegister = Xtensa::A12;
501
502 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
503 if (FrameIndex == -1)
505 "Unable to properly handle scavenged register for indirect jump, "
506 "function code size is significantly larger than estimated");
507
508 storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
509 &Xtensa::ARRegClass, &RI, Register());
510 RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
511 /*SpAdj=*/0, /*FIOperandNum=*/1);
512
513 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
514 &Xtensa::ARRegClass, &RI, Register());
515 RI.eliminateFrameIndex(RestoreBB.back(),
516 /*SpAdj=*/0, /*FIOperandNum=*/1);
517 JumpToMBB = &RestoreBB;
518 }
519
521 MF->getFunction().getContext(), JumpToMBB, 0);
522 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
524
525 MRI.replaceRegWith(ScratchReg, ScavRegister);
526 MRI.clearVirtRegs();
527}
528
530 MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
531 ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
532 assert(Cond.size() <= 4 &&
533 "Xtensa branch conditions have less than four components!");
534
535 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
536 // Unconditional branch
537 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
538 if (BytesAdded && MI)
539 *BytesAdded += getInstSizeInBytes(*MI);
540 return 1;
541 }
542
543 unsigned Count = 0;
544 unsigned BR_C = Cond[0].getImm();
545 MachineInstr *MI = nullptr;
546 switch (BR_C) {
547 case Xtensa::BEQ:
548 case Xtensa::BNE:
549 case Xtensa::BLT:
550 case Xtensa::BLTU:
551 case Xtensa::BGE:
552 case Xtensa::BGEU:
553 MI = BuildMI(MBB, I, DL, get(BR_C))
554 .addImm(offset)
555 .addReg(Cond[1].getReg())
556 .addReg(Cond[2].getReg());
557 break;
558 case Xtensa::BEQI:
559 case Xtensa::BNEI:
560 case Xtensa::BLTI:
561 case Xtensa::BLTUI:
562 case Xtensa::BGEI:
563 case Xtensa::BGEUI:
564 MI = BuildMI(MBB, I, DL, get(BR_C))
565 .addImm(offset)
566 .addReg(Cond[1].getReg())
567 .addImm(Cond[2].getImm());
568 break;
569 case Xtensa::BEQZ:
570 case Xtensa::BNEZ:
571 case Xtensa::BLTZ:
572 case Xtensa::BGEZ:
573 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
574 break;
575 default:
576 llvm_unreachable("Invalid branch type!");
577 }
578 if (BytesAdded && MI)
579 *BytesAdded += getInstSizeInBytes(*MI);
580 ++Count;
581 return Count;
582}
583
588 const DebugLoc &DL,
589 int *BytesAdded) const {
590 // Shouldn't be a fall through.
591 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
592 assert(Cond.size() <= 4 &&
593 "Xtensa branch conditions have less than four components!");
594
595 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
596 // Unconditional branch
597 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
598 if (BytesAdded && MI)
599 *BytesAdded += getInstSizeInBytes(*MI);
600 return 1;
601 }
602
603 unsigned Count = 0;
604 unsigned BR_C = Cond[0].getImm();
605 MachineInstr *MI = nullptr;
606 switch (BR_C) {
607 case Xtensa::BEQ:
608 case Xtensa::BNE:
609 case Xtensa::BLT:
610 case Xtensa::BLTU:
611 case Xtensa::BGE:
612 case Xtensa::BGEU:
613 MI = BuildMI(MBB, I, DL, get(BR_C))
614 .addReg(Cond[1].getReg())
615 .addReg(Cond[2].getReg())
616 .addMBB(TBB);
617 break;
618 case Xtensa::BEQI:
619 case Xtensa::BNEI:
620 case Xtensa::BLTI:
621 case Xtensa::BLTUI:
622 case Xtensa::BGEI:
623 case Xtensa::BGEUI:
624 MI = BuildMI(MBB, I, DL, get(BR_C))
625 .addReg(Cond[1].getReg())
626 .addImm(Cond[2].getImm())
627 .addMBB(TBB);
628 break;
629 case Xtensa::BEQZ:
630 case Xtensa::BNEZ:
631 case Xtensa::BLTZ:
632 case Xtensa::BGEZ:
633 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
634 break;
635 default:
636 report_fatal_error("Invalid branch type!");
637 }
638 if (BytesAdded && MI)
639 *BytesAdded += getInstSizeInBytes(*MI);
640 ++Count;
641 return Count;
642}
643
646 const MachineOperand *&Target) const {
647 unsigned OpCode = MI->getOpcode();
648 switch (OpCode) {
649 case Xtensa::J:
650 case Xtensa::JX:
651 case Xtensa::BR_JT:
652 Cond[0].setImm(OpCode);
653 Target = &MI->getOperand(0);
654 return true;
655 case Xtensa::BEQ:
656 case Xtensa::BNE:
657 case Xtensa::BLT:
658 case Xtensa::BLTU:
659 case Xtensa::BGE:
660 case Xtensa::BGEU:
661 Cond[0].setImm(OpCode);
662 Target = &MI->getOperand(2);
663 return true;
664
665 case Xtensa::BEQI:
666 case Xtensa::BNEI:
667 case Xtensa::BLTI:
668 case Xtensa::BLTUI:
669 case Xtensa::BGEI:
670 case Xtensa::BGEUI:
671 Cond[0].setImm(OpCode);
672 Target = &MI->getOperand(2);
673 return true;
674
675 case Xtensa::BEQZ:
676 case Xtensa::BNEZ:
677 case Xtensa::BLTZ:
678 case Xtensa::BGEZ:
679 Cond[0].setImm(OpCode);
680 Target = &MI->getOperand(1);
681 return true;
682
683 default:
684 assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
685 return false;
686 }
687}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t High
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This is an important base class in LLVM.
Definition: Constant.h:42
A debug info location.
Definition: DebugLoc.h:33
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:369
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:444
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:438
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
unsigned pred_size() const
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
static XtensaConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *M, unsigned ID)
XtensaConstantPoolValue - Xtensa specific constantpool value.
bool isBranch(const MachineBasicBlock::iterator &MI, SmallVectorImpl< MachineOperand > &Cond, const MachineOperand *&Target) const
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned *Reg, int64_t Value) const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset=0, RegScavenger *RS=nullptr) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
unsigned insertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I, int64_t offset, ArrayRef< MachineOperand > Cond, DebugLoc DL, int *BytesAdded) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
unsigned insertBranchAtInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded) const
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
XtensaInstrInfo(const XtensaSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode, int64_t offset) const
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
self_iterator getIterator()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:260
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.