LLVM 24.0.0git
X86Subtarget.cpp
Go to the documentation of this file.
1//===-- X86Subtarget.cpp - X86 Subtarget 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 implements the X86 specific subclass of TargetSubtargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#include "X86Subtarget.h"
18#include "X86.h"
19#include "X86MacroFusion.h"
20#include "X86TargetMachine.h"
25#include "llvm/IR/Attributes.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/Module.h"
33#include "llvm/Support/Debug.h"
37
38#if defined(_MSC_VER)
39#include <intrin.h>
40#endif
41
42using namespace llvm;
43
44#define DEBUG_TYPE "subtarget"
45
46#define GET_SUBTARGETINFO_TARGET_DESC
47#define GET_SUBTARGETINFO_CTOR
48#include "X86GenSubtargetInfo.inc"
49
50#define OPTIONS_STRUCT_DEFS
51#include "X86Options.inc"
52
53/// Classify a blockaddress reference for the current subtarget according to how
54/// we should reference it in a non-pcrel context.
56 return classifyLocalReference(nullptr);
57}
58
59/// Classify a global variable reference for the current subtarget according to
60/// how we should reference it in a non-pcrel context.
61unsigned char
65
66unsigned char
68 CodeModel::Model CM = TM.getCodeModel();
69 // Tagged globals have non-zero upper bits, which makes direct references
70 // require a 64-bit immediate. With the small/medium code models this causes
71 // relocation errors, so we go through the GOT instead.
72 if (AllowTaggedGlobals && CM != CodeModel::Large && GV && !isa<Function>(GV))
74
75 // If we're not PIC, it's not very interesting.
77 return X86II::MO_NO_FLAG;
78
79 if (is64Bit()) {
80 // 64-bit ELF PIC local references may use GOTOFF relocations.
81 if (isTargetELF()) {
82 assert(CM != CodeModel::Tiny &&
83 "Tiny codesize model not supported on X86");
84 // In the large code model, all text is far from any global data, so we
85 // use GOTOFF.
86 if (CM == CodeModel::Large)
87 return X86II::MO_GOTOFF;
88 // Large GlobalValues use GOTOFF, otherwise use RIP-rel access.
89 if (GV)
90 return TM.isLargeGlobalValue(GV) ? X86II::MO_GOTOFF : X86II::MO_NO_FLAG;
91 // GV == nullptr is for all other non-GlobalValue global data like the
92 // constant pool, jump tables, labels, etc. The small and medium code
93 // models treat these as accessible with a RIP-rel access.
94 return X86II::MO_NO_FLAG;
95 }
96
97 // Otherwise, this is either a RIP-relative reference or a 64-bit movabsq,
98 // both of which use MO_NO_FLAG.
99 return X86II::MO_NO_FLAG;
100 }
101
102 // The COFF dynamic linker just patches the executable sections.
103 if (isTargetCOFF())
104 return X86II::MO_NO_FLAG;
105
106 if (isTargetDarwin()) {
107 // 32 bit macho has no relocation for a-b if a is undefined, even if
108 // b is in the section that is being relocated.
109 // This means we have to use o load even for GVs that are known to be
110 // local to the dso.
111 if (GV && (GV->isDeclarationForLinker() || GV->hasCommonLinkage()))
113
115 }
116
117 return X86II::MO_GOTOFF;
118}
119
121 const Module &M) const {
122 // The static large model never uses stubs.
123 if (TM.getCodeModel() == CodeModel::Large && !isPositionIndependent())
124 return X86II::MO_NO_FLAG;
125
126 // Absolute symbols can be referenced directly.
127 if (GV) {
128 if (std::optional<ConstantRange> CR = GV->getAbsoluteSymbolRange()) {
129 // See if we can use the 8-bit immediate form. Note that some instructions
130 // will sign extend the immediate operand, so to be conservative we only
131 // accept the range [0,128).
132 if (CR->getUnsignedMax().ult(128))
133 return X86II::MO_ABS8;
134 else
135 return X86II::MO_NO_FLAG;
136 }
137 }
138
139 if (TM.shouldAssumeDSOLocal(GV))
140 return classifyLocalReference(GV);
141
142 if (isTargetCOFF()) {
143 // ExternalSymbolSDNode like _tls_index.
144 if (!GV)
145 return X86II::MO_NO_FLAG;
146 if (GV->hasDLLImportStorageClass())
147 return X86II::MO_DLLIMPORT;
148 return X86II::MO_COFFSTUB;
149 }
150 // Some JIT users use *-win32-elf triples; these shouldn't use GOT tables.
151 if (isOSWindows())
152 return X86II::MO_NO_FLAG;
153
154 if (is64Bit()) {
155 // ELF supports a large, truly PIC code model with non-PC relative GOT
156 // references. Other object file formats do not. Use the no-flag, 64-bit
157 // reference for them.
158 if (TM.getCodeModel() == CodeModel::Large)
160 // Tagged globals have non-zero upper bits, which makes direct references
161 // require a 64-bit immediate. So we can't let the linker relax the
162 // relocation to a 32-bit RIP-relative direct reference.
163 if (AllowTaggedGlobals && GV && !isa<Function>(GV))
165 return X86II::MO_GOTPCREL;
166 }
167
168 if (isTargetDarwin()) {
172 }
173
174 // 32-bit ELF references GlobalAddress directly in static relocation model.
175 // We cannot use MO_GOT because EBX may not be set up.
176 if (TM.getRelocationModel() == Reloc::Static)
177 return X86II::MO_NO_FLAG;
178 return X86II::MO_GOT;
179}
180
181unsigned char
185
186unsigned char
188 const Module &M) const {
189 if (TM.shouldAssumeDSOLocal(GV))
190 return X86II::MO_NO_FLAG;
191
192 // Functions on COFF can be non-DSO local for three reasons:
193 // - They are intrinsic functions (!GV)
194 // - They are marked dllimport
195 // - They are extern_weak, and a stub is needed
196 if (isTargetCOFF()) {
197 if (!GV)
198 return X86II::MO_NO_FLAG;
199 if (GV->hasDLLImportStorageClass())
200 return X86II::MO_DLLIMPORT;
201 return X86II::MO_COFFSTUB;
202 }
203
205
206 if (isTargetELF()) {
207 if (is64Bit() && F && (CallingConv::X86_RegCall == F->getCallingConv()))
208 // According to psABI, PLT stub clobbers XMM8-XMM15.
209 // In Regcall calling convention those registers are used for passing
210 // parameters. Thus we need to prevent lazy binding in Regcall.
211 return X86II::MO_GOTPCREL;
212 // If PLT must be avoided then the call should be via GOTPCREL.
213 if (((F && F->hasFnAttribute(Attribute::NonLazyBind)) ||
214 (!F && M.getRtLibUseGOT())) &&
215 is64Bit())
216 return X86II::MO_GOTPCREL;
217 // Reference ExternalSymbol directly in static relocation model.
218 if (!is64Bit() && !GV && TM.getRelocationModel() == Reloc::Static)
219 return X86II::MO_NO_FLAG;
220 return X86II::MO_PLT;
221 }
222
223 if (is64Bit()) {
224 if (F && F->hasFnAttribute(Attribute::NonLazyBind))
225 // If the function is marked as non-lazy, generate an indirect call
226 // which loads from the GOT directly. This avoids runtime overhead
227 // at the cost of eager binding (and one extra byte of encoding).
228 return X86II::MO_GOTPCREL;
229 return X86II::MO_NO_FLAG;
230 }
231
232 return X86II::MO_NO_FLAG;
233}
234
235/// Return true if the subtarget allows calls to immediate address.
237 // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32
238 // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does,
239 // the following check for Win32 should be removed.
240 if (Is64Bit || isTargetWin32() || isPositionIndependent())
241 return false;
242 return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
243}
244
245void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
246 StringRef FS) {
247 if (CPU.empty())
248 CPU = "generic";
249
250 if (TuneCPU.empty())
251 TuneCPU = "i586"; // FIXME: "generic" is more modern than llc tests expect.
252
253 std::string FullFS = X86_MC::ParseX86Triple(TargetTriple);
254 assert(!FullFS.empty() && "Failed to parse X86 triple");
255
256 if (!FS.empty())
257 FullFS = (Twine(FullFS) + "," + FS).str();
258
259 // Disable 64-bit only features in non-64-bit mode.
260 StringRef FeaturesIn64BitOnly[] = {"egpr", "push2pop2", "ppx", "ndd",
261 "ccmp", "nf", "cf", "zu",
262 "jmpabs", "uintr"};
263 if (FullFS.find("-64bit-mode") != std::string::npos)
264 for (StringRef F : FeaturesIn64BitOnly)
265 FullFS += ",-" + F.str();
266
267 // Parse features string and set the CPU.
268 ParseSubtargetFeatures(CPU, TuneCPU, FullFS);
269
270 // All CPUs that implement SSE4.2 or SSE4A support unaligned accesses of
271 // 16-bytes and under that are reasonably fast. These features were
272 // introduced with Intel's Nehalem/Silvermont and AMD's Family10h
273 // micro-architectures respectively.
274 if (hasSSE42() || hasSSE4A())
275 IsUnalignedMem16Slow = false;
276
277 LLVM_DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
278 << ", MMX " << HasMMX << ", 64bit " << HasX86_64 << "\n");
279 if (Is64Bit && !HasX86_64)
280 reportFatalUsageError("64-bit code requested on a subtarget that doesn't "
281 "support it!");
282
283 if (HasEGPR && !hasSSE1() && isTargetWin64())
284 reportFatalUsageError("EGPR on Windows x64 requires SSE");
285
286 // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD, Hurd and for all
287 // 64-bit targets. On Solaris (32-bit), stack alignment is 4 bytes
288 // following the i386 psABI, while on Illumos it is always 16 bytes.
289 if (StackAlignOverride)
290 stackAlignment = *StackAlignOverride;
291 else if (isTargetDarwin() || isTargetLinux() || isTargetKFreeBSD() ||
292 isTargetHurd() || Is64Bit)
293 stackAlignment = Align(16);
294
295 // Consume the vector width attribute or apply any target specific limit.
296 if (PreferVectorWidthOverride)
297 PreferVectorWidth = PreferVectorWidthOverride;
298 else if (Prefer128Bit)
299 PreferVectorWidth = 128;
300 else if (Prefer256Bit)
301 PreferVectorWidth = 256;
302
303 HasUserReservedRegisters = ReservedRReg.any();
304}
305
306X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
307 StringRef TuneCPU,
308 StringRef FS) {
309 initSubtargetFeatures(CPU, TuneCPU, FS);
310 return *this;
311}
312
314 StringRef FS, const X86TargetMachine &TM,
315 MaybeAlign StackAlignOverride,
316 unsigned PreferVectorWidthOverride,
317 unsigned RequiredVectorWidth)
318 : X86GenSubtargetInfo(TT, CPU, TuneCPU, FS), CLOpts(TM.getCLOpts()),
319 PICStyle(PICStyles::Style::None), TM(TM), TargetTriple(TT),
320 StackAlignOverride(StackAlignOverride),
321 PreferVectorWidthOverride(PreferVectorWidthOverride),
322 RequiredVectorWidth(RequiredVectorWidth),
323 InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
324 TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
325 // Determine the PICStyle based on the target selected.
326 if (!isPositionIndependent() || TM.getCodeModel() == CodeModel::Large)
327 // With the large code model, None forces all memory accesses to be indirect
328 // rather than RIP-relative.
330 else if (is64Bit())
332 else if (isTargetCOFF())
334 else if (isTargetDarwin())
336 else if (isTargetELF())
338
339 CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering()));
340 Legalizer.reset(new X86LegalizerInfo(*this, TM));
341
342 auto *RBI = new X86RegisterBankInfo(*getRegisterInfo());
343 RegBankInfo.reset(RBI);
344 InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI));
345}
346
347// Define the virtual destructor out-of-line for build efficiency.
349
351 return CallLoweringInfo.get();
352}
353
355 return InstSelector.get();
356}
357
359 return Legalizer.get();
360}
361
363 return RegBankInfo.get();
364}
365
367 return canUseCMOV() && CLOpts.early_ifcvt;
368}
369
371 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
372 Mutations.push_back(createX86MacroFusionDAGMutation());
373}
374
376 return TM.isPositionIndependent();
377}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the simple types necessary to represent the attributes associated with functions a...
This file describes how to lower LLVM calls to machine code calls.
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM calls to machine code calls.
static bool is64Bit(const char *name)
This file declares the targeting of the Machinelegalizer class for X86.
This file declares the targeting of the RegisterBankInfo class for X86.
bool hasDLLImportStorageClass() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
Definition Globals.cpp:534
bool hasCommonLinkage() const
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Holds all the information related to register banks.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This class provides the information for the target register banks.
bool enableEarlyIfConversion() const override
~X86Subtarget() override
bool isOSWindows() const
bool isTargetKFreeBSD() const
bool hasSSE1() const
bool hasSSE42() const
InstructionSelector * getInstructionSelector() const override
const X86TargetLowering * getTargetLowering() const override
bool canUseCMOV() const
bool isLegalToCallImmediateAddr() const
Return true if the subtarget allows calls to immediate address.
bool isTargetDarwin() const
bool isTargetWin64() const
const RegisterBankInfo * getRegBankInfo() const override
bool isTargetCOFF() const
Align getStackAlignment() const
Returns the minimum alignment known to hold of the stack frame on entry to the function and which mus...
bool isTargetELF() const
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
const LegalizerInfo * getLegalizerInfo() const override
bool isPositionIndependent() const
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
unsigned char classifyBlockAddressReference() const
Classify a blockaddress reference for the current subtarget according to how we should reference it i...
const X86RegisterInfo * getRegisterInfo() const override
void setPICStyle(PICStyles::Style Style)
X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, const X86TargetMachine &TM, MaybeAlign StackAlignOverride, unsigned PreferVectorWidthOverride, unsigned RequiredVectorWidth)
This constructor initializes the data members to match that of the specified triple.
const X86Options & getCLOpts() const
const CallLowering * getCallLowering() const override
Methods used by Global ISel.
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation > > &Mutations) const override
bool isTargetHurd() const
bool isTargetWin32() const
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
bool isTargetLinux() const
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
The X86 backend supports a number of different styles of PIC.
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_DARWIN_NONLAZY_PIC_BASE
MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
@ MO_DARWIN_NONLAZY
MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...
@ MO_GOT
MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...
@ MO_ABS8
MO_ABS8 - On a symbol operand this indicates that the symbol is known to be an absolute symbol in ran...
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
std::string ParseX86Triple(const Triple &TT)
This is an optimization pass for GlobalISel generic memory operations.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
std::unique_ptr< ScheduleDAGMutation > createX86MacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createX86MacroFusionDAGMutation()); to X86TargetMachine::c...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
InstructionSelector * createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &)
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:111