[llvm] r190863 - [asan] inline the calls to __asan_stack_free_* with small sizes. Yet another 10%-20% speedup for use-after-return

David Blaikie dblaikie at gmail.com
Tue Sep 17 17:14:38 PDT 2013


On Tue, Sep 17, 2013 at 5:14 AM, Kostya Serebryany <kcc at google.com> wrote:

> Author: kcc
> Date: Tue Sep 17 07:14:50 2013
> New Revision: 190863
>
> URL: http://llvm.org/viewvc/llvm-project?rev=190863&view=rev
> Log:
> [asan] inline the calls to __asan_stack_free_* with small sizes. Yet
> another 10%-20% speedup for use-after-return
>
> Modified:
>     llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=190863&r1=190862&r2=190863&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Sep
> 17 07:14:50 2013
> @@ -88,10 +88,12 @@ static const char *const kAsanPoisonStac
>  static const char *const kAsanUnpoisonStackMemoryName =
>      "__asan_unpoison_stack_memory";
>
> +// These constants must match the definitions in the run-time library.
>  static const int kAsanStackLeftRedzoneMagic = 0xf1;
>  static const int kAsanStackMidRedzoneMagic = 0xf2;
>  static const int kAsanStackRightRedzoneMagic = 0xf3;
>  static const int kAsanStackPartialRedzoneMagic = 0xf4;
> +static const int kAsanStackAfterReturnMagic = 0xf5;
>

This breaks a -Werror release self-host build as the TU-local constant is
unused. I fixed this in r190905.


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


More information about the llvm-commits mailing list