2012-02-18 20:03:15 +08:00
|
|
|
//===-- ARMSubtarget.cpp - ARM Subtarget Information ----------------------===//
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2011-07-02 05:01:15 +08:00
|
|
|
// This file implements the ARM specific subclass of TargetSubtargetInfo.
|
2007-01-19 15:51:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "ARMSubtarget.h"
|
2012-09-18 11:18:56 +08:00
|
|
|
#include "ARMBaseInstrInfo.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "ARMBaseRegisterInfo.h"
|
2013-02-16 06:41:25 +08:00
|
|
|
#include "llvm/IR/Attributes.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
2014-01-07 19:48:04 +08:00
|
|
|
#include "llvm/IR/GlobalValue.h"
|
2009-06-23 05:01:46 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2013-03-22 02:47:47 +08:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2011-07-02 04:45:01 +08:00
|
|
|
|
2014-04-22 10:03:14 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 06:55:11 +08:00
|
|
|
#define DEBUG_TYPE "arm-subtarget"
|
|
|
|
|
2011-07-02 04:45:01 +08:00
|
|
|
#define GET_SUBTARGETINFO_TARGET_DESC
|
2011-07-08 09:53:10 +08:00
|
|
|
#define GET_SUBTARGETINFO_CTOR
|
2011-07-02 06:36:09 +08:00
|
|
|
#include "ARMGenSubtargetInfo.inc"
|
2011-07-02 04:45:01 +08:00
|
|
|
|
2009-06-23 05:01:46 +08:00
|
|
|
static cl::opt<bool>
|
|
|
|
ReserveR9("arm-reserve-r9", cl::Hidden,
|
|
|
|
cl::desc("Reserve R9, making it unavailable as GPR"));
|
|
|
|
|
2009-11-24 08:44:37 +08:00
|
|
|
static cl::opt<bool>
|
2013-08-16 04:54:38 +08:00
|
|
|
ArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden);
|
2009-11-24 08:44:37 +08:00
|
|
|
|
2012-09-30 05:43:49 +08:00
|
|
|
static cl::opt<bool>
|
|
|
|
UseFusedMulOps("arm-use-mulops",
|
|
|
|
cl::init(true), cl::Hidden);
|
|
|
|
|
2013-05-18 07:49:01 +08:00
|
|
|
enum AlignMode {
|
|
|
|
DefaultAlign,
|
|
|
|
StrictAlign,
|
|
|
|
NoStrictAlign
|
|
|
|
};
|
|
|
|
|
|
|
|
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));
|
2010-09-28 12:09:35 +08:00
|
|
|
|
2013-11-14 02:29:49 +08:00
|
|
|
enum ITMode {
|
|
|
|
DefaultIT,
|
|
|
|
RestrictedIT,
|
|
|
|
NoRestrictedIT
|
|
|
|
};
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
2014-06-13 08:20:35 +08:00
|
|
|
static std::string computeDataLayout(ARMSubtarget &ST) {
|
|
|
|
std::string Ret = "";
|
|
|
|
|
|
|
|
if (ST.isLittle())
|
|
|
|
// Little endian.
|
|
|
|
Ret += "e";
|
|
|
|
else
|
|
|
|
// Big endian.
|
|
|
|
Ret += "E";
|
|
|
|
|
|
|
|
Ret += DataLayout::getManglingComponent(ST.getTargetTriple());
|
|
|
|
|
|
|
|
// Pointers are 32 bits and aligned to 32 bits.
|
|
|
|
Ret += "-p:32:32";
|
|
|
|
|
|
|
|
// On thumb, i16,i18 and i1 have natural aligment requirements, but we try to
|
|
|
|
// align to 32.
|
|
|
|
if (ST.isThumb())
|
|
|
|
Ret += "-i1:8:32-i8:8:32-i16:16:32";
|
|
|
|
|
|
|
|
// ABIs other than APCS have 64 bit integers with natural alignment.
|
|
|
|
if (!ST.isAPCS_ABI())
|
|
|
|
Ret += "-i64:64";
|
|
|
|
|
|
|
|
// We have 64 bits floats. The APCS ABI requires them to be aligned to 32
|
|
|
|
// bits, others to 64 bits. We always try to align to 64 bits.
|
|
|
|
if (ST.isAPCS_ABI())
|
|
|
|
Ret += "-f64:32:64";
|
|
|
|
|
|
|
|
// We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
|
|
|
|
// to 64. We always ty to give them natural alignment.
|
|
|
|
if (ST.isAPCS_ABI())
|
|
|
|
Ret += "-v64:32:64-v128:32:128";
|
|
|
|
else
|
|
|
|
Ret += "-v128:64:128";
|
|
|
|
|
|
|
|
// On thumb and APCS, only try to align aggregates to 32 bits (the default is
|
|
|
|
// 64 bits).
|
|
|
|
if (ST.isThumb() || ST.isAPCS_ABI())
|
|
|
|
Ret += "-a:0:32";
|
|
|
|
|
|
|
|
// Integer registers are 32 bits.
|
|
|
|
Ret += "-n32";
|
|
|
|
|
|
|
|
// The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit
|
|
|
|
// aligned everywhere else.
|
|
|
|
if (ST.isTargetNaCl())
|
|
|
|
Ret += "-S128";
|
|
|
|
else if (ST.isAAPCS_ABI())
|
|
|
|
Ret += "-S64";
|
|
|
|
else
|
|
|
|
Ret += "-S32";
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// initializeSubtargetDependencies - Initializes using a CPU and feature string
|
|
|
|
/// so that we can use initializer lists for subtarget initialization.
|
|
|
|
ARMSubtarget &ARMSubtarget::initializeSubtargetDependencies(StringRef CPU,
|
|
|
|
StringRef FS) {
|
2013-02-16 09:36:26 +08:00
|
|
|
initializeEnvironment();
|
2013-02-16 06:41:25 +08:00
|
|
|
resetSubtargetFeatures(CPU, FS);
|
2014-06-13 08:20:35 +08:00
|
|
|
return *this;
|
2013-02-16 06:41:25 +08:00
|
|
|
}
|
|
|
|
|
2014-06-13 08:20:35 +08:00
|
|
|
ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
|
|
|
|
const std::string &FS, bool IsLittle,
|
|
|
|
const TargetOptions &Options)
|
|
|
|
: ARMGenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
|
|
|
|
ARMProcClass(None), stackAlignment(4), CPUString(CPU), IsLittle(IsLittle),
|
|
|
|
TargetTriple(TT), Options(Options), TargetABI(ARM_ABI_UNKNOWN),
|
|
|
|
DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS))) {}
|
|
|
|
|
2013-02-16 09:36:26 +08:00
|
|
|
void ARMSubtarget::initializeEnvironment() {
|
|
|
|
HasV4TOps = false;
|
|
|
|
HasV5TOps = false;
|
|
|
|
HasV5TEOps = false;
|
|
|
|
HasV6Ops = false;
|
2013-10-08 00:55:23 +08:00
|
|
|
HasV6MOps = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasV6T2Ops = false;
|
|
|
|
HasV7Ops = false;
|
2013-06-27 00:58:26 +08:00
|
|
|
HasV8Ops = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasVFPv2 = false;
|
|
|
|
HasVFPv3 = false;
|
|
|
|
HasVFPv4 = false;
|
2013-09-13 21:46:57 +08:00
|
|
|
HasFPARMv8 = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
HasNEON = false;
|
2013-12-02 22:46:26 +08:00
|
|
|
MinSize = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
UseNEONForSinglePrecisionFP = false;
|
|
|
|
UseMulOps = UseFusedMulOps;
|
|
|
|
SlowFPVMLx = false;
|
|
|
|
HasVMLxForwarding = false;
|
|
|
|
SlowFPBrcc = false;
|
|
|
|
InThumbMode = false;
|
|
|
|
HasThumb2 = false;
|
|
|
|
NoARM = false;
|
|
|
|
PostRAScheduler = false;
|
|
|
|
IsR9Reserved = ReserveR9;
|
|
|
|
UseMovt = false;
|
|
|
|
SupportsTailCall = false;
|
|
|
|
HasFP16 = false;
|
|
|
|
HasD16 = false;
|
|
|
|
HasHardwareDivide = false;
|
|
|
|
HasHardwareDivideInARM = false;
|
|
|
|
HasT2ExtractPack = false;
|
|
|
|
HasDataBarrier = false;
|
|
|
|
Pref32BitThumb = false;
|
|
|
|
AvoidCPSRPartialUpdate = false;
|
|
|
|
AvoidMOVsShifterOperand = false;
|
|
|
|
HasRAS = false;
|
|
|
|
HasMPExtension = false;
|
2013-11-01 21:27:35 +08:00
|
|
|
HasVirtualization = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
FPOnlySP = false;
|
2013-05-24 03:11:14 +08:00
|
|
|
HasPerfMon = false;
|
2013-04-10 20:08:35 +08:00
|
|
|
HasTrustZone = false;
|
2013-09-19 19:59:01 +08:00
|
|
|
HasCrypto = false;
|
2013-10-30 00:54:52 +08:00
|
|
|
HasCRC = false;
|
2014-04-01 21:22:02 +08:00
|
|
|
HasZeroCycleZeroing = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
AllowsUnalignedMem = false;
|
|
|
|
Thumb2DSP = false;
|
|
|
|
UseNaClTrap = false;
|
2013-03-22 02:47:47 +08:00
|
|
|
UnsafeFPMath = false;
|
2013-02-16 09:36:26 +08:00
|
|
|
}
|
|
|
|
|
2013-02-16 06:41:25 +08:00
|
|
|
void ARMSubtarget::resetSubtargetFeatures(const MachineFunction *MF) {
|
|
|
|
AttributeSet FnAttrs = MF->getFunction()->getAttributes();
|
|
|
|
Attribute CPUAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex,
|
|
|
|
"target-cpu");
|
|
|
|
Attribute FSAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex,
|
|
|
|
"target-features");
|
|
|
|
std::string CPU =
|
|
|
|
!CPUAttr.hasAttribute(Attribute::None) ?CPUAttr.getValueAsString() : "";
|
|
|
|
std::string FS =
|
|
|
|
!FSAttr.hasAttribute(Attribute::None) ? FSAttr.getValueAsString() : "";
|
2013-02-16 09:36:26 +08:00
|
|
|
if (!FS.empty()) {
|
|
|
|
initializeEnvironment();
|
2013-02-16 06:41:25 +08:00
|
|
|
resetSubtargetFeatures(CPU, FS);
|
2013-02-16 09:36:26 +08:00
|
|
|
}
|
2013-12-02 22:46:26 +08:00
|
|
|
|
|
|
|
MinSize =
|
|
|
|
FnAttrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::MinSize);
|
2013-02-16 06:41:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
|
2013-09-03 01:09:01 +08:00
|
|
|
if (CPUString.empty()) {
|
|
|
|
if (isTargetIOS() && TargetTriple.getArchName().endswith("v7s"))
|
|
|
|
// Default to the Swift CPU when targeting armv7s/thumbv7s.
|
|
|
|
CPUString = "swift";
|
|
|
|
else
|
|
|
|
CPUString = "generic";
|
|
|
|
}
|
2009-03-08 12:02:49 +08:00
|
|
|
|
2011-06-30 10:12:44 +08:00
|
|
|
// Insert the architecture feature derived from the target triple into the
|
|
|
|
// feature string. This is important for setting features that are implied
|
|
|
|
// based on the architecture version.
|
2013-02-16 06:41:25 +08:00
|
|
|
std::string ArchFS = ARM_MC::ParseARMTriple(TargetTriple.getTriple(),
|
|
|
|
CPUString);
|
2011-07-07 08:08:19 +08:00
|
|
|
if (!FS.empty()) {
|
|
|
|
if (!ArchFS.empty())
|
2013-02-16 06:41:25 +08:00
|
|
|
ArchFS = ArchFS + "," + FS.str();
|
2011-07-07 08:08:19 +08:00
|
|
|
else
|
|
|
|
ArchFS = FS;
|
|
|
|
}
|
2011-07-07 15:07:08 +08:00
|
|
|
ParseSubtargetFeatures(CPUString, ArchFS);
|
2011-07-07 08:08:19 +08:00
|
|
|
|
2013-12-13 19:16:00 +08:00
|
|
|
// FIXME: This used enable V6T2 support implicitly for Thumb2 mode.
|
|
|
|
// Assert this for now to make the change obvious.
|
|
|
|
assert(hasV6T2Ops() || !hasThumb2());
|
2010-11-10 06:50:47 +08:00
|
|
|
|
2012-08-08 10:44:16 +08:00
|
|
|
// Keep a pointer to static instruction cost data for the specified CPU.
|
|
|
|
SchedModel = getSchedModelForCPU(CPUString);
|
|
|
|
|
2011-07-02 04:45:01 +08:00
|
|
|
// Initialize scheduling itinerary for the specified CPU.
|
|
|
|
InstrItins = getInstrItineraryForCPU(CPUString);
|
|
|
|
|
2014-01-02 21:40:08 +08:00
|
|
|
if (TargetABI == ARM_ABI_UNKNOWN) {
|
|
|
|
switch (TargetTriple.getEnvironment()) {
|
|
|
|
case Triple::Android:
|
|
|
|
case Triple::EABI:
|
|
|
|
case Triple::EABIHF:
|
|
|
|
case Triple::GNUEABI:
|
|
|
|
case Triple::GNUEABIHF:
|
2013-12-15 08:12:52 +08:00
|
|
|
TargetABI = ARM_ABI_AAPCS;
|
2014-01-02 21:40:08 +08:00
|
|
|
break;
|
|
|
|
default:
|
2014-03-07 04:47:11 +08:00
|
|
|
if ((isTargetIOS() && isMClass()) ||
|
|
|
|
(TargetTriple.isOSBinFormatMachO() &&
|
|
|
|
TargetTriple.getOS() == Triple::UnknownOS))
|
2014-01-02 21:40:08 +08:00
|
|
|
TargetABI = ARM_ABI_AAPCS;
|
|
|
|
else
|
|
|
|
TargetABI = ARM_ABI_APCS;
|
|
|
|
break;
|
|
|
|
}
|
2013-12-15 08:12:52 +08:00
|
|
|
}
|
2011-07-07 15:07:08 +08:00
|
|
|
|
2014-04-03 04:32:05 +08:00
|
|
|
// FIXME: this is invalid for WindowsCE
|
|
|
|
if (isTargetWindows()) {
|
|
|
|
TargetABI = ARM_ABI_AAPCS;
|
|
|
|
NoARM = true;
|
|
|
|
}
|
|
|
|
|
2007-02-14 03:52:28 +08:00
|
|
|
if (isAAPCS_ABI())
|
|
|
|
stackAlignment = 8;
|
Use 16 byte stack alignment for NaCl on ARM
NaCl's ARM ABI uses 16 byte stack alignment, so set that in
ARMSubtarget.cpp.
Using 16 byte alignment exposes an issue in code generation in which a
varargs function leaves a 4 byte gap between the values of r1-r3 saved
to the stack and the following arguments that were passed on the
stack. (Previously, this code only needed to support 4 byte and 8
byte alignment.)
With this issue, llc generated:
varargs_func:
sub sp, sp, #16
push {lr}
sub sp, sp, #12
add r0, sp, #16 // Should be 20
stm r0, {r1, r2, r3}
ldr r0, .LCPI0_0 // Address of va_list
add r1, sp, #16
str r1, [r0]
bl external_func
Fix the bug by checking for "Align > 4". Also simplify the code by
using OffsetToAlignment(), and update comments.
Differential Revision: http://llvm-reviews.chandlerc.com/D2677
llvm-svn: 201497
2014-02-17 02:59:48 +08:00
|
|
|
if (isTargetNaCl())
|
|
|
|
stackAlignment = 16;
|
2007-02-14 03:52:28 +08:00
|
|
|
|
2013-08-16 04:54:38 +08:00
|
|
|
UseMovt = hasV6T2Ops() && ArmUseMOVT;
|
|
|
|
|
2014-01-06 22:28:05 +08:00
|
|
|
if (isTargetMachO()) {
|
2011-07-07 11:55:05 +08:00
|
|
|
IsR9Reserved = ReserveR9 | !HasV6Ops;
|
2014-01-06 22:28:05 +08:00
|
|
|
SupportsTailCall = !isTargetIOS() || !getTargetTriple().isOSVersionLT(5, 0);
|
2014-03-11 23:09:44 +08:00
|
|
|
} else {
|
2014-01-06 22:28:05 +08:00
|
|
|
IsR9Reserved = ReserveR9;
|
2014-03-11 23:09:44 +08:00
|
|
|
SupportsTailCall = !isThumb1Only();
|
|
|
|
}
|
2009-10-02 05:46:35 +08:00
|
|
|
|
2009-10-16 14:11:08 +08:00
|
|
|
if (!isThumb() || hasThumb2())
|
|
|
|
PostRAScheduler = true;
|
2010-09-28 12:09:35 +08:00
|
|
|
|
2013-05-18 07:49:01 +08:00
|
|
|
switch (Align) {
|
|
|
|
case DefaultAlign:
|
|
|
|
// Assume pre-ARMv6 doesn't support unaligned accesses.
|
|
|
|
//
|
|
|
|
// ARMv6 may or may not support unaligned accesses depending on the
|
|
|
|
// SCTLR.U bit, which is architecture-specific. We assume ARMv6
|
2014-04-03 03:28:13 +08:00
|
|
|
// Darwin and NetBSD targets support unaligned accesses, and others don't.
|
2013-05-18 07:49:01 +08:00
|
|
|
//
|
|
|
|
// ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
|
|
|
|
// which raises an alignment fault on unaligned accesses. Linux
|
|
|
|
// defaults this bit to 0 and handles it as a system-wide (not
|
|
|
|
// per-process) setting. It is therefore safe to assume that ARMv7+
|
|
|
|
// Linux targets support unaligned accesses. The same goes for NaCl.
|
|
|
|
//
|
|
|
|
// The above behavior is consistent with GCC.
|
2014-02-03 05:18:36 +08:00
|
|
|
AllowsUnalignedMem =
|
|
|
|
(hasV7Ops() && (isTargetLinux() || isTargetNaCl() ||
|
|
|
|
isTargetNetBSD())) ||
|
|
|
|
(hasV6Ops() && (isTargetMachO() || isTargetNetBSD()));
|
2014-04-03 03:28:13 +08:00
|
|
|
// The one exception is cortex-m0, which despite being v6, does not
|
|
|
|
// support unaligned accesses. Rather than make the above boolean
|
|
|
|
// expression even more obtuse, just override the value here.
|
|
|
|
if (isThumb1Only() && isMClass())
|
|
|
|
AllowsUnalignedMem = false;
|
2013-05-18 07:49:01 +08:00
|
|
|
break;
|
|
|
|
case StrictAlign:
|
|
|
|
AllowsUnalignedMem = false;
|
|
|
|
break;
|
|
|
|
case NoStrictAlign:
|
|
|
|
AllowsUnalignedMem = true;
|
|
|
|
break;
|
|
|
|
}
|
2013-03-22 02:47:47 +08:00
|
|
|
|
2013-11-14 02:29:49 +08:00
|
|
|
switch (IT) {
|
|
|
|
case DefaultIT:
|
|
|
|
RestrictIT = hasV8Ops() ? true : false;
|
|
|
|
break;
|
|
|
|
case RestrictedIT:
|
|
|
|
RestrictIT = true;
|
|
|
|
break;
|
|
|
|
case NoRestrictedIT:
|
|
|
|
RestrictIT = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-03-22 02:47:47 +08:00
|
|
|
// NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default.
|
|
|
|
uint64_t Bits = getFeatureBits();
|
|
|
|
if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters
|
|
|
|
(Options.UnsafeFPMath || isTargetDarwin()))
|
|
|
|
UseNEONForSinglePrecisionFP = true;
|
2007-01-19 15:51:42 +08:00
|
|
|
}
|
2009-08-29 07:18:09 +08:00
|
|
|
|
|
|
|
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
|
2009-09-03 15:04:02 +08:00
|
|
|
bool
|
2010-04-15 09:51:59 +08:00
|
|
|
ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
|
|
|
|
Reloc::Model RelocM) const {
|
2009-09-03 15:04:02 +08:00
|
|
|
if (RelocM == Reloc::Static)
|
2009-08-29 07:18:09 +08:00
|
|
|
return false;
|
2009-09-03 15:04:02 +08:00
|
|
|
|
2010-01-28 04:34:15 +08:00
|
|
|
// Materializable GVs (in JIT lazy compilation mode) do not require an extra
|
|
|
|
// load from stub.
|
2011-02-22 14:58:34 +08:00
|
|
|
bool isDecl = GV->hasAvailableExternallyLinkage();
|
|
|
|
if (GV->isDeclaration() && !GV->isMaterializable())
|
|
|
|
isDecl = true;
|
2009-09-03 15:04:02 +08:00
|
|
|
|
2014-01-06 22:28:05 +08:00
|
|
|
if (!isTargetMachO()) {
|
2009-09-03 15:04:02 +08:00
|
|
|
// Extra load is needed for all externally visible.
|
|
|
|
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (RelocM == Reloc::PIC_) {
|
|
|
|
// If this is a strong reference to a definition, it is definitely not
|
|
|
|
// through a stub.
|
|
|
|
if (!isDecl && !GV->isWeakForLinker())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Unless we have a symbol with hidden visibility, we have to go through a
|
|
|
|
// normal $non_lazy_ptr stub because this symbol might be resolved late.
|
|
|
|
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// If symbol visibility is hidden, we have a stub for common symbol
|
|
|
|
// references and external declarations.
|
|
|
|
if (isDecl || GV->hasCommonLinkage())
|
|
|
|
// Hidden $non_lazy_ptr reference.
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
// If this is a strong reference to a definition, it is definitely not
|
|
|
|
// through a stub.
|
|
|
|
if (!isDecl && !GV->isWeakForLinker())
|
|
|
|
return false;
|
2010-12-24 12:28:06 +08:00
|
|
|
|
2009-09-03 15:04:02 +08:00
|
|
|
// Unless we have a symbol with hidden visibility, we have to go through a
|
|
|
|
// normal $non_lazy_ptr stub because this symbol might be resolved late.
|
|
|
|
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2009-08-29 07:18:09 +08:00
|
|
|
}
|
2009-11-10 08:48:55 +08:00
|
|
|
|
2010-09-29 05:57:50 +08:00
|
|
|
unsigned ARMSubtarget::getMispredictionPenalty() const {
|
2012-08-08 10:44:16 +08:00
|
|
|
return SchedModel->MispredictPenalty;
|
2010-09-29 05:57:50 +08:00
|
|
|
}
|
|
|
|
|
2013-11-03 14:14:38 +08:00
|
|
|
bool ARMSubtarget::hasSinCos() const {
|
|
|
|
return getTargetTriple().getOS() == Triple::IOS &&
|
|
|
|
!getTargetTriple().isOSVersionLT(7, 0);
|
|
|
|
}
|
|
|
|
|
2014-06-04 15:06:27 +08:00
|
|
|
// Enable the PostMachineScheduler if the target selects it instead of
|
|
|
|
// PostRAScheduler. Currently only available on the command line via
|
|
|
|
// -misched-postra.
|
|
|
|
bool ARMSubtarget::enablePostMachineScheduler() const {
|
|
|
|
return PostRAScheduler;
|
|
|
|
}
|
|
|
|
|
2009-11-10 08:48:55 +08:00
|
|
|
bool ARMSubtarget::enablePostRAScheduler(
|
|
|
|
CodeGenOpt::Level OptLevel,
|
2011-07-02 05:01:15 +08:00
|
|
|
TargetSubtargetInfo::AntiDepBreakMode& Mode,
|
2009-11-14 03:52:48 +08:00
|
|
|
RegClassVector& CriticalPathRCs) const {
|
2013-09-25 08:26:16 +08:00
|
|
|
Mode = TargetSubtargetInfo::ANTIDEP_NONE;
|
2009-11-10 08:48:55 +08:00
|
|
|
return PostRAScheduler && OptLevel >= CodeGenOpt::Default;
|
|
|
|
}
|