LLVM 23.0.0git
X86RegisterInfo.cpp
Go to the documentation of this file.
1//===-- X86RegisterInfo.cpp - X86 Register Information --------------------===//
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//
9// This file contains the X86 implementation of the TargetRegisterInfo class.
10// This file is responsible for the frame pointer elimination optimization
11// on X86.
12//
13//===----------------------------------------------------------------------===//
14
15#include "X86RegisterInfo.h"
16#include "X86FrameLowering.h"
18#include "X86Subtarget.h"
19#include "llvm/ADT/BitVector.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallSet.h"
30#include "llvm/IR/Function.h"
31#include "llvm/IR/Type.h"
32#include "llvm/MC/MCContext.h"
37
38using namespace llvm;
39
40#define GET_REGINFO_TARGET_DESC
41#include "X86GenRegisterInfo.inc"
42
43static cl::opt<bool>
44EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true),
45 cl::desc("Enable use of a base pointer for complex stack frames"));
46
47static cl::opt<bool>
48 DisableRegAllocNDDHints("x86-disable-regalloc-hints-for-ndd", cl::Hidden,
49 cl::init(false),
50 cl::desc("Disable two address hints for register "
51 "allocation"));
52
54 "x86-setjmp-csr-warning-threshold", cl::Hidden, cl::init(50),
55 cl::desc("Basic block count threshold for emitting a warning about "
56 "callee-saved registers reserved due to setjmp"));
57
59
61 : X86GenRegisterInfo((TT.isX86_64() ? X86::RIP : X86::EIP),
62 X86_MC::getDwarfRegFlavour(TT, false),
63 X86_MC::getDwarfRegFlavour(TT, true),
64 (TT.isX86_64() ? X86::RIP : X86::EIP)) {
66
67 // Cache some information.
68 Is64Bit = TT.isX86_64();
69 IsTarget64BitLP64 = Is64Bit && !TT.isX32();
70 IsWin64 = Is64Bit && TT.isOSWindows();
71 IsUEFI64 = Is64Bit && TT.isUEFI();
72
73 // Use a callee-saved register as the base pointer. These registers must
74 // not conflict with any ABI requirements. For example, in 32-bit mode PIC
75 // requires GOT in the EBX register before function calls via PLT GOT pointer.
76 if (Is64Bit) {
77 SlotSize = 8;
78 // This matches the simplified 32-bit pointer code in the data layout
79 // computation.
80 // FIXME: Should use the data layout?
81 bool Use64BitReg = !TT.isX32();
82 StackPtr = Use64BitReg ? X86::RSP : X86::ESP;
83 FramePtr = Use64BitReg ? X86::RBP : X86::EBP;
84 BasePtr = Use64BitReg ? X86::RBX : X86::EBX;
85 } else {
86 SlotSize = 4;
87 StackPtr = X86::ESP;
88 FramePtr = X86::EBP;
89 BasePtr = X86::ESI;
90 }
91}
92
95 unsigned Idx) const {
96 // The sub_8bit sub-register index is more constrained in 32-bit mode.
97 // It behaves just like the sub_8bit_hi index.
98 if (!Is64Bit && Idx == X86::sub_8bit)
99 Idx = X86::sub_8bit_hi;
100
101 // Forward to TableGen's default version.
102 return X86GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
103}
104
107 const TargetRegisterClass *B,
108 unsigned SubIdx) const {
109 // The sub_8bit sub-register index is more constrained in 32-bit mode.
110 if (!Is64Bit && SubIdx == X86::sub_8bit) {
111 A = X86GenRegisterInfo::getSubClassWithSubReg(A, X86::sub_8bit_hi);
112 if (!A)
113 return nullptr;
114 }
115 return X86GenRegisterInfo::getMatchingSuperRegClass(A, B, SubIdx);
116}
117
120 const MachineFunction &MF) const {
121 // Don't allow super-classes of GR8_NOREX. This class is only used after
122 // extracting sub_8bit_hi sub-registers. The H sub-registers cannot be copied
123 // to the full GR8 register class in 64-bit mode, so we cannot allow the
124 // reigster class inflation.
125 //
126 // The GR8_NOREX class is always used in a way that won't be constrained to a
127 // sub-class, so sub-classes like GR8_ABCD_L are allowed to expand to the
128 // full GR8 class.
129 if (RC == &X86::GR8_NOREXRegClass)
130 return RC;
131
132 // Keep using non-rex2 register class when APX feature (EGPR/NDD/NF) is not
133 // enabled for relocation.
135 return RC;
136
137 const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
138
139 const TargetRegisterClass *Super = RC;
140 auto I = RC->superclasses().begin();
141 auto E = RC->superclasses().end();
142 do {
143 switch (Super->getID()) {
144 case X86::FR32RegClassID:
145 case X86::FR64RegClassID:
146 // If AVX-512 isn't supported we should only inflate to these classes.
147 if (!Subtarget.hasAVX512() &&
148 getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
149 return Super;
150 break;
151 case X86::VR128RegClassID:
152 case X86::VR256RegClassID:
153 // If VLX isn't supported we should only inflate to these classes.
154 if (!Subtarget.hasVLX() &&
155 getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
156 return Super;
157 break;
158 case X86::VR128XRegClassID:
159 case X86::VR256XRegClassID:
160 // If VLX isn't support we shouldn't inflate to these classes.
161 if (Subtarget.hasVLX() &&
162 getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
163 return Super;
164 break;
165 case X86::FR32XRegClassID:
166 case X86::FR64XRegClassID:
167 // If AVX-512 isn't support we shouldn't inflate to these classes.
168 if (Subtarget.hasAVX512() &&
169 getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
170 return Super;
171 break;
172 case X86::GR8RegClassID:
173 case X86::GR16RegClassID:
174 case X86::GR32RegClassID:
175 case X86::GR64RegClassID:
176 case X86::GR8_NOREX2RegClassID:
177 case X86::GR16_NOREX2RegClassID:
178 case X86::GR32_NOREX2RegClassID:
179 case X86::GR64_NOREX2RegClassID:
180 case X86::RFP32RegClassID:
181 case X86::RFP64RegClassID:
182 case X86::RFP80RegClassID:
183 case X86::VR512_0_15RegClassID:
184 case X86::VR512RegClassID:
185 // Don't return a super-class that would shrink the spill size.
186 // That can happen with the vector and float classes.
187 if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
188 return Super;
189 }
190 if (I != E) {
191 Super = getRegClass(*I);
192 ++I;
193 } else {
194 Super = nullptr;
195 }
196 } while (Super);
197 return RC;
198}
199
202 assert(Kind == 0 && "this should only be used for default cases");
203 if (IsTarget64BitLP64)
204 return &X86::GR64RegClass;
205 // If the target is 64bit but we have been told to use 32bit addresses,
206 // we can still use 64-bit register as long as we know the high bits
207 // are zeros.
208 // Reflect that in the returned register class.
209 return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
210}
211
214 if (RC == &X86::CCRRegClass) {
215 if (Is64Bit)
216 return &X86::GR64RegClass;
217 else
218 return &X86::GR32RegClass;
219 }
220 return RC;
221}
222
223unsigned
225 MachineFunction &MF) const {
226 const X86FrameLowering *TFI = getFrameLowering(MF);
227
228 unsigned FPDiff = TFI->hasFP(MF) ? 1 : 0;
229 switch (RC->getID()) {
230 default:
231 return 0;
232 case X86::GR32RegClassID:
233 return 4 - FPDiff;
234 case X86::GR64RegClassID:
235 return 12 - FPDiff;
236 case X86::VR128RegClassID:
237 return Is64Bit ? 10 : 4;
238 case X86::VR64RegClassID:
239 return 4;
240 }
241}
242
243const MCPhysReg *
245 assert(MF && "MachineFunction required");
246
247 const X86Subtarget &Subtarget = MF->getSubtarget<X86Subtarget>();
248 const Function &F = MF->getFunction();
249 bool HasSSE = Subtarget.hasSSE1();
250 bool HasAVX = Subtarget.hasAVX();
251 bool HasAVX512 = Subtarget.hasAVX512();
252 bool HasEGPR = Subtarget.hasEGPR();
253 bool CallsEHReturn = MF->callsEHReturn();
254
255 CallingConv::ID CC = F.getCallingConv();
256
257 // If attribute NoCallerSavedRegisters exists then we set X86_INTR calling
258 // convention because it has the CSR list.
259 if (MF->getFunction().hasFnAttribute("no_caller_saved_registers"))
261
262 // If atribute specified, override the CSRs normally specified by the
263 // calling convention and use the empty set instead.
264 if (MF->getFunction().hasFnAttribute("no_callee_saved_registers"))
265 return CSR_NoRegs_SaveList;
266
267 switch (CC) {
268 case CallingConv::GHC:
270 return CSR_NoRegs_SaveList;
272 if (HasAVX)
273 return CSR_64_AllRegs_AVX_SaveList;
274 return CSR_64_AllRegs_SaveList;
276 if (IsWin64)
277 return HasEGPR ? CSR_Win64_APX_RT_MostRegs_SaveList
278 : CSR_Win64_RT_MostRegs_SaveList;
279 return CSR_64_RT_MostRegs_SaveList;
281 if (HasAVX)
282 return CSR_64_RT_AllRegs_AVX_SaveList;
283 return CSR_64_RT_AllRegs_SaveList;
285 return CSR_64_NoneRegs_SaveList;
287 if (Is64Bit)
288 return MF->getInfo<X86MachineFunctionInfo>()->isSplitCSR() ?
289 CSR_64_CXX_TLS_Darwin_PE_SaveList : CSR_64_TLS_Darwin_SaveList;
290 break;
292 if (HasAVX512 && IsWin64)
293 return HasEGPR ? CSR_Win64_APX_Intel_OCL_BI_AVX512_SaveList
294 : CSR_Win64_Intel_OCL_BI_AVX512_SaveList;
295 if (HasAVX512 && Is64Bit)
296 return CSR_64_Intel_OCL_BI_AVX512_SaveList;
297 if (HasAVX && IsWin64)
298 return HasEGPR ? CSR_Win64_APX_Intel_OCL_BI_AVX_SaveList
299 : CSR_Win64_Intel_OCL_BI_AVX_SaveList;
300 if (HasAVX && Is64Bit)
301 return CSR_64_Intel_OCL_BI_AVX_SaveList;
302 if (!HasAVX && !IsWin64 && Is64Bit)
303 return CSR_64_Intel_OCL_BI_SaveList;
304 break;
305 }
307 if (Is64Bit) {
308 if (IsWin64) {
309 if (HasSSE)
310 return HasEGPR ? CSR_Win64_APX_RegCall_SaveList
311 : CSR_Win64_RegCall_SaveList;
312 return CSR_Win64_RegCall_NoSSE_SaveList;
313 }
314 return HasSSE ? CSR_SysV64_RegCall_SaveList
315 : CSR_SysV64_RegCall_NoSSE_SaveList;
316 }
317 return HasSSE ? CSR_32_RegCall_SaveList : CSR_32_RegCall_NoSSE_SaveList;
319 assert(!Is64Bit && "CFGuard check mechanism only used on 32-bit X86");
320 return HasSSE ? CSR_Win32_CFGuard_Check_SaveList
321 : CSR_Win32_CFGuard_Check_NoSSE_SaveList;
323 if (Is64Bit)
324 return CSR_64_MostRegs_SaveList;
325 break;
327 if (HasSSE)
328 return HasEGPR ? CSR_Win64_APX_SaveList : CSR_Win64_SaveList;
329 return CSR_Win64_NoSSE_SaveList;
331 if (!Is64Bit)
332 return CSR_32_SaveList;
333 if (IsWin64)
334 return HasEGPR ? CSR_Win64_APX_SwiftTail_SaveList
335 : CSR_Win64_SwiftTail_SaveList;
336 return CSR_64_SwiftTail_SaveList;
338 if (CallsEHReturn)
339 return CSR_64EHRet_SaveList;
340 return CSR_64_SaveList;
342 if (Is64Bit) {
343 if (HasAVX512)
344 return CSR_64_AllRegs_AVX512_SaveList;
345 if (HasAVX)
346 return CSR_64_AllRegs_AVX_SaveList;
347 if (HasSSE)
348 return CSR_64_AllRegs_SaveList;
349 return CSR_64_AllRegs_NoSSE_SaveList;
350 }
351 if (HasAVX512)
352 return CSR_32_AllRegs_AVX512_SaveList;
353 if (HasAVX)
354 return CSR_32_AllRegs_AVX_SaveList;
355 if (HasSSE)
356 return CSR_32_AllRegs_SSE_SaveList;
357 return CSR_32_AllRegs_SaveList;
358 default:
359 break;
360 }
361
362 if (Is64Bit) {
363 bool IsSwiftCC = Subtarget.getTargetLowering()->supportSwiftError() &&
364 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError);
365 if (IsSwiftCC) {
366 if (IsWin64)
367 return HasEGPR ? CSR_Win64_APX_SwiftError_SaveList
368 : CSR_Win64_SwiftError_SaveList;
369 return CSR_64_SwiftError_SaveList;
370 }
371
372 if (IsWin64 || IsUEFI64) {
373 if (HasSSE)
374 return HasEGPR ? CSR_Win64_APX_SaveList : CSR_Win64_SaveList;
375 return CSR_Win64_NoSSE_SaveList;
376 }
377 if (CallsEHReturn)
378 return CSR_64EHRet_SaveList;
379 return CSR_64_SaveList;
380 }
381
382 return CallsEHReturn ? CSR_32EHRet_SaveList : CSR_32_SaveList;
383}
384
385const MCPhysReg *
387 return Is64Bit ? CSR_IPRA_64_SaveList : CSR_IPRA_32_SaveList;
388}
389
391 const MachineFunction *MF) const {
392 assert(MF && "Invalid MachineFunction pointer.");
395 return CSR_64_CXX_TLS_Darwin_ViaCopy_SaveList;
396 return nullptr;
397}
398
399const uint32_t *
401 CallingConv::ID CC) const {
402 const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
403 bool HasSSE = Subtarget.hasSSE1();
404 bool HasAVX = Subtarget.hasAVX();
405 bool HasAVX512 = Subtarget.hasAVX512();
406 bool HasEGPR = Subtarget.hasEGPR();
407
408 switch (CC) {
409 case CallingConv::GHC:
411 return CSR_NoRegs_RegMask;
413 if (HasAVX)
414 return CSR_64_AllRegs_AVX_RegMask;
415 return CSR_64_AllRegs_RegMask;
417 if (IsWin64)
418 return HasEGPR ? CSR_Win64_APX_RT_MostRegs_RegMask
419 : CSR_Win64_RT_MostRegs_RegMask;
420 return CSR_64_RT_MostRegs_RegMask;
422 if (HasAVX)
423 return CSR_64_RT_AllRegs_AVX_RegMask;
424 return CSR_64_RT_AllRegs_RegMask;
426 return CSR_64_NoneRegs_RegMask;
428 if (Is64Bit)
429 return CSR_64_TLS_Darwin_RegMask;
430 break;
432 if (HasAVX512 && IsWin64)
433 return HasEGPR ? CSR_Win64_APX_Intel_OCL_BI_AVX512_RegMask
434 : CSR_Win64_Intel_OCL_BI_AVX512_RegMask;
435 if (HasAVX512 && Is64Bit)
436 return CSR_64_Intel_OCL_BI_AVX512_RegMask;
437 if (HasAVX && IsWin64)
438 return HasEGPR ? CSR_Win64_APX_Intel_OCL_BI_AVX_RegMask
439 : CSR_Win64_Intel_OCL_BI_AVX_RegMask;
440 if (HasAVX && Is64Bit)
441 return CSR_64_Intel_OCL_BI_AVX_RegMask;
442 if (!HasAVX && !IsWin64 && Is64Bit)
443 return CSR_64_Intel_OCL_BI_RegMask;
444 break;
445 }
447 if (Is64Bit) {
448 if (IsWin64) {
449 if (HasSSE)
450 return HasEGPR ? CSR_Win64_APX_RegCall_RegMask
451 : CSR_Win64_RegCall_RegMask;
452 return CSR_Win64_RegCall_NoSSE_RegMask;
453 }
454 return HasSSE ? CSR_SysV64_RegCall_RegMask
455 : CSR_SysV64_RegCall_NoSSE_RegMask;
456 }
457 return HasSSE ? CSR_32_RegCall_RegMask : CSR_32_RegCall_NoSSE_RegMask;
459 if (Is64Bit) {
460 if (HasSSE)
461 return HasEGPR ? CSR_Win64_APX_CFGuard_Check_RegMask
462 : CSR_Win64_CFGuard_Check_RegMask;
463 return CSR_Win64_CFGuard_Check_NoSSE_RegMask;
464 }
465 return HasSSE ? CSR_Win32_CFGuard_Check_RegMask
466 : CSR_Win32_CFGuard_Check_NoSSE_RegMask;
468 if (Is64Bit)
469 return CSR_64_MostRegs_RegMask;
470 break;
472 return HasEGPR ? CSR_Win64_APX_RegMask : CSR_Win64_RegMask;
474 if (!Is64Bit)
475 return CSR_32_RegMask;
476 if (IsWin64)
477 return HasEGPR ? CSR_Win64_APX_SwiftTail_RegMask
478 : CSR_Win64_SwiftTail_RegMask;
479 return CSR_64_SwiftTail_RegMask;
481 return CSR_64_RegMask;
483 if (Is64Bit) {
484 if (HasAVX512)
485 return CSR_64_AllRegs_AVX512_RegMask;
486 if (HasAVX)
487 return CSR_64_AllRegs_AVX_RegMask;
488 if (HasSSE)
489 return CSR_64_AllRegs_RegMask;
490 return CSR_64_AllRegs_NoSSE_RegMask;
491 }
492 if (HasAVX512)
493 return CSR_32_AllRegs_AVX512_RegMask;
494 if (HasAVX)
495 return CSR_32_AllRegs_AVX_RegMask;
496 if (HasSSE)
497 return CSR_32_AllRegs_SSE_RegMask;
498 return CSR_32_AllRegs_RegMask;
499 default:
500 break;
501 }
502
503 // Unlike getCalleeSavedRegs(), we don't have MMI so we can't check
504 // callsEHReturn().
505 if (Is64Bit) {
506 const Function &F = MF.getFunction();
507 bool IsSwiftCC = Subtarget.getTargetLowering()->supportSwiftError() &&
508 F.getAttributes().hasAttrSomewhere(Attribute::SwiftError);
509 if (IsSwiftCC) {
510 if (IsWin64)
511 return HasEGPR ? CSR_Win64_APX_SwiftError_RegMask
512 : CSR_Win64_SwiftError_RegMask;
513 return CSR_64_SwiftError_RegMask;
514 }
515
516 if (IsWin64 || IsUEFI64)
517 return HasEGPR ? CSR_Win64_APX_RegMask : CSR_Win64_RegMask;
518 return CSR_64_RegMask;
519 }
520
521 return CSR_32_RegMask;
522}
523
524const uint32_t*
526 return CSR_NoRegs_RegMask;
527}
528
530 return CSR_64_TLS_Darwin_RegMask;
531}
532
534 BitVector Reserved(getNumRegs());
535 const X86FrameLowering *TFI = getFrameLowering(MF);
536
537 // Set the floating point control register as reserved.
538 Reserved.set(X86::FPCW);
539
540 // Set the floating point status register as reserved.
541 Reserved.set(X86::FPSW);
542
543 // Set the SIMD floating point control register as reserved.
544 Reserved.set(X86::MXCSR);
545
546 // Set the stack-pointer register and its aliases as reserved.
547 for (const MCPhysReg &SubReg : subregs_inclusive(X86::RSP))
548 Reserved.set(SubReg);
549
550 // Set the Shadow Stack Pointer as reserved.
551 Reserved.set(X86::SSP);
552
553 auto &ST = MF.getSubtarget<X86Subtarget>();
554 if (ST.hasUserReservedRegisters()) {
555 if (ST.is64Bit()) {
556 // Set r# as reserved register if user required.
557 for (unsigned Reg = X86::R8; Reg <= X86::R15; ++Reg)
558 if (ST.isRegisterReservedByUser(Reg))
559 for (const MCPhysReg &SubReg : subregs_inclusive(Reg))
560 Reserved.set(SubReg);
561 if (ST.hasEGPR())
562 for (unsigned Reg = X86::R16; Reg <= X86::R31; ++Reg)
563 if (ST.isRegisterReservedByUser(Reg))
564 for (const MCPhysReg &SubReg : subregs_inclusive(Reg))
565 Reserved.set(SubReg);
566 } else {
567 if (ST.isRegisterReservedByUser(X86::EDI))
568 for (const MCPhysReg &SubReg : sub_and_superregs_inclusive(X86::EDI))
569 Reserved.set(SubReg);
570 }
571 }
572
573 // Set the instruction pointer register and its aliases as reserved.
574 for (const MCPhysReg &SubReg : subregs_inclusive(X86::RIP))
575 Reserved.set(SubReg);
576
577 // Set the frame-pointer register and its aliases as reserved if needed.
578 if (TFI->hasFP(MF) || MF.getTarget().Options.FramePointerIsReserved(MF)) {
581 SMLoc(),
582 "Frame pointer clobbered by function invoke is not supported.");
583
584 for (const MCPhysReg &SubReg : subregs_inclusive(X86::RBP))
585 Reserved.set(SubReg);
586 }
587
588 // Set the base-pointer register and its aliases as reserved if needed.
589 if (hasBasePointer(MF)) {
592 "Stack realignment in presence of dynamic "
593 "allocas is not supported with "
594 "this calling convention.");
595
597 for (const MCPhysReg &SubReg : subregs_inclusive(BasePtr))
598 Reserved.set(SubReg);
599 }
600
601 // Mark the segment registers as reserved.
602 Reserved.set(X86::CS);
603 Reserved.set(X86::SS);
604 Reserved.set(X86::DS);
605 Reserved.set(X86::ES);
606 Reserved.set(X86::FS);
607 Reserved.set(X86::GS);
608
609 // Mark the floating point stack registers as reserved.
610 for (unsigned n = 0; n != 8; ++n)
611 Reserved.set(X86::ST0 + n);
612
613 // Reserve the registers that only exist in 64-bit mode.
614 if (!Is64Bit) {
615 // These 8-bit registers are part of the x86-64 extension even though their
616 // super-registers are old 32-bits.
617 Reserved.set(X86::SIL);
618 Reserved.set(X86::DIL);
619 Reserved.set(X86::BPL);
620 Reserved.set(X86::SPL);
621 Reserved.set(X86::SIH);
622 Reserved.set(X86::DIH);
623 Reserved.set(X86::BPH);
624 Reserved.set(X86::SPH);
625
626 for (unsigned n = 0; n != 8; ++n) {
627 // R8, R9, ...
628 for (MCRegAliasIterator AI(X86::R8 + n, this, true); AI.isValid(); ++AI)
629 Reserved.set(*AI);
630
631 // XMM8, XMM9, ...
632 for (MCRegAliasIterator AI(X86::XMM8 + n, this, true); AI.isValid(); ++AI)
633 Reserved.set(*AI);
634 }
635 }
636 if (!Is64Bit || !MF.getSubtarget<X86Subtarget>().hasAVX512()) {
637 for (unsigned n = 0; n != 16; ++n) {
638 for (MCRegAliasIterator AI(X86::XMM16 + n, this, true); AI.isValid();
639 ++AI)
640 Reserved.set(*AI);
641 }
642 }
643
644 // Reserve the extended general purpose registers.
645 if (!Is64Bit || !MF.getSubtarget<X86Subtarget>().hasEGPR())
646 Reserved.set(X86::R16, X86::R31WH + 1);
647
648 // Due to specifics of setjmp unwinding in Win64 APX ABI, the unwinder
649 // cannot restore R30/R31. Reserve them to prevent register allocation.
650 // https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention#setjmplongjmp
651 if (MF.exposesReturnsTwice() && ST.isTargetWin64()) {
652 unsigned NumReservedCSRs = 0;
653 for (unsigned Reg = X86::R16; Reg <= X86::R31; ++Reg)
654 if (isCalleeSavedPhysReg(Reg, MF)) {
655 ++NumReservedCSRs;
656 for (const MCPhysReg &SubReg : subregs_inclusive(Reg))
657 Reserved.set(SubReg);
658 }
659 if (NumReservedCSRs && MF.size() > SetjmpCSRWarningThreshold &&
662 SMLoc(), Twine(NumReservedCSRs) +
663 " callee-saved register(s) reserved due to setjmp in '" +
664 MF.getName() +
665 "'; this may impact performance in large functions");
666 }
667 }
668
670 for (MCRegAliasIterator AI(X86::R14, this, true); AI.isValid(); ++AI)
671 Reserved.set(*AI);
672 for (MCRegAliasIterator AI(X86::R15, this, true); AI.isValid(); ++AI)
673 Reserved.set(*AI);
674 }
675
676 // Reserve registers for LFI sandboxing.
677 if (MF.getSubtarget<X86Subtarget>().isLFI()) {
678 for (MCRegAliasIterator AI(X86::R11, this, true); AI.isValid(); ++AI)
679 Reserved.set(*AI);
680 for (MCRegAliasIterator AI(X86::R14, this, true); AI.isValid(); ++AI)
681 Reserved.set(*AI);
682 for (MCRegAliasIterator AI(X86::R15, this, true); AI.isValid(); ++AI)
683 Reserved.set(*AI);
684 }
685
686 assert(checkAllSuperRegsMarked(Reserved,
687 {X86::SIL, X86::DIL, X86::BPL, X86::SPL,
688 X86::SIH, X86::DIH, X86::BPH, X86::SPH}));
689 return Reserved;
690}
691
693 // All existing Intel CPUs that support AMX support AVX512 and all existing
694 // Intel CPUs that support APX support AMX. AVX512 implies AVX.
695 //
696 // We enumerate the registers in X86GenRegisterInfo.inc in this order:
697 //
698 // Registers before AVX512,
699 // AVX512 registers (X/YMM16-31, ZMM0-31, K registers)
700 // AMX registers (TMM)
701 // APX registers (R16-R31)
702 //
703 // and try to return the minimum number of registers supported by the target.
704 static_assert((X86::R15WH + 1 == X86::YMM0) && (X86::YMM15 + 1 == X86::K0) &&
705 (X86::K6_K7 + 1 == X86::TMMCFG) &&
706 (X86::TMM7 + 1 == X86::R16) &&
707 (X86::R31WH + 1 == X86::NUM_TARGET_REGS),
708 "Register number may be incorrect");
709
710 const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
711 if (ST.hasEGPR())
712 return X86::NUM_TARGET_REGS;
713 if (ST.hasAMXTILE())
714 return X86::TMM7 + 1;
715 if (ST.hasAVX512())
716 return X86::K6_K7 + 1;
717 if (ST.hasAVX())
718 return X86::YMM15 + 1;
719 return X86::R15WH + 1;
720}
721
723 MCRegister Reg) const {
724 const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
725 const TargetRegisterInfo &TRI = *ST.getRegisterInfo();
726 auto IsSubReg = [&](MCRegister RegA, MCRegister RegB) {
727 return TRI.isSuperOrSubRegisterEq(RegA, RegB);
728 };
729
730 if (!ST.is64Bit())
731 return llvm::any_of(
732 SmallVector<MCRegister>{X86::EAX, X86::ECX, X86::EDX},
733 [&](MCRegister &RegA) { return IsSubReg(RegA, Reg); }) ||
734 (ST.hasMMX() && X86::VR64RegClass.contains(Reg));
735
737
738 if (CC == CallingConv::X86_64_SysV && IsSubReg(X86::RAX, Reg))
739 return true;
740
741 if (llvm::any_of(
742 SmallVector<MCRegister>{X86::RDX, X86::RCX, X86::R8, X86::R9},
743 [&](MCRegister &RegA) { return IsSubReg(RegA, Reg); }))
744 return true;
745
746 if (CC != CallingConv::Win64 &&
747 llvm::any_of(SmallVector<MCRegister>{X86::RDI, X86::RSI},
748 [&](MCRegister &RegA) { return IsSubReg(RegA, Reg); }))
749 return true;
750
751 if (ST.hasSSE1() &&
752 llvm::any_of(SmallVector<MCRegister>{X86::XMM0, X86::XMM1, X86::XMM2,
753 X86::XMM3, X86::XMM4, X86::XMM5,
754 X86::XMM6, X86::XMM7},
755 [&](MCRegister &RegA) { return IsSubReg(RegA, Reg); }))
756 return true;
757
758 return X86GenRegisterInfo::isArgumentRegister(MF, Reg);
759}
760
762 MCRegister PhysReg) const {
763 const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
764 const TargetRegisterInfo &TRI = *ST.getRegisterInfo();
765
766 // Stack pointer.
767 if (TRI.isSuperOrSubRegisterEq(X86::RSP, PhysReg))
768 return true;
769
770 // Don't use the frame pointer if it's being used.
771 const X86FrameLowering &TFI = *getFrameLowering(MF);
772 if (TFI.hasFP(MF) && TRI.isSuperOrSubRegisterEq(X86::RBP, PhysReg))
773 return true;
774
775 return X86GenRegisterInfo::isFixedRegister(MF, PhysReg);
776}
777
779 return RC->getID() == X86::TILERegClassID;
780}
781
783 // Check if the EFLAGS register is marked as live-out. This shouldn't happen,
784 // because the calling convention defines the EFLAGS register as NOT
785 // preserved.
786 //
787 // Unfortunatelly the EFLAGS show up as live-out after branch folding. Adding
788 // an assert to track this and clear the register afterwards to avoid
789 // unnecessary crashes during release builds.
790 assert(!(Mask[X86::EFLAGS / 32] & (1U << (X86::EFLAGS % 32))) &&
791 "EFLAGS are not live-out from a patchpoint.");
792
793 // Also clean other registers that don't need preserving (IP).
794 for (auto Reg : {X86::EFLAGS, X86::RIP, X86::EIP, X86::IP})
795 Mask[Reg / 32] &= ~(1U << (Reg % 32));
796}
797
798//===----------------------------------------------------------------------===//
799// Stack Frame Processing methods
800//===----------------------------------------------------------------------===//
801
802static bool CantUseSP(const MachineFrameInfo &MFI) {
803 return MFI.hasVarSizedObjects() || MFI.hasOpaqueSPAdjustment();
804}
805
808 // We have a virtual register to reference argument, and don't need base
809 // pointer.
810 if (X86FI->getStackPtrSaveMI() != nullptr)
811 return false;
812
813 if (X86FI->hasPreallocatedCall())
814 return true;
815
816 const MachineFrameInfo &MFI = MF.getFrameInfo();
817
819 return false;
820
821 // When we need stack realignment, we can't address the stack from the frame
822 // pointer. When we have dynamic allocas or stack-adjusting inline asm, we
823 // can't address variables from the stack pointer. MS inline asm can
824 // reference locals while also adjusting the stack pointer. When we can't
825 // use both the SP and the FP, we need a separate base pointer register.
826 bool CantUseFP = hasStackRealignment(MF);
827 return CantUseFP && CantUseSP(MFI);
828}
829
832 return false;
833
834 const MachineFrameInfo &MFI = MF.getFrameInfo();
835 const MachineRegisterInfo *MRI = &MF.getRegInfo();
836
837 // Stack realignment requires a frame pointer. If we already started
838 // register allocation with frame pointer elimination, it is too late now.
839 if (!MRI->canReserveReg(FramePtr))
840 return false;
841
842 // If a base pointer is necessary. Check that it isn't too late to reserve
843 // it.
844 if (CantUseSP(MFI))
845 return MRI->canReserveReg(BasePtr);
846 return true;
847}
848
851 return true;
852
853 return !Is64Bit && MF.getFunction().getCallingConv() == CallingConv::X86_INTR;
854}
855
856// tryOptimizeLEAtoMOV - helper function that tries to replace a LEA instruction
857// of the form 'lea (%esp), %ebx' --> 'mov %esp, %ebx'.
858// TODO: In this case we should be really trying first to entirely eliminate
859// this instruction which is a plain copy.
861 MachineInstr &MI = *II;
862 unsigned Opc = II->getOpcode();
863 // Check if this is a LEA of the form 'lea (%esp), %ebx'
864 if ((Opc != X86::LEA32r && Opc != X86::LEA64r && Opc != X86::LEA64_32r) ||
865 MI.getOperand(2).getImm() != 1 ||
866 MI.getOperand(3).getReg() != X86::NoRegister ||
867 MI.getOperand(4).getImm() != 0 ||
868 MI.getOperand(5).getReg() != X86::NoRegister)
869 return false;
870 Register BasePtr = MI.getOperand(1).getReg();
871 // In X32 mode, ensure the base-pointer is a 32-bit operand, so the LEA will
872 // be replaced with a 32-bit operand MOV which will zero extend the upper
873 // 32-bits of the super register.
874 if (Opc == X86::LEA64_32r)
875 BasePtr = getX86SubSuperRegister(BasePtr, 32);
876 Register NewDestReg = MI.getOperand(0).getReg();
877 const X86InstrInfo *TII =
878 MI.getParent()->getParent()->getSubtarget<X86Subtarget>().getInstrInfo();
879 TII->copyPhysReg(*MI.getParent(), II, MI.getDebugLoc(), NewDestReg, BasePtr,
880 MI.getOperand(1).isKill());
881 MI.eraseFromParent();
882 return true;
883}
884
886 switch (MI.getOpcode()) {
887 case X86::CATCHRET:
888 case X86::CLEANUPRET:
889 return true;
890 default:
891 return false;
892 }
893 llvm_unreachable("impossible");
894}
895
897 unsigned FIOperandNum,
898 Register BaseReg,
899 int FIOffset) const {
900 MachineInstr &MI = *II;
901 unsigned Opc = MI.getOpcode();
902 if (Opc == TargetOpcode::LOCAL_ESCAPE) {
903 MachineOperand &FI = MI.getOperand(FIOperandNum);
904 FI.ChangeToImmediate(FIOffset);
905 return;
906 }
907
908 MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg, false);
909
910 // The frame index format for stackmaps and patchpoints is different from the
911 // X86 format. It only has a FI and an offset.
912 if (Opc == TargetOpcode::STACKMAP || Opc == TargetOpcode::PATCHPOINT) {
913 assert(BasePtr == FramePtr && "Expected the FP as base register");
914 int64_t Offset = MI.getOperand(FIOperandNum + 1).getImm() + FIOffset;
915 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
916 return;
917 }
918
919 if (MI.getOperand(FIOperandNum + 3).isImm()) {
920 // Offset is a 32-bit integer.
921 int Imm = (int)(MI.getOperand(FIOperandNum + 3).getImm());
922 int Offset = FIOffset + Imm;
923 assert((!Is64Bit || isInt<32>((long long)FIOffset + Imm)) &&
924 "Requesting 64-bit offset in 32-bit immediate!");
925 if (Offset != 0)
926 MI.getOperand(FIOperandNum + 3).ChangeToImmediate(Offset);
927 } else {
928 // Offset is symbolic. This is extremely rare.
930 FIOffset + (uint64_t)MI.getOperand(FIOperandNum + 3).getOffset();
931 MI.getOperand(FIOperandNum + 3).setOffset(Offset);
932 }
933}
934
935bool
937 int SPAdj, unsigned FIOperandNum,
938 RegScavenger *RS) const {
939 MachineInstr &MI = *II;
940 MachineBasicBlock &MBB = *MI.getParent();
941 MachineFunction &MF = *MBB.getParent();
942 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
943 bool IsEHFuncletEpilogue = MBBI == MBB.end() ? false
945 const X86FrameLowering *TFI = getFrameLowering(MF);
946 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
947
948 // Determine base register and offset.
949 int64_t FIOffset;
950 Register BasePtr;
951 if (MI.isReturn()) {
952 assert((!hasStackRealignment(MF) ||
953 MF.getFrameInfo().isFixedObjectIndex(FrameIndex)) &&
954 "Return instruction can only reference SP relative frame objects");
955 FIOffset =
956 TFI->getFrameIndexReferenceSP(MF, FrameIndex, BasePtr, 0).getFixed();
957 } else if (TFI->Is64Bit && (MBB.isEHFuncletEntry() || IsEHFuncletEpilogue)) {
958 FIOffset = TFI->getWin64EHFrameIndexRef(MF, FrameIndex, BasePtr);
959 } else {
960 FIOffset = TFI->getFrameIndexReference(MF, FrameIndex, BasePtr).getFixed();
961 }
962
963 // LOCAL_ESCAPE uses a single offset, with no register. It only works in the
964 // simple FP case, and doesn't work with stack realignment. On 32-bit, the
965 // offset is from the traditional base pointer location. On 64-bit, the
966 // offset is from the SP at the end of the prologue, not the FP location. This
967 // matches the behavior of llvm.frameaddress.
968 unsigned Opc = MI.getOpcode();
969 if (Opc == TargetOpcode::LOCAL_ESCAPE) {
970 MachineOperand &FI = MI.getOperand(FIOperandNum);
971 FI.ChangeToImmediate(FIOffset);
972 return false;
973 }
974
975 // For LEA64_32r when BasePtr is 32-bits (X32) we can use full-size 64-bit
976 // register as source operand, semantic is the same and destination is
977 // 32-bits. It saves one byte per lea in code since 0x67 prefix is avoided.
978 // Don't change BasePtr since it is used later for stack adjustment.
979 Register MachineBasePtr = BasePtr;
980 if (Opc == X86::LEA64_32r && X86::GR32RegClass.contains(BasePtr))
981 MachineBasePtr = getX86SubSuperRegister(BasePtr, 64);
982
983 // This must be part of a four operand memory reference. Replace the
984 // FrameIndex with base register. Add an offset to the offset.
985 MI.getOperand(FIOperandNum).ChangeToRegister(MachineBasePtr, false);
986
987 if (BasePtr == StackPtr)
988 FIOffset += SPAdj;
989
990 // The frame index format for stackmaps and patchpoints is different from the
991 // X86 format. It only has a FI and an offset.
992 if (Opc == TargetOpcode::STACKMAP || Opc == TargetOpcode::PATCHPOINT) {
993 assert(BasePtr == FramePtr && "Expected the FP as base register");
994 int64_t Offset = MI.getOperand(FIOperandNum + 1).getImm() + FIOffset;
995 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
996 return false;
997 }
998
999 if (MI.getOperand(FIOperandNum+3).isImm()) {
1000 const X86InstrInfo *TII = MF.getSubtarget<X86Subtarget>().getInstrInfo();
1001 const DebugLoc &DL = MI.getDebugLoc();
1002 int64_t Imm = MI.getOperand(FIOperandNum + 3).getImm();
1003 int64_t Offset = FIOffset + Imm;
1004 bool FitsIn32Bits = isInt<32>(Offset);
1005 // If the offset will not fit in a 32-bit displacement, then for 64-bit
1006 // targets, scavenge a register to hold it. Otherwise...
1007 if (Is64Bit && !FitsIn32Bits) {
1008 assert(RS && "RegisterScavenger was NULL");
1009
1010 RS->enterBasicBlockEnd(MBB);
1011 RS->backward(std::next(II));
1012
1013 Register ScratchReg = RS->scavengeRegisterBackwards(
1014 X86::GR64RegClass, II, /*RestoreAfter=*/false, /*SPAdj=*/0,
1015 /*AllowSpill=*/true);
1016 assert(ScratchReg != 0 && "scratch reg was 0");
1017 RS->setRegUsed(ScratchReg);
1018
1019 BuildMI(MBB, II, DL, TII->get(X86::MOV64ri), ScratchReg).addImm(Offset);
1020
1021 MI.getOperand(FIOperandNum + 3).setImm(0);
1022 MI.getOperand(FIOperandNum + 2).setReg(ScratchReg);
1023
1024 return false;
1025 }
1026
1027 // ... for 32-bit targets, this is a bug!
1028 if (!Is64Bit && !FitsIn32Bits) {
1029 MI.emitGenericError("64-bit offset calculated but target is 32-bit");
1030 // Trap so that the instruction verification pass does not fail if run.
1031 BuildMI(MBB, MBBI, DL, TII->get(X86::TRAP));
1032 return false;
1033 }
1034
1035 if (Offset != 0 || !tryOptimizeLEAtoMOV(II))
1036 MI.getOperand(FIOperandNum + 3).ChangeToImmediate(Offset);
1037 } else {
1038 // Offset is symbolic. This is extremely rare.
1039 uint64_t Offset = FIOffset +
1040 (uint64_t)MI.getOperand(FIOperandNum+3).getOffset();
1041 MI.getOperand(FIOperandNum + 3).setOffset(Offset);
1042 }
1043 return false;
1044}
1045
1048 const MachineFunction *MF = MBB.getParent();
1049 const MachineRegisterInfo &MRI = MF->getRegInfo();
1050 if (MF->callsEHReturn())
1051 return 0;
1052
1053 if (MBBI == MBB.end())
1054 return 0;
1055
1056 switch (MBBI->getOpcode()) {
1057 default:
1058 return 0;
1059 case TargetOpcode::PATCHABLE_RET:
1060 case X86::RET:
1061 case X86::RET32:
1062 case X86::RET64:
1063 case X86::RETI32:
1064 case X86::RETI64:
1065 case X86::TCRETURNdi:
1066 case X86::TCRETURNri:
1067 case X86::TCRETURN_WIN64ri:
1068 case X86::TCRETURN_HIPE32ri:
1069 case X86::TCRETURNmi:
1070 case X86::TCRETURNdi64:
1071 case X86::TCRETURNri64:
1072 case X86::TCRETURNri64_ImpCall:
1073 case X86::TCRETURNmi64:
1074 case X86::TCRETURN_WINmi64:
1075 case X86::EH_RETURN:
1076 case X86::EH_RETURN64: {
1077 LiveRegUnits LRU(*this);
1078 LRU.addLiveOuts(MBB);
1079 LRU.stepBackward(*MBBI);
1080
1081 const TargetRegisterClass &RC =
1082 Is64Bit ? X86::GR64_NOSPRegClass : X86::GR32_NOSPRegClass;
1083 for (MCRegister Reg : RC) {
1084 if (LRU.available(Reg) && !MRI.isReserved(Reg))
1085 return Reg;
1086 }
1087 }
1088 }
1089
1090 return 0;
1091}
1092
1094 const X86FrameLowering *TFI = getFrameLowering(MF);
1095 return TFI->hasFP(MF) ? FramePtr : StackPtr;
1096}
1097
1100 const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
1101 Register FrameReg = getFrameRegister(MF);
1102 if (Subtarget.isTarget64BitILP32())
1103 FrameReg = getX86SubSuperRegister(FrameReg, 32);
1104 return FrameReg;
1105}
1106
1109 const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
1110 Register StackReg = getStackRegister();
1111 if (Subtarget.isTarget64BitILP32())
1112 StackReg = getX86SubSuperRegister(StackReg, 32);
1113 return StackReg;
1114}
1115
1117 const MachineRegisterInfo *MRI) {
1118 if (VRM->hasShape(VirtReg))
1119 return VRM->getShape(VirtReg);
1120
1121 const MachineOperand &Def = *MRI->def_begin(VirtReg);
1122 MachineInstr *MI = const_cast<MachineInstr *>(Def.getParent());
1123 unsigned OpCode = MI->getOpcode();
1124 switch (OpCode) {
1125 default:
1126 llvm_unreachable("Unexpected machine instruction on tile register!");
1127 break;
1128 case X86::COPY: {
1129 Register SrcReg = MI->getOperand(1).getReg();
1130 ShapeT Shape = getTileShape(SrcReg, VRM, MRI);
1131 VRM->assignVirt2Shape(VirtReg, Shape);
1132 return Shape;
1133 }
1134 // We only collect the tile shape that is defined.
1135 case X86::PTILELOADDV:
1136 case X86::PTILELOADDT1V:
1137 case X86::PTDPBSSDV:
1138 case X86::PTDPBSUDV:
1139 case X86::PTDPBUSDV:
1140 case X86::PTDPBUUDV:
1141 case X86::PTILEZEROV:
1142 case X86::PTDPBF16PSV:
1143 case X86::PTDPFP16PSV:
1144 case X86::PTCMMIMFP16PSV:
1145 case X86::PTCMMRLFP16PSV:
1146 case X86::PTILELOADDRSV:
1147 case X86::PTILELOADDRST1V:
1148 case X86::PTDPBF8PSV:
1149 case X86::PTDPBHF8PSV:
1150 case X86::PTDPHBF8PSV:
1151 case X86::PTDPHF8PSV: {
1152 MachineOperand &MO1 = MI->getOperand(1);
1153 MachineOperand &MO2 = MI->getOperand(2);
1154 ShapeT Shape(&MO1, &MO2, MRI);
1155 VRM->assignVirt2Shape(VirtReg, Shape);
1156 return Shape;
1157 }
1158 }
1159}
1160
1162 ArrayRef<MCPhysReg> Order,
1164 const MachineFunction &MF,
1165 const VirtRegMap *VRM,
1166 const LiveRegMatrix *Matrix) const {
1167 const MachineRegisterInfo *MRI = &MF.getRegInfo();
1168 const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
1169 bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
1170 VirtReg, Order, Hints, MF, VRM, Matrix);
1171 const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
1172 const TargetRegisterInfo &TRI = *ST.getRegisterInfo();
1173
1174 unsigned ID = RC.getID();
1175
1176 if (!VRM)
1177 return BaseImplRetVal;
1178
1179 if (ID != X86::TILERegClassID) {
1180 if (DisableRegAllocNDDHints || !ST.hasNDD() ||
1181 !TRI.isGeneralPurposeRegisterClass(&RC))
1182 return BaseImplRetVal;
1183
1184 // Add any two address hints after any copy hints.
1185 SmallSet<unsigned, 4> TwoAddrHints;
1186
1187 auto TryAddNDDHint = [&](const MachineOperand &MO) {
1188 Register Reg = MO.getReg();
1189 Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));
1190 if (PhysReg && !MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
1191 TwoAddrHints.insert(PhysReg);
1192 };
1193
1194 // NDD instructions is compressible when Op0 is allocated to the same
1195 // physic register as Op1 (or Op2 if it's commutable).
1196 for (auto &MO : MRI->reg_nodbg_operands(VirtReg)) {
1197 const MachineInstr &MI = *MO.getParent();
1198 if (!X86::getNonNDVariant(MI.getOpcode()))
1199 continue;
1200 unsigned OpIdx = MI.getOperandNo(&MO);
1201 if (OpIdx == 0) {
1202 assert(MI.getOperand(1).isReg());
1203 TryAddNDDHint(MI.getOperand(1));
1204 if (MI.isCommutable()) {
1205 assert(MI.getOperand(2).isReg());
1206 TryAddNDDHint(MI.getOperand(2));
1207 }
1208 } else if (OpIdx == 1) {
1209 TryAddNDDHint(MI.getOperand(0));
1210 } else if (MI.isCommutable() && OpIdx == 2) {
1211 TryAddNDDHint(MI.getOperand(0));
1212 }
1213 }
1214
1215 for (MCPhysReg OrderReg : Order)
1216 if (TwoAddrHints.count(OrderReg))
1217 Hints.push_back(OrderReg);
1218
1219 return BaseImplRetVal;
1220 }
1221
1222 ShapeT VirtShape = getTileShape(VirtReg, const_cast<VirtRegMap *>(VRM), MRI);
1223 auto AddHint = [&](MCPhysReg PhysReg) {
1224 Register VReg = Matrix->getOneVReg(PhysReg);
1225 if (VReg == MCRegister::NoRegister) { // Not allocated yet
1226 Hints.push_back(PhysReg);
1227 return;
1228 }
1229 ShapeT PhysShape = getTileShape(VReg, const_cast<VirtRegMap *>(VRM), MRI);
1230 if (PhysShape == VirtShape)
1231 Hints.push_back(PhysReg);
1232 };
1233
1234 SmallSet<MCPhysReg, 4> CopyHints(llvm::from_range, Hints);
1235 Hints.clear();
1236 for (auto Hint : CopyHints) {
1237 if (RC.contains(Hint) && !MRI->isReserved(Hint))
1238 AddHint(Hint);
1239 }
1240 for (MCPhysReg PhysReg : Order) {
1241 if (!CopyHints.count(PhysReg) && RC.contains(PhysReg) &&
1242 !MRI->isReserved(PhysReg))
1243 AddHint(PhysReg);
1244 }
1245
1246#define DEBUG_TYPE "tile-hint"
1247 LLVM_DEBUG({
1248 dbgs() << "Hints for virtual register " << format_hex(VirtReg, 8) << "\n";
1249 for (auto Hint : Hints) {
1250 dbgs() << "tmm" << Hint << ",";
1251 }
1252 dbgs() << "\n";
1253 });
1254#undef DEBUG_TYPE
1255
1256 return true;
1257}
1258
1260 const TargetRegisterClass *RC) const {
1261 switch (RC->getID()) {
1262 default:
1263 return RC;
1264 case X86::GR8RegClassID:
1265 return &X86::GR8_NOREX2RegClass;
1266 case X86::GR16RegClassID:
1267 return &X86::GR16_NOREX2RegClass;
1268 case X86::GR32RegClassID:
1269 return &X86::GR32_NOREX2RegClass;
1270 case X86::GR64RegClassID:
1271 return &X86::GR64_NOREX2RegClass;
1272 case X86::GR32_NOSPRegClassID:
1273 return &X86::GR32_NOREX2_NOSPRegClass;
1274 case X86::GR64_NOSPRegClassID:
1275 return &X86::GR64_NOREX2_NOSPRegClass;
1276 }
1277}
1278
1280 switch (RC->getID()) {
1281 default:
1282 return false;
1283 case X86::GR8_NOREX2RegClassID:
1284 case X86::GR16_NOREX2RegClassID:
1285 case X86::GR32_NOREX2RegClassID:
1286 case X86::GR64_NOREX2RegClassID:
1287 case X86::GR32_NOREX2_NOSPRegClassID:
1288 case X86::GR64_NOREX2_NOSPRegClassID:
1289 case X86::GR64_with_sub_16bit_in_GR16_NOREX2RegClassID:
1290 return true;
1291 }
1292}
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Live Register Matrix
static cl::opt< bool > EnableBasePointer("m68k-use-base-pointer", cl::Hidden, cl::init(true), cl::desc("Enable use of a base pointer for complex stack frames"))
static bool CantUseSP(const MachineFrameInfo &MFI)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file defines the SmallSet class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
cl::opt< bool > X86EnableAPXForRelocation
static cl::opt< unsigned > SetjmpCSRWarningThreshold("x86-setjmp-csr-warning-threshold", cl::Hidden, cl::init(50), cl::desc("Basic block count threshold for emitting a warning about " "callee-saved registers reserved due to setjmp"))
static cl::opt< bool > EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true), cl::desc("Enable use of a base pointer for complex stack frames"))
static bool tryOptimizeLEAtoMOV(MachineBasicBlock::iterator II)
static cl::opt< bool > DisableRegAllocNDDHints("x86-disable-regalloc-hints-for-ndd", cl::Hidden, cl::init(false), cl::desc("Disable two address hints for register " "allocation"))
static ShapeT getTileShape(Register VirtReg, VirtRegMap *VRM, const MachineRegisterInfo *MRI)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
A debug info location.
Definition DebugLoc.h:126
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
LLVM_ABI void stepBackward(const MachineInstr &MI)
Updates liveness when stepping backwards over the instruction MI.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
LLVM_ABI void reportWarning(SMLoc L, const Twine &Msg)
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
MCRegAliasIterator enumerates all registers aliasing Reg.
ArrayRef< unsigned > superclasses() const
Returns a list of super-classes.
unsigned getID() const
getID() - Return the register class ID number.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
static constexpr unsigned NoRegister
Definition MCRegister.h:60
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
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...
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.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
def_iterator def_begin(Register RegNo) const
bool reservedRegsFrozen() const
reservedRegsFrozen - Returns true after freezeReservedRegs() was called to ensure the set of reserved...
bool canReserveReg(MCRegister PhysReg) const
canReserveReg - Returns true if PhysReg can be used as a reserved register.
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
Represents a location in source code.
Definition SMLoc.h:22
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetOptions Options
LLVM_ABI bool FramePointerIsReserved(const MachineFunction &MF) const
FramePointerIsReserved - This returns true if the frame pointer must always either point to a new fra...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool canRealignStack(const MachineFunction &MF) const
True if the stack can be realigned for the target.
virtual bool shouldRealignStack(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
bool hasShape(Register virtReg) const
Definition VirtRegMap.h:102
ShapeT getShape(Register virtReg) const
Definition VirtRegMap.h:106
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition VirtRegMap.h:91
void assignVirt2Shape(Register virtReg, ShapeT shape)
Definition VirtRegMap.h:111
StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, Register &SPReg, int Adjustment) const
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
bool Is64Bit
Is64Bit implies that x86_64 instructions are available.
int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, Register &SPReg) const
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
MachineInstr * getStackPtrSaveMI() const
bool hasBasePointer(const MachineFunction &MF) const
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
getPointerRegClass - Returns a TargetRegisterClass used for pointer values.
const MCPhysReg * getCalleeSavedRegsViaCopy(const MachineFunction *MF) const
bool canRealignStack(const MachineFunction &MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
getReservedRegs - Returns a bitset indexed by physical register number indicating if a register is a ...
Register getPtrSizedFrameRegister(const MachineFunction &MF) const
bool shouldRealignStack(const MachineFunction &MF) const override
unsigned getNumSupportedRegs(const MachineFunction &MF) const override
Return the number of registers for the function.
const MCPhysReg * getIPRACSRegs(const MachineFunction *MF) const override
getIPRACSRegs - This API can be removed when rbp is safe to optimized out when IPRA is on.
Register getFrameRegister(const MachineFunction &MF) const override
unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const
findDeadCallerSavedReg - Return a caller-saved register that isn't live when it reaches the "return" ...
const uint32_t * getDarwinTLSCallPreservedMask() const
bool isTileRegisterClass(const TargetRegisterClass *RC) const
Return true if it is tile register class.
bool isNonRex2RegClass(const TargetRegisterClass *RC) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register getPtrSizedStackRegister(const MachineFunction &MF) const
bool isArgumentRegister(const MachineFunction &MF, MCRegister Reg) const override
isArgumentReg - Returns true if Reg can be used as an argument to a function.
Register getStackRegister() const
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const override
getMatchingSuperRegClass - Return a subclass of the specified register class A so that each register ...
unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override
const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const override
getCrossCopyRegClass - Returns a legal register class to copy a register in the specified class to or...
X86RegisterInfo(const Triple &TT)
const TargetRegisterClass * constrainRegClassToNonRex2(const TargetRegisterClass *RC) const
Register getBaseRegister() const
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
void eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned FIOperandNum, Register BaseReg, int FIOffset) const
const uint32_t * getNoPreservedMask() const override
bool isFixedRegister(const MachineFunction &MF, MCRegister PhysReg) const override
Returns true if PhysReg is a fixed register.
const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const override
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
getCalleeSavedRegs - Return a null-terminated list of all of the callee-save registers on this target...
void adjustStackMapLiveOutMask(uint32_t *Mask) const override
bool isLFI() const
bool hasSSE1() const
const X86TargetLowering * getTargetLowering() const override
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
bool hasAVX512() const
bool hasAVX() const
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ X86_64_SysV
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
Definition CallingConv.h:53
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Definition CallingConv.h:82
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
Definition CallingConv.h:60
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ X86_INTR
x86 hardware interrupt context.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
Definition CallingConv.h:47
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Intel_OCL_BI
Used for Intel OpenCL built-ins.
@ PreserveNone
Used for runtime calls that preserves none general registers.
Definition CallingConv.h:90
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ GRAAL
Used by GraalVM. Two additional registers are reserved.
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
void initLLVMToSEHAndCVRegMapping(MCRegisterInfo *MRI)
Define some predicates that are used for node matching.
unsigned getNonNDVariant(unsigned Opc)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
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:165
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
constexpr from_range_t from_range
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
static bool isFuncletReturnInstr(const MachineInstr &MI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition Format.h:156
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58