<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Sep 17, 2013 at 5:14 AM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kcc<br>
Date: Tue Sep 17 07:14:50 2013<br>
New Revision: 190863<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=190863&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=190863&view=rev</a><br>
Log:<br>
[asan] inline the calls to __asan_stack_free_* with small sizes. Yet another 10%-20% speedup for use-after-return<br>
<br>
Modified:<br>
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=190863&r1=190862&r2=190863&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=190863&r1=190862&r2=190863&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Sep 17 07:14:50 2013<br>
@@ -88,10 +88,12 @@ static const char *const kAsanPoisonStac<br>
 static const char *const kAsanUnpoisonStackMemoryName =<br>
     "__asan_unpoison_stack_memory";<br>
<br>
+// These constants must match the definitions in the run-time library.<br>
 static const int kAsanStackLeftRedzoneMagic = 0xf1;<br>
 static const int kAsanStackMidRedzoneMagic = 0xf2;<br>
 static const int kAsanStackRightRedzoneMagic = 0xf3;<br>
 static const int kAsanStackPartialRedzoneMagic = 0xf4;<br>
+static const int kAsanStackAfterReturnMagic = 0xf5;<br></blockquote><div><br></div><div>This breaks a -Werror release self-host build as the TU-local constant is unused. I fixed this in r190905.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.<br>
 static const size_t kNumberOfAccessSizes = 5;<br>
@@ -519,6 +521,9 @@ struct FunctionStackPoisoner : public In<br>
   void poisonRedZones(const ArrayRef<AllocaInst*> &AllocaVec, IRBuilder<> &IRB,<br>
                       Value *ShadowBase, bool DoPoison);<br>
   void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison);<br>
+<br>
+  void SetShadowToStackAfterReturnInlined(IRBuilder<> &IRB, Value *ShadowBase,<br>
+                                          int Size);<br>
 };<br>
<br>
 }  // namespace<br>
@@ -1362,6 +1367,22 @@ static int StackMallocSizeClass(uint64_t<br>
   llvm_unreachable("impossible LocalStackSize");<br>
 }<br>
<br>
+// Set Size bytes starting from ShadowBase to kAsanStackAfterReturnMagic.<br>
+// We can not use MemSet intrinsic because it may end up calling the actual<br>
+// memset. Size is a multiple of 8.<br>
+// Currently this generates 8-byte stores on x86_64; it may be better to<br>
+// generate wider stores.<br>
+void FunctionStackPoisoner::SetShadowToStackAfterReturnInlined(<br>
+    IRBuilder<> &IRB, Value *ShadowBase, int Size) {<br>
+  assert(!(Size % 8));<br>
+  assert(kAsanStackAfterReturnMagic == 0xf5);<br>
+  for (int i = 0; i < Size; i += 8) {<br>
+    Value *p = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));<br>
+    IRB.CreateStore(ConstantInt::get(IRB.getInt64Ty(), 0xf5f5f5f5f5f5f5f5ULL),<br>
+                    IRB.CreateIntToPtr(p, IRB.getInt64Ty()->getPointerTo()));<br>
+  }<br>
+}<br>
+<br>
 void FunctionStackPoisoner::poisonStack() {<br>
   uint64_t LocalStackSize = TotalStackSize +<br>
                             (AllocaVec.size() + 1) * RedzoneSize();<br>
@@ -1465,9 +1486,33 @@ void FunctionStackPoisoner::poisonStack(<br>
     if (DoStackMalloc) {<br>
       assert(StackMallocIdx >= 0);<br>
       // In use-after-return mode, mark the whole stack frame unaddressable.<br>
-      IRBRet.CreateCall3(AsanStackFreeFunc[StackMallocIdx], LocalStackBase,<br>
-                         ConstantInt::get(IntptrTy, LocalStackSize),<br>
-                         OrigStackBase);<br>
+      if (StackMallocIdx <= 4) {<br>
+        // For small sizes inline the whole thing:<br>
+        // if LocalStackBase != OrigStackBase:<br>
+        //     memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);<br>
+        //     **SavedFlagPtr(LocalStackBase) = 0<br>
+        // FIXME: if LocalStackBase != OrigStackBase don't call poisonRedZones.<br>
+        Value *Cmp = IRBRet.CreateICmpNE(LocalStackBase, OrigStackBase);<br>
+        TerminatorInst *PoisonTerm =<br>
+            SplitBlockAndInsertIfThen(cast<Instruction>(Cmp), false);<br>
+        IRBuilder<> IRBPoison(PoisonTerm);<br>
+        int ClassSize = kMinStackMallocSize << StackMallocIdx;<br>
+        SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase,<br>
+                                           ClassSize >> Mapping.Scale);<br>
+        Value *SavedFlagPtrPtr = IRBPoison.CreateAdd(<br>
+            LocalStackBase,<br>
+            ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));<br>
+        Value *SavedFlagPtr = IRBPoison.CreateLoad(<br>
+            IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy));<br>
+        IRBPoison.CreateStore(<br>
+            Constant::getNullValue(IRBPoison.getInt8Ty()),<br>
+            IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy()));<br>
+      } else {<br>
+        // For larger frames call __asan_stack_free_*.<br>
+        IRBRet.CreateCall3(AsanStackFreeFunc[StackMallocIdx], LocalStackBase,<br>
+                           ConstantInt::get(IntptrTy, LocalStackSize),<br>
+                           OrigStackBase);<br>
+      }<br>
     } else if (HavePoisonedAllocas) {<br>
       // If we poisoned some allocas in llvm.lifetime analysis,<br>
       // unpoison whole stack frame now.<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>