LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMSubtarget.cpp
Go to the documentation of this file.
1 //===-- ARMSubtarget.cpp - ARM Subtarget Information ----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ARM specific subclass of TargetSubtargetInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARMSubtarget.h"
15 #include "ARMBaseInstrInfo.h"
16 #include "ARMBaseRegisterInfo.h"
17 #include "llvm/IR/Attributes.h"
18 #include "llvm/IR/GlobalValue.h"
19 #include "llvm/IR/Function.h"
23 
24 #define GET_SUBTARGETINFO_TARGET_DESC
25 #define GET_SUBTARGETINFO_CTOR
26 #include "ARMGenSubtargetInfo.inc"
27 
28 using namespace llvm;
29 
30 static cl::opt<bool>
31 ReserveR9("arm-reserve-r9", cl::Hidden,
32  cl::desc("Reserve R9, making it unavailable as GPR"));
33 
34 static cl::opt<bool>
35 ArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden);
36 
37 static cl::opt<bool>
38 UseFusedMulOps("arm-use-mulops",
39  cl::init(true), cl::Hidden);
40 
41 enum AlignMode {
45 };
46 
47 static cl::opt<AlignMode>
48 Align(cl::desc("Load/store alignment support"),
50  cl::values(
51  clEnumValN(DefaultAlign, "arm-default-align",
52  "Generate unaligned accesses only on hardware/OS "
53  "combinations that are known to support them"),
54  clEnumValN(StrictAlign, "arm-strict-align",
55  "Disallow all unaligned memory accesses"),
56  clEnumValN(NoStrictAlign, "arm-no-strict-align",
57  "Allow unaligned memory accesses"),
58  clEnumValEnd));
59 
60 enum ITMode {
64 };
65 
66 static cl::opt<ITMode>
67 IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT),
69  cl::values(clEnumValN(DefaultIT, "arm-default-it",
70  "Generate IT block based on arch"),
71  clEnumValN(RestrictedIT, "arm-restrict-it",
72  "Disallow deprecated IT based on ARMv8"),
73  clEnumValN(NoRestrictedIT, "arm-no-restrict-it",
74  "Allow IT blocks based on ARMv7"),
75  clEnumValEnd));
76 
77 ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
78  const std::string &FS, const TargetOptions &Options)
79  : ARMGenSubtargetInfo(TT, CPU, FS)
80  , ARMProcFamily(Others)
81  , ARMProcClass(None)
82  , stackAlignment(4)
83  , CPUString(CPU)
84  , TargetTriple(TT)
85  , Options(Options)
86  , TargetABI(ARM_ABI_APCS) {
87  initializeEnvironment();
88  resetSubtargetFeatures(CPU, FS);
89 }
90 
91 void ARMSubtarget::initializeEnvironment() {
92  HasV4TOps = false;
93  HasV5TOps = false;
94  HasV5TEOps = false;
95  HasV6Ops = false;
96  HasV6MOps = false;
97  HasV6T2Ops = false;
98  HasV7Ops = false;
99  HasV8Ops = false;
100  HasVFPv2 = false;
101  HasVFPv3 = false;
102  HasVFPv4 = false;
103  HasFPARMv8 = false;
104  HasNEON = false;
107  SlowFPVMLx = false;
108  HasVMLxForwarding = false;
109  SlowFPBrcc = false;
110  InThumbMode = false;
111  HasThumb2 = false;
112  NoARM = false;
113  PostRAScheduler = false;
115  UseMovt = false;
116  SupportsTailCall = false;
117  HasFP16 = false;
118  HasD16 = false;
119  HasHardwareDivide = false;
120  HasHardwareDivideInARM = false;
121  HasT2ExtractPack = false;
122  HasDataBarrier = false;
123  Pref32BitThumb = false;
124  AvoidCPSRPartialUpdate = false;
125  AvoidMOVsShifterOperand = false;
126  HasRAS = false;
127  HasMPExtension = false;
128  HasVirtualization = false;
129  FPOnlySP = false;
130  HasPerfMon = false;
131  HasTrustZone = false;
132  HasCrypto = false;
133  HasCRC = false;
134  AllowsUnalignedMem = false;
135  Thumb2DSP = false;
136  UseNaClTrap = false;
137  UnsafeFPMath = false;
138 }
139 
141  AttributeSet FnAttrs = MF->getFunction()->getAttributes();
142  Attribute CPUAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex,
143  "target-cpu");
144  Attribute FSAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex,
145  "target-features");
146  std::string CPU =
147  !CPUAttr.hasAttribute(Attribute::None) ?CPUAttr.getValueAsString() : "";
148  std::string FS =
149  !FSAttr.hasAttribute(Attribute::None) ? FSAttr.getValueAsString() : "";
150  if (!FS.empty()) {
151  initializeEnvironment();
152  resetSubtargetFeatures(CPU, FS);
153  }
154 }
155 
157  if (CPUString.empty()) {
158  if (isTargetIOS() && TargetTriple.getArchName().endswith("v7s"))
159  // Default to the Swift CPU when targeting armv7s/thumbv7s.
160  CPUString = "swift";
161  else
162  CPUString = "generic";
163  }
164 
165  // Insert the architecture feature derived from the target triple into the
166  // feature string. This is important for setting features that are implied
167  // based on the architecture version.
168  std::string ArchFS = ARM_MC::ParseARMTriple(TargetTriple.getTriple(),
169  CPUString);
170  if (!FS.empty()) {
171  if (!ArchFS.empty())
172  ArchFS = ArchFS + "," + FS.str();
173  else
174  ArchFS = FS;
175  }
177 
178  // Thumb2 implies at least V6T2. FIXME: Fix tests to explicitly specify a
179  // ARM version or CPU and then remove this.
180  if (!HasV6T2Ops && hasThumb2())
182 
183  // Keep a pointer to static instruction cost data for the specified CPU.
184  SchedModel = getSchedModelForCPU(CPUString);
185 
186  // Initialize scheduling itinerary for the specified CPU.
187  InstrItins = getInstrItineraryForCPU(CPUString);
188 
189  if ((TargetTriple.getTriple().find("eabi") != std::string::npos) ||
190  (isTargetIOS() && isMClass()))
191  // FIXME: We might want to separate AAPCS and EABI. Some systems, e.g.
192  // Darwin-EABI conforms to AACPS but not the rest of EABI.
194 
195  if (isAAPCS_ABI())
196  stackAlignment = 8;
197 
199 
200  if (!isTargetIOS()) {
202  } else {
205  }
206 
207  if (!isThumb() || hasThumb2())
208  PostRAScheduler = true;
209 
210  switch (Align) {
211  case DefaultAlign:
212  // Assume pre-ARMv6 doesn't support unaligned accesses.
213  //
214  // ARMv6 may or may not support unaligned accesses depending on the
215  // SCTLR.U bit, which is architecture-specific. We assume ARMv6
216  // Darwin targets support unaligned accesses, and others don't.
217  //
218  // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
219  // which raises an alignment fault on unaligned accesses. Linux
220  // defaults this bit to 0 and handles it as a system-wide (not
221  // per-process) setting. It is therefore safe to assume that ARMv7+
222  // Linux targets support unaligned accesses. The same goes for NaCl.
223  //
224  // The above behavior is consistent with GCC.
226  (hasV7Ops() && (isTargetLinux() || isTargetNaCl())) ||
227  (hasV6Ops() && isTargetDarwin()));
228  break;
229  case StrictAlign:
230  AllowsUnalignedMem = false;
231  break;
232  case NoStrictAlign:
233  AllowsUnalignedMem = true;
234  break;
235  }
236 
237  switch (IT) {
238  case DefaultIT:
239  RestrictIT = hasV8Ops() ? true : false;
240  break;
241  case RestrictedIT:
242  RestrictIT = true;
243  break;
244  case NoRestrictedIT:
245  RestrictIT = false;
246  break;
247  }
248 
249  // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
250  uint64_t Bits = getFeatureBits();
251  if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters
254 }
255 
256 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
257 bool
259  Reloc::Model RelocM) const {
260  if (RelocM == Reloc::Static)
261  return false;
262 
263  // Materializable GVs (in JIT lazy compilation mode) do not require an extra
264  // load from stub.
265  bool isDecl = GV->hasAvailableExternallyLinkage();
266  if (GV->isDeclaration() && !GV->isMaterializable())
267  isDecl = true;
268 
269  if (!isTargetDarwin()) {
270  // Extra load is needed for all externally visible.
271  if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
272  return false;
273  return true;
274  } else {
275  if (RelocM == Reloc::PIC_) {
276  // If this is a strong reference to a definition, it is definitely not
277  // through a stub.
278  if (!isDecl && !GV->isWeakForLinker())
279  return false;
280 
281  // Unless we have a symbol with hidden visibility, we have to go through a
282  // normal $non_lazy_ptr stub because this symbol might be resolved late.
283  if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
284  return true;
285 
286  // If symbol visibility is hidden, we have a stub for common symbol
287  // references and external declarations.
288  if (isDecl || GV->hasCommonLinkage())
289  // Hidden $non_lazy_ptr reference.
290  return true;
291 
292  return false;
293  } else {
294  // If this is a strong reference to a definition, it is definitely not
295  // through a stub.
296  if (!isDecl && !GV->isWeakForLinker())
297  return false;
298 
299  // Unless we have a symbol with hidden visibility, we have to go through a
300  // normal $non_lazy_ptr stub because this symbol might be resolved late.
301  if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
302  return true;
303  }
304  }
305 
306  return false;
307 }
308 
311 }
312 
314  return getTargetTriple().getOS() == Triple::IOS &&
316 }
317 
319  CodeGenOpt::Level OptLevel,
321  RegClassVector& CriticalPathRCs) const {
323  return PostRAScheduler && OptLevel >= CodeGenOpt::Default;
324 }
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:178
unsigned stackAlignment
Definition: ARMSubtarget.h:196
Triple TargetTriple
TargetTriple - What processor and OS we're targeting.
Definition: ARMSubtarget.h:202
static cl::opt< bool > ArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden)
unsigned getMispredictionPenalty() const
unsigned MispredictPenalty
Definition: MCSchedule.h:174
#define clEnumValEnd
Definition: CommandLine.h:472
const MCSchedModel * SchedModel
SchedModel - Processor specific instruction costs.
Definition: ARMSubtarget.h:205
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:217
ValuesClass< DataType > END_WITH_NULL values(const char *Arg, DataType Val, const char *Desc,...)
Definition: CommandLine.h:510
bool hasAvailableExternallyLinkage() const
Definition: GlobalValue.h:195
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:181
bool hasV6Ops() const
Definition: ARMSubtarget.h:247
const Function * getFunction() const
bool HasHardwareDivideInARM
HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode.
Definition: ARMSubtarget.h:122
bool hasV6T2Ops() const
Definition: ARMSubtarget.h:249
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:134
bool hasV8Ops() const
Definition: ARMSubtarget.h:251
bool hasCommonLinkage() const
Definition: GlobalValue.h:215
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7"), clEnumValEnd))
bool hasThumb2() const
Definition: ARMSubtarget.h:322
bool isTargetDarwin() const
Definition: ARMSubtarget.h:303
This file contains the simple types necessary to represent the attributes associated with functions a...
bool HasThumb2
HasThumb2 - True if Thumb2 instructions are supported.
Definition: ARMSubtarget.h:90
No attributes have been set.
Definition: Attributes.h:66
bool UnsafeFPMath
Target machine allowed unsafe FP math (such as use of NEON fp)
Definition: ARMSubtarget.h:192
bool isThumb() const
Definition: ARMSubtarget.h:319
bool hasV7Ops() const
Definition: ARMSubtarget.h:250
const Triple & getTargetTriple() const
Definition: ARMSubtarget.h:300
bool NoARM
NoARM - True if subtarget does not support ARM mode execution.
Definition: ARMSubtarget.h:93
bool isMaterializable() const
Definition: Globals.cpp:30
virtual void resetSubtargetFeatures(const MachineFunction *MF)
Reset the features for the ARM target.
static bool isWeakForLinker(LinkageTypes Linkage)
Definition: GlobalValue.h:183
bool isTargetIOS() const
Definition: ARMSubtarget.h:302
bool HasCRC
HasCRC - if true, processor supports CRC instructions.
Definition: ARMSubtarget.h:173
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
ARMSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, const TargetOptions &Options)
const std::string & getTriple() const
Definition: Triple.h:223
static cl::opt< bool > UseFusedMulOps("arm-use-mulops", cl::init(true), cl::Hidden)
bool isMClass() const
Definition: ARMSubtarget.h:323
bool hasHiddenVisibility() const
Definition: GlobalValue.h:89
bool HasCrypto
HasCrypto - if true, processor supports Cryptography extensions.
Definition: ARMSubtarget.h:170
enum llvm::ARMSubtarget::@174 TargetABI
bool hasSinCos() const
std::string ParseARMTriple(StringRef TT, StringRef CPU)
bool HasTrustZone
HasTrustZone - if true, processor supports TrustZone security extensions.
Definition: ARMSubtarget.h:167
AlignMode
bool InThumbMode
InThumbMode - True if compiling for Thumb, false for ARM.
Definition: ARMSubtarget.h:87
bool isTargetNaCl() const
Definition: ARMSubtarget.h:304
void ParseSubtargetFeatures(StringRef CPU, StringRef FS)
bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const
GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, TargetSubtargetInfo::AntiDepBreakMode &Mode, RegClassVector &CriticalPathRCs) const
enablePostRAScheduler - True at 'More' optimization.
bool UseNaClTrap
NaCl TRAP instruction is generated instead of the regular TRAP.
Definition: ARMSubtarget.h:189
AttributeSet getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:170
const TargetOptions & Options
Options passed via command line that could influence the target.
Definition: ARMSubtarget.h:211
static cl::opt< bool > ReserveR9("arm-reserve-r9", cl::Hidden, cl::desc("Reserve R9, making it unavailable as GPR"))
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
bool isOSVersionLT(unsigned Major, unsigned Minor=0, unsigned Micro=0) const
Definition: Triple.h:270
bool IsR9Reserved
IsR9Reserved - True if R9 is a not available as general purpose register.
Definition: ARMSubtarget.h:99
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:471
bool isDeclaration() const
Definition: Globals.cpp:66
bool isTargetLinux() const
Definition: ARMSubtarget.h:305
StringRef getArchName() const
Definition: Triple.cpp:486
InstrItineraryData InstrItins
Selected instruction itineraries (one entry per itinerary class.)
Definition: ARMSubtarget.h:208
bool UseNEONForSinglePrecisionFP
Definition: ARMSubtarget.h:69
bool PostRAScheduler
PostRAScheduler - True if using post-register-allocation scheduler.
Definition: ARMSubtarget.h:96
bool hasLocalLinkage() const
Definition: GlobalValue.h:211
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
Definition: Attributes.cpp:847
StringRef getValueAsString() const
Return the attribute's value as a string. This requires the attribute to be a string attribute...
Definition: Attributes.cpp:127
bool SlowFPBrcc
SlowFPBrcc - True if floating point compare + branch is slow.
Definition: ARMSubtarget.h:84
bool isAAPCS_ABI() const
Definition: ARMSubtarget.h:317
std::string CPUString
CPUString - String name of used CPU.
Definition: ARMSubtarget.h:199
ITMode
bool HasHardwareDivide
HasHardwareDivide - True if subtarget supports [su]div.
Definition: ARMSubtarget.h:119
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110