summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64
diff options
context:
space:
mode:
authorJiangning Liu <jiangning.liu@arm.com>2014-04-18 03:58:38 +0000
committerJiangning Liu <jiangning.liu@arm.com>2014-04-18 03:58:38 +0000
commite56c30614f91440ac033a30f6c81a55904d6545e (patch)
tree1fee3f075b7e4ae8423b45dcee28188363ecfee2 /llvm/lib/Target/AArch64
parente576167df81353876c3be9ca2b6ab0ceafa01764 (diff)
downloadbcm5719-llvm-e56c30614f91440ac033a30f6c81a55904d6545e.tar.gz
bcm5719-llvm-e56c30614f91440ac033a30f6c81a55904d6545e.zip
This commit enables unaligned memory accesses of vector types on AArch64 back end. This should boost vectorized code performance.
Patched by Z. Zheng llvm-svn: 206557
Diffstat (limited to 'llvm/lib/Target/AArch64')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp44
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.h6
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.cpp34
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.h7
4 files changed, 91 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 236d5ec4a9e..1e798944722 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4412,6 +4412,50 @@ AArch64TargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const {
return false;
}
+
+bool AArch64TargetLowering::allowsUnalignedMemoryAccesses(EVT VT,
+ unsigned AddrSpace,
+ bool *Fast) const {
+ const AArch64Subtarget *Subtarget = getSubtarget();
+ // The AllowsUnaliged flag models the SCTLR.A setting in ARM cpus
+ bool AllowsUnaligned = Subtarget->allowsUnalignedMem();
+
+ switch (VT.getSimpleVT().SimpleTy) {
+ default:
+ return false;
+ // Scalar types
+ case MVT::i8: case MVT::i16:
+ case MVT::i32: case MVT::i64:
+ case MVT::f32: case MVT::f64: {
+ // Unaligned access can use (for example) LRDB, LRDH, LDRW
+ if (AllowsUnaligned) {
+ if (Fast)
+ *Fast = true;
+ return true;
+ }
+ return false;
+ }
+ // 64-bit vector types
+ case MVT::v8i8: case MVT::v4i16:
+ case MVT::v2i32: case MVT::v1i64:
+ case MVT::v2f32: case MVT::v1f64:
+ // 128-bit vector types
+ case MVT::v16i8: case MVT::v8i16:
+ case MVT::v4i32: case MVT::v2i64:
+ case MVT::v4f32: case MVT::v2f64: {
+ // For any little-endian targets with neon, we can support unaligned
+ // load/store of V registers using ld1/st1.
+ // A big-endian target may also explicitly support unaligned accesses
+ if (Subtarget->hasNEON() && (AllowsUnaligned || isLittleEndian())) {
+ if (Fast)
+ *Fast = true;
+ return true;
+ }
+ return false;
+ }
+ }
+}
+
// Check whether a shuffle_vector could be presented as concat_vector.
bool AArch64TargetLowering::isConcatVector(SDValue Op, SelectionDAG &DAG,
SDValue V0, SDValue V1,
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index f83c1ab0052..154c1d76737 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -355,6 +355,12 @@ public:
/// expanded to fmul + fadd.
virtual bool isFMAFasterThanFMulAndFAdd(EVT VT) const;
+ /// allowsUnalignedMemoryAccesses - Returns true if the target allows
+ /// unaligned memory accesses of the specified type. Returns whether it
+ /// is "fast" by reference in the second argument.
+ virtual bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
+ bool *Fast) const;
+
ConstraintType getConstraintType(const std::string &Constraint) const;
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info,
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
index 9140bbdb412..53cdf30b966 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
@@ -25,6 +25,25 @@
using namespace llvm;
+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, "aarch64-default-align",
+ "Generate unaligned accesses only on hardware/OS "
+ "combinations that are known to support them"),
+ clEnumValN(StrictAlign, "aarch64-strict-align",
+ "Disallow all unaligned memory accesses"),
+ clEnumValN(NoStrictAlign, "aarch64-no-strict-align",
+ "Allow unaligned memory accesses"),
+ clEnumValEnd));
+
// Pin the vtable to this file.
void AArch64Subtarget::anchor() {}
@@ -39,6 +58,8 @@ AArch64Subtarget::AArch64Subtarget(StringRef TT, StringRef CPU, StringRef FS,
void AArch64Subtarget::initializeSubtargetFeatures(StringRef CPU,
StringRef FS) {
+ AllowsUnalignedMem = false;
+
if (CPU.empty())
CPUString = "generic";
@@ -52,6 +73,19 @@ void AArch64Subtarget::initializeSubtargetFeatures(StringRef CPU,
}
ParseSubtargetFeatures(CPU, FullFS);
+
+ switch (Align) {
+ case DefaultAlign:
+ // Linux targets support unaligned accesses on AARCH64
+ AllowsUnalignedMem = isTargetLinux();
+ break;
+ case StrictAlign:
+ AllowsUnalignedMem = false;
+ break;
+ case NoStrictAlign:
+ AllowsUnalignedMem = true;
+ break;
+ }
}
bool AArch64Subtarget::GVIsIndirectSymbol(const GlobalValue *GV,
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 68c6c4b63cc..45e5a5eb063 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -38,6 +38,11 @@ protected:
bool HasNEON;
bool HasCrypto;
+ /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory
+ /// accesses for some types. For details, see
+ /// AArch64TargetLowering::allowsUnalignedMemoryAccesses().
+ bool AllowsUnalignedMem;
+
/// TargetTriple - What processor and OS we're targeting.
Triple TargetTriple;
@@ -74,6 +79,8 @@ public:
bool hasNEON() const { return HasNEON; }
bool hasCrypto() const { return HasCrypto; }
+ bool allowsUnalignedMem() const { return AllowsUnalignedMem; }
+
bool isLittle() const { return IsLittleEndian; }
const std::string & getCPUString() const { return CPUString; }
OpenPOWER on IntegriCloud