[Inliner] Teach inliner to merge 'min-legal-vector-width' function attribute
authorCraig Topper <craig.topper@intel.com>
Tue, 24 Jul 2018 18:49:00 +0000 (18:49 +0000)
committerCraig Topper <craig.topper@intel.com>
Tue, 24 Jul 2018 18:49:00 +0000 (18:49 +0000)
When we inline a function with a min-legal-vector-width attribute we need to make sure the caller also ends up with at least that vector width.

This patch is necessary to make always_inline functions like intrinsics propagate their min-legal-vector-width. Though nothing uses min-legal-vector-width yet.

A future patch will add heuristics to preventing inlining with different vector width mismatches. But that code would need to be in inline cost analysis which is separate from the code added here.

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

llvm-svn: 337844

llvm/include/llvm/IR/Attributes.td
llvm/lib/IR/Attributes.cpp

index 564ab0a3f3f44a8d78217a6b43bd7ff5d5a6c975..1019f867aab0b8d9b8cb1e8513fb0d03159a189d 100644 (file)
@@ -235,3 +235,4 @@ def : MergeRule<"setOR<ProfileSampleAccurateAttr>">;
 def : MergeRule<"adjustCallerSSPLevel">;
 def : MergeRule<"adjustCallerStackProbes">;
 def : MergeRule<"adjustCallerStackProbeSize">;
+def : MergeRule<"adjustMinLegalVectorWidth">;
index 01de8bb56279fe75172691f3d06be97cd5f00cae..9e5f55d497562a761486ff3ffa20b0775513e792 100644 (file)
@@ -1682,6 +1682,33 @@ adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
   }
 }
 
+/// If the inlined function defines a min legal vector width, then ensure
+/// the calling function has the same or larger min legal vector width. This
+/// function is called after the inlining decision has been made so we have to
+/// merge the attribute this way. Heuristics that would use
+/// min-legal-vector-width to determine inline compatibility would need to be
+/// handled as part of inline cost analysis.
+static void
+adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
+  if (Callee.hasFnAttribute("min-legal-vector-width")) {
+    uint64_t CalleeVectorWidth;
+    Callee.getFnAttribute("min-legal-vector-width")
+          .getValueAsString()
+          .getAsInteger(0, CalleeVectorWidth);
+    if (Caller.hasFnAttribute("min-legal-vector-width")) {
+      uint64_t CallerVectorWidth;
+      Caller.getFnAttribute("min-legal-vector-width")
+            .getValueAsString()
+            .getAsInteger(0, CallerVectorWidth);
+      if (CallerVectorWidth < CalleeVectorWidth) {
+        Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
+      }
+    } else {
+      Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
+    }
+  }
+}
+
 #define GET_ATTR_COMPAT_FUNC
 #include "AttributesCompatFunc.inc"