[llvm] r215676 - Copy noalias metadata from call sites to inlined instructions

Hal Finkel hfinkel at anl.gov
Thu Aug 14 14:09:37 PDT 2014


Author: hfinkel
Date: Thu Aug 14 16:09:37 2014
New Revision: 215676

URL: http://llvm.org/viewvc/llvm-project?rev=215676&view=rev
Log:
Copy noalias metadata from call sites to inlined instructions

When a call site with noalias metadata is inlined, that metadata can be
propagated directly to the inlined instructions (only those that might access
memory because it is not useful on the others). Prior to inlining, the noalias
metadata could express that a call would not alias with some other memory
access, which implies that no instruction within that called function would
alias. By propagating the metadata to the inlined instructions, we preserve
that knowledge.

This should complete the enhancements requested in PR20500.

Added:
    llvm/trunk/test/Transforms/Inline/noalias-cs.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp

Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=215676&r1=215675&r2=215676&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu Aug 14 16:09:37 2014
@@ -356,11 +356,35 @@ static void CloneAliasScopeMetadata(Call
     if (!NI)
       continue;
 
-    if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope))
-      NI->setMetadata(LLVMContext::MD_alias_scope, MDMap[M]);
+    if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope)) {
+      MDNode *NewMD = MDMap[M];
+      // If the call site also had alias scope metadata (a list of scopes to
+      // which instructions inside it might belong), propagate those scopes to
+      // the inlined instructions.
+      if (MDNode *CSM =
+          CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope))
+        NewMD = MDNode::concatenate(NewMD, CSM);
+      NI->setMetadata(LLVMContext::MD_alias_scope, NewMD);
+    } else if (NI->mayReadOrWriteMemory()) {
+      if (MDNode *M =
+          CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope))
+        NI->setMetadata(LLVMContext::MD_alias_scope, M);
+    }
 
-    if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias))
-      NI->setMetadata(LLVMContext::MD_noalias, MDMap[M]);
+    if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias)) {
+      MDNode *NewMD = MDMap[M];
+      // If the call site also had noalias metadata (a list of scopes with
+      // which instructions inside it don't alias), propagate those scopes to
+      // the inlined instructions.
+      if (MDNode *CSM =
+          CS.getInstruction()->getMetadata(LLVMContext::MD_noalias))
+        NewMD = MDNode::concatenate(NewMD, CSM);
+      NI->setMetadata(LLVMContext::MD_noalias, NewMD);
+    } else if (NI->mayReadOrWriteMemory()) {
+      if (MDNode *M =
+          CS.getInstruction()->getMetadata(LLVMContext::MD_noalias))
+        NI->setMetadata(LLVMContext::MD_noalias, M);
+    }
   }
 
   // Now that everything has been replaced, delete the dummy nodes.

Added: llvm/trunk/test/Transforms/Inline/noalias-cs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/noalias-cs.ll?rev=215676&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/Inline/noalias-cs.ll (added)
+++ llvm/trunk/test/Transforms/Inline/noalias-cs.ll Thu Aug 14 16:09:37 2014
@@ -0,0 +1,84 @@
+; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
+target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+entry:
+  %0 = load float* %c, align 4, !noalias !3
+  %arrayidx.i = getelementptr inbounds float* %a, i64 5
+  store float %0, float* %arrayidx.i, align 4, !alias.scope !7, !noalias !8
+  %arrayidx1.i = getelementptr inbounds float* %b, i64 8
+  store float %0, float* %arrayidx1.i, align 4, !alias.scope !8, !noalias !7
+  %1 = load float* %c, align 4
+  %arrayidx = getelementptr inbounds float* %a, i64 7
+  store float %1, float* %arrayidx, align 4
+  ret void
+}
+
+define void @foo(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+entry:
+  call void @foo2(float* %a, float* %b, float* %c), !noalias !0
+  call void @foo2(float* %b, float* %b, float* %a), !alias.scope !0
+  ret void
+}
+
+; CHECK: define void @foo(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
+; CHECK: entry:
+; CHECK:   %0 = load float* %c, align 4, !noalias !6
+; CHECK:   %arrayidx.i.i = getelementptr inbounds float* %a, i64 5
+; CHECK:   store float %0, float* %arrayidx.i.i, align 4, !alias.scope !12, !noalias !13
+; CHECK:   %arrayidx1.i.i = getelementptr inbounds float* %b, i64 8
+; CHECK:   store float %0, float* %arrayidx1.i.i, align 4, !alias.scope !14, !noalias !15
+; CHECK:   %1 = load float* %c, align 4, !noalias !16
+; CHECK:   %arrayidx.i = getelementptr inbounds float* %a, i64 7
+; CHECK:   store float %1, float* %arrayidx.i, align 4, !noalias !16
+; CHECK:   %2 = load float* %a, align 4, !alias.scope !16, !noalias !17
+; CHECK:   %arrayidx.i.i1 = getelementptr inbounds float* %b, i64 5
+; CHECK:   store float %2, float* %arrayidx.i.i1, align 4, !alias.scope !21, !noalias !22
+; CHECK:   %arrayidx1.i.i2 = getelementptr inbounds float* %b, i64 8
+; CHECK:   store float %2, float* %arrayidx1.i.i2, align 4, !alias.scope !23, !noalias !24
+; CHECK:   %3 = load float* %a, align 4, !alias.scope !16
+; CHECK:   %arrayidx.i3 = getelementptr inbounds float* %b, i64 7
+; CHECK:   store float %3, float* %arrayidx.i3, align 4, !alias.scope !16
+; CHECK:   ret void
+; CHECK: }
+
+attributes #0 = { nounwind uwtable }
+
+!0 = metadata !{metadata !1}
+!1 = metadata !{metadata !1, metadata !2, metadata !"hello: %a"}
+!2 = metadata !{metadata !2, metadata !"hello"}
+!3 = metadata !{metadata !4, metadata !6}
+!4 = metadata !{metadata !4, metadata !5, metadata !"hello2: %a"}
+!5 = metadata !{metadata !5, metadata !"hello2"}
+!6 = metadata !{metadata !6, metadata !5, metadata !"hello2: %b"}
+!7 = metadata !{metadata !4}
+!8 = metadata !{metadata !6}
+
+; CHECK: !0 = metadata !{metadata !1, metadata !3}
+; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello2: %a"}
+; CHECK: !2 = metadata !{metadata !2, metadata !"hello2"}
+; CHECK: !3 = metadata !{metadata !3, metadata !2, metadata !"hello2: %b"}
+; CHECK: !4 = metadata !{metadata !1}
+; CHECK: !5 = metadata !{metadata !3}
+; CHECK: !6 = metadata !{metadata !7, metadata !9, metadata !10}
+; CHECK: !7 = metadata !{metadata !7, metadata !8, metadata !"hello2: %a"}
+; CHECK: !8 = metadata !{metadata !8, metadata !"hello2"}
+; CHECK: !9 = metadata !{metadata !9, metadata !8, metadata !"hello2: %b"}
+; CHECK: !10 = metadata !{metadata !10, metadata !11, metadata !"hello: %a"}
+; CHECK: !11 = metadata !{metadata !11, metadata !"hello"}
+; CHECK: !12 = metadata !{metadata !7}
+; CHECK: !13 = metadata !{metadata !9, metadata !10}
+; CHECK: !14 = metadata !{metadata !9}
+; CHECK: !15 = metadata !{metadata !7, metadata !10}
+; CHECK: !16 = metadata !{metadata !10}
+; CHECK: !17 = metadata !{metadata !18, metadata !20}
+; CHECK: !18 = metadata !{metadata !18, metadata !19, metadata !"hello2: %a"}
+; CHECK: !19 = metadata !{metadata !19, metadata !"hello2"}
+; CHECK: !20 = metadata !{metadata !20, metadata !19, metadata !"hello2: %b"}
+; CHECK: !21 = metadata !{metadata !18, metadata !10}
+; CHECK: !22 = metadata !{metadata !20}
+; CHECK: !23 = metadata !{metadata !20, metadata !10}
+; CHECK: !24 = metadata !{metadata !18}
+





More information about the llvm-commits mailing list