]> granicus.if.org Git - llvm/commitdiff
[AArch64] Inline callee if its target-features are a subset of the caller
authorFlorian Hahn <florian.hahn@arm.com>
Tue, 27 Jun 2017 22:27:32 +0000 (22:27 +0000)
committerFlorian Hahn <florian.hahn@arm.com>
Tue, 27 Jun 2017 22:27:32 +0000 (22:27 +0000)
Summary:
Similar to X86, it should be safe to inline callees if their target-features
are a subset of the caller. This change matches GCC's inlining behavior
with respect to attributes [1].

[1] https://gcc.gnu.org/onlinedocs/gcc/AArch64-Function-Attributes.html#AArch64-Function-Attributes

Reviewers: kristof.beyls, javed.absar, rengolin, t.p.northover

Reviewed By: t.p.northover

Subscribers: aemerson, eraman, llvm-commits

Differential Revision: https://reviews.llvm.org/D34698

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306478 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64TargetTransformInfo.cpp
lib/Target/AArch64/AArch64TargetTransformInfo.h
test/Transforms/Inline/AArch64/inline-target-attr.ll [new file with mode: 0644]

index a4328682b93c37dce9e1ed7f4cf93b174e6db917..1d0f0b98b767ea856eecbb0cd813acd24c061ecf 100644 (file)
@@ -20,6 +20,20 @@ using namespace llvm;
 
 #define DEBUG_TYPE "aarch64tti"
 
+bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
+                                         const Function *Callee) const {
+  const TargetMachine &TM = getTLI()->getTargetMachine();
+
+  const FeatureBitset &CallerBits =
+      TM.getSubtargetImpl(*Caller)->getFeatureBits();
+  const FeatureBitset &CalleeBits =
+      TM.getSubtargetImpl(*Callee)->getFeatureBits();
+
+  // Inline a callee if its target-features are a subset of the callers
+  // target-features.
+  return (CallerBits & CalleeBits) == CalleeBits;
+}
+
 /// \brief Calculate the cost of materializing a 64-bit value. This helper
 /// method might only calculate a fraction of a larger immediate. Therefore it
 /// is valid to return a cost of ZERO.
index 290a1ca1f24b47b30e8d48f4eaad15fb76056392..75c62ea3233d36ec633e55ee05419cc5c8e31c29 100644 (file)
@@ -51,6 +51,9 @@ public:
       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
         TLI(ST->getTargetLowering()) {}
 
+  bool areInlineCompatible(const Function *Caller,
+                           const Function *Callee) const;
+
   /// \name Scalar TTI Implementations
   /// @{
 
diff --git a/test/Transforms/Inline/AArch64/inline-target-attr.ll b/test/Transforms/Inline/AArch64/inline-target-attr.ll
new file mode 100644 (file)
index 0000000..af87ff6
--- /dev/null
@@ -0,0 +1,40 @@
+; RUN: opt < %s -mtriple=aarch64-unknown-linux-gnu -S -inline | FileCheck %s
+; RUN: opt < %s -mtriple=aarch64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s
+; Check that we only inline when we have compatible target attributes.
+
+define i32 @foo() #0 {
+entry:
+  %call = call i32 (...) @baz()
+  ret i32 %call
+; CHECK-LABEL: foo
+; CHECK: call i32 (...) @baz()
+}
+declare i32 @baz(...) #0
+
+define i32 @bar() #1 {
+entry:
+  %call = call i32 @foo()
+  ret i32 %call
+; CHECK-LABEL: bar
+; CHECK: call i32 (...) @baz()
+}
+
+define i32 @qux() #0 {
+entry:
+  %call = call i32 @bar()
+  ret i32 %call
+; CHECK-LABEL: qux
+; CHECK: call i32 @bar()
+}
+
+define i32 @strict_align() #2 {
+entry:
+  %call = call i32 @foo()
+  ret i32 %call
+; CHECK-LABEL: strict_align
+; CHECK: call i32 (...) @baz()
+}
+
+attributes #0 = { "target-cpu"="generic" "target-features"="+crc,+neon" }
+attributes #1 = { "target-cpu"="generic" "target-features"="+crc,+neon,+crypto" }
+attributes #2 = { "target-cpu"="generic" "target-features"="+crc,+neon,+strict-align" }