LLVM 22.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"
38
39#if defined(_MSC_VER)
40#include <intrin.h>
41#endif
42
43using namespace llvm;
44
45#define DEBUG_TYPE "subtarget"
46
47#define GET_SUBTARGETINFO_TARGET_DESC
48#define GET_SUBTARGETINFO_CTOR
49#include "X86GenSubtargetInfo.inc"
50
51// Temporary option to control early if-conversion for x86 while adding machine
52// models.
53static cl::opt<bool>
54X86EarlyIfConv("x86-early-ifcvt", cl::Hidden,
55 cl::desc("Enable early if-conversion on X86"));
56
57
58/// Classify a blockaddress reference for the current subtarget according to how
59/// we should reference it in a non-pcrel context.
61 return classifyLocalReference(nullptr);
62}
63
64/// Classify a global variable reference for the current subtarget according to
65/// how we should reference it in a non-pcrel context.
66unsigned char
68 return classifyGlobalReference(GV, *GV->getParent());
69}
70
71unsigned char
74 // Tagged globals have non-zero upper bits, which makes direct references
75 // require a 64-bit immediate. With the small/medium code models this causes
76 // relocation errors, so we go through the GOT instead.
77 if (AllowTaggedGlobals && CM != CodeModel::Large && GV && !isa<Function>(GV))
79
80 // If we're not PIC, it's not very interesting.
82 return X86II::MO_NO_FLAG;
83
84 if (is64Bit()) {
85 // 64-bit ELF PIC local references may use GOTOFF relocations.
86 if (isTargetELF()) {
87 assert(CM != CodeModel::Tiny &&
88 "Tiny codesize model not supported on X86");
89 // In the large code model, all text is far from any global data, so we
90 // use GOTOFF.
91 if (CM == CodeModel::Large)
92 return X86II::MO_GOTOFF;
93 // Large GlobalValues use GOTOFF, otherwise use RIP-rel access.
94 if (GV)
96 // GV == nullptr is for all other non-GlobalValue global data like the
97 // constant pool, jump tables, labels, etc. The small and medium code
98 // models treat these as accessible with a RIP-rel access.
99 return X86II::MO_NO_FLAG;
100 }
101
102 // Otherwise, this is either a RIP-relative reference or a 64-bit movabsq,
103 // both of which use MO_NO_FLAG.
104 return X86II::MO_NO_FLAG;
105 }
106
107 // The COFF dynamic linker just patches the executable sections.
108 if (isTargetCOFF())
109 return X86II::MO_NO_FLAG;
110
111 if (isTargetDarwin()) {
112 // 32 bit macho has no relocation for a-b if a is undefined, even if
113 // b is in the section that is being relocated.
114 // This means we have to use o load even for GVs that are known to be
115 // local to the dso.
116 if (GV && (GV->isDeclarationForLinker() || GV->hasCommonLinkage()))
118
120 }
121
122 return X86II::MO_GOTOFF;
123}
124
126 const Module &M) const {
127 // The static large model never uses stubs.
129 return X86II::MO_NO_FLAG;
130
131 // Absolute symbols can be referenced directly.
132 if (GV) {
133 if (std::optional<ConstantRange> CR = GV->getAbsoluteSymbolRange()) {
134 // See if we can use the 8-bit immediate form. Note that some instructions
135 // will sign extend the immediate operand, so to be conservative we only
136 // accept the range [0,128).
137 if (CR->getUnsignedMax().ult(128))
138 return X86II::MO_ABS8;
139 else
140 return X86II::MO_NO_FLAG;
141 }
142 }
143
144 if (TM.shouldAssumeDSOLocal(GV))
145 return classifyLocalReference(GV);
146
147 if (isTargetCOFF()) {
148 // ExternalSymbolSDNode like _tls_index.
149 if (!GV)
150 return X86II::MO_NO_FLAG;
151 if (GV->hasDLLImportStorageClass())
152 return X86II::MO_DLLIMPORT;
153 return X86II::MO_COFFSTUB;
154 }
155 // Some JIT users use *-win32-elf triples; these shouldn't use GOT tables.
156 if (isOSWindows())
157 return X86II::MO_NO_FLAG;
158
159 if (is64Bit()) {
160 // ELF supports a large, truly PIC code model with non-PC relative GOT
161 // references. Other object file formats do not. Use the no-flag, 64-bit
162 // reference for them.
163 if (TM.getCodeModel() == CodeModel::Large)
165 // Tagged globals have non-zero upper bits, which makes direct references
166 // require a 64-bit immediate. So we can't let the linker relax the
167 // relocation to a 32-bit RIP-relative direct reference.
168 if (AllowTaggedGlobals && GV && !isa<Function>(GV))
170 return X86II::MO_GOTPCREL;
171 }
172
173 if (isTargetDarwin()) {
177 }
178
179 // 32-bit ELF references GlobalAddress directly in static relocation model.
180 // We cannot use MO_GOT because EBX may not be set up.
182 return X86II::MO_NO_FLAG;
183 return X86II::MO_GOT;
184}
185
186unsigned char
189}
190
191unsigned char
193 const Module &M) const {
194 if (TM.shouldAssumeDSOLocal(GV))
195 return X86II::MO_NO_FLAG;
196
197 // Functions on COFF can be non-DSO local for three reasons:
198 // - They are intrinsic functions (!GV)
199 // - They are marked dllimport
200 // - They are extern_weak, and a stub is needed
201 if (isTargetCOFF()) {
202 if (!GV)
203 return X86II::MO_NO_FLAG;
204 if (GV->hasDLLImportStorageClass())
205 return X86II::MO_DLLIMPORT;
206 return X86II::MO_COFFSTUB;
207 }
208
209 const Function *F = dyn_cast_or_null<Function>(GV);
210
211 if (isTargetELF()) {
212 if (is64Bit() && F && (CallingConv::X86_RegCall == F->getCallingConv()))
213 // According to psABI, PLT stub clobbers XMM8-XMM15.
214 // In Regcall calling convention those registers are used for passing
215 // parameters. Thus we need to prevent lazy binding in Regcall.
216 return X86II::MO_GOTPCREL;
217 // If PLT must be avoided then the call should be via GOTPCREL.
218 if (((F && F->hasFnAttribute(Attribute::NonLazyBind)) ||
219 (!F && M.getRtLibUseGOT())) &&
220 is64Bit())
221 return X86II::MO_GOTPCREL;
222 // Reference ExternalSymbol directly in static relocation model.
223 if (!is64Bit() && !GV && TM.getRelocationModel() == Reloc::Static)
224 return X86II::MO_NO_FLAG;
225 return X86II::MO_PLT;
226 }
227
228 if (is64Bit()) {
229 if (F && F->hasFnAttribute(Attribute::NonLazyBind))
230 // If the function is marked as non-lazy, generate an indirect call
231 // which loads from the GOT directly. This avoids runtime overhead
232 // at the cost of eager binding (and one extra byte of encoding).
233 return X86II::MO_GOTPCREL;
234 return X86II::MO_NO_FLAG;
235 }
236
237 return X86II::MO_NO_FLAG;
238}
239
240/// Return true if the subtarget allows calls to immediate address.
242 // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32
243 // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does,
244 // the following check for Win32 should be removed.
245 if (Is64Bit || isTargetWin32())
246 return false;
247 return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
248}
249
250void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
251 StringRef FS) {
252 if (CPU.empty())
253 CPU = "generic";
254
255 if (TuneCPU.empty())
256 TuneCPU = "i586"; // FIXME: "generic" is more modern than llc tests expect.
257
258 std::string FullFS = X86_MC::ParseX86Triple(TargetTriple);
259 assert(!FullFS.empty() && "Failed to parse X86 triple");
260
261 if (!FS.empty())
262 FullFS = (Twine(FullFS) + "," + FS).str();
263
264 // Attach EVEX512 feature when we have AVX512 features with a default CPU.
265 // "pentium4" is default CPU for 32-bit targets.
266 // "x86-64" is default CPU for 64-bit targets.
267 if (CPU == "generic" || CPU == "pentium4" || CPU == "x86-64") {
268 size_t posNoEVEX512 = FS.rfind("-evex512");
269 // Make sure we won't be cheated by "-avx512fp16".
270 size_t posNoAVX512F =
271 FS.ends_with("-avx512f") ? FS.size() - 8 : FS.rfind("-avx512f,");
272 size_t posEVEX512 = FS.rfind("+evex512");
273 // Any AVX512XXX will enable AVX512F.
274 size_t posAVX512F = FS.rfind("+avx512");
275
276 if (posAVX512F != StringRef::npos &&
277 (posNoAVX512F == StringRef::npos || posNoAVX512F < posAVX512F))
278 if (posEVEX512 == StringRef::npos && posNoEVEX512 == StringRef::npos)
279 FullFS += ",+evex512";
280 }
281
282 // Disable 64-bit only features in non-64-bit mode.
283 StringRef FeaturesIn64BitOnly[] = {
284 "egpr", "push2pop2", "ppx", "ndd", "ccmp", "nf", "cf", "zu", "uintr"};
285 if (FullFS.find("-64bit-mode") != std::string::npos)
286 for (StringRef F : FeaturesIn64BitOnly)
287 FullFS += ",-" + F.str();
288
289 // Parse features string and set the CPU.
290 ParseSubtargetFeatures(CPU, TuneCPU, FullFS);
291
292 // All CPUs that implement SSE4.2 or SSE4A support unaligned accesses of
293 // 16-bytes and under that are reasonably fast. These features were
294 // introduced with Intel's Nehalem/Silvermont and AMD's Family10h
295 // micro-architectures respectively.
296 if (hasSSE42() || hasSSE4A())
297 IsUnalignedMem16Slow = false;
298
299 LLVM_DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
300 << ", MMX " << HasMMX << ", 64bit " << HasX86_64 << "\n");
301 if (Is64Bit && !HasX86_64)
302 reportFatalUsageError("64-bit code requested on a subtarget that doesn't "
303 "support it!");
304
305 // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD, and for all
306 // 64-bit targets. On Solaris (32-bit), stack alignment is 4 bytes
307 // following the i386 psABI, while on Illumos it is always 16 bytes.
308 if (StackAlignOverride)
309 stackAlignment = *StackAlignOverride;
310 else if (isTargetDarwin() || isTargetLinux() || isTargetKFreeBSD() || Is64Bit)
311 stackAlignment = Align(16);
312
313 // Consume the vector width attribute or apply any target specific limit.
314 if (PreferVectorWidthOverride)
315 PreferVectorWidth = PreferVectorWidthOverride;
316 else if (Prefer128Bit)
317 PreferVectorWidth = 128;
318 else if (Prefer256Bit)
319 PreferVectorWidth = 256;
320}
321
322X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
323 StringRef TuneCPU,
324 StringRef FS) {
325 initSubtargetFeatures(CPU, TuneCPU, FS);
326 return *this;
327}
328
330 StringRef FS, const X86TargetMachine &TM,
331 MaybeAlign StackAlignOverride,
332 unsigned PreferVectorWidthOverride,
333 unsigned RequiredVectorWidth)
334 : X86GenSubtargetInfo(TT, CPU, TuneCPU, FS),
335 PICStyle(PICStyles::Style::None), TM(TM), TargetTriple(TT),
336 StackAlignOverride(StackAlignOverride),
337 PreferVectorWidthOverride(PreferVectorWidthOverride),
338 RequiredVectorWidth(RequiredVectorWidth),
339 InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
340 TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
341 // Determine the PICStyle based on the target selected.
342 if (!isPositionIndependent() || TM.getCodeModel() == CodeModel::Large)
343 // With the large code model, None forces all memory accesses to be indirect
344 // rather than RIP-relative.
346 else if (is64Bit())
348 else if (isTargetCOFF())
350 else if (isTargetDarwin())
352 else if (isTargetELF())
354
355 CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering()));
356 Legalizer.reset(new X86LegalizerInfo(*this, TM));
357
358 auto *RBI = new X86RegisterBankInfo(*getRegisterInfo());
359 RegBankInfo.reset(RBI);
360 InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI));
361}
362
363// Define the virtual destructor out-of-line for build efficiency.
365
367 return CallLoweringInfo.get();
368}
369
371 return InstSelector.get();
372}
373
375 return Legalizer.get();
376}
377
379 return RegBankInfo.get();
380}
381
383 return canUseCMOV() && X86EarlyIfConv;
384}
385
387 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
388 Mutations.push_back(createX86MacroFusionDAGMutation());
389}
390
392 return TM.isPositionIndependent();
393}
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:55
#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.
static cl::opt< bool > X86EarlyIfConv("x86-early-ifcvt", cl::Hidden, cl::desc("Enable early if-conversion on X86"))
bool hasDLLImportStorageClass() const
Definition: GlobalValue.h:280
bool isDeclarationForLinker() const
Definition: GlobalValue.h:625
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:663
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:432
bool hasCommonLinkage() const
Definition: GlobalValue.h:534
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Holds all the information related to register banks.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
static constexpr size_t npos
Definition: StringRef.h:57
bool isPositionIndependent() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool isLargeGlobalValue(const GlobalValue *GV) const
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
This class provides the information for the target register banks.
bool enableEarlyIfConversion() const override
~X86Subtarget() override
bool isOSWindows() const
Definition: X86Subtarget.h:325
bool isTargetKFreeBSD() const
Definition: X86Subtarget.h:295
bool hasSSE42() const
Definition: X86Subtarget.h:194
InstructionSelector * getInstructionSelector() const override
const X86TargetLowering * getTargetLowering() const override
Definition: X86Subtarget.h:118
bool canUseCMOV() const
Definition: X86Subtarget.h:188
bool isLegalToCallImmediateAddr() const
Return true if the subtarget allows calls to immediate address.
bool isTargetDarwin() const
Definition: X86Subtarget.h:284
const RegisterBankInfo * getRegBankInfo() const override
bool isTargetCOFF() const
Definition: X86Subtarget.h:291
bool isTargetELF() const
Definition: X86Subtarget.h:290
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
Definition: X86Subtarget.h:132
void setPICStyle(PICStyles::Style Style)
Definition: X86Subtarget.h:179
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 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 isTargetWin32() const
Definition: X86Subtarget.h:331
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
bool isTargetLinux() const
Definition: X86Subtarget.h:294
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
Definition: CallingConv.h:203
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
Definition: X86BaseInfo.h:391
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
Definition: X86BaseInfo.h:381
@ MO_DARWIN_NONLAZY_PIC_BASE
MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...
Definition: X86BaseInfo.h:468
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
Definition: X86BaseInfo.h:488
@ MO_DARWIN_NONLAZY
MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...
Definition: X86BaseInfo.h:464
@ MO_GOT
MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...
Definition: X86BaseInfo.h:376
@ MO_ABS8
MO_ABS8 - On a symbol operand this indicates that the symbol is known to be an absolute symbol in ran...
Definition: X86BaseInfo.h:484
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
Definition: X86BaseInfo.h:396
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
Definition: X86BaseInfo.h:363
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
Definition: X86BaseInfo.h:460
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
Definition: X86BaseInfo.h:371
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
Definition: X86BaseInfo.h:387
std::string ParseX86Triple(const Triple &TT)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::unique_ptr< ScheduleDAGMutation > createX86MacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createX86MacroFusionDAGMutation()); to X86TargetMachine::c...
@ None
Definition: CodeGenData.h:107
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:180
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:117