From cc271861da5d9487cbcbb44f949b411a12ec0d96 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 13 Oct 2009 07:03:23 +0000 Subject: [PATCH] Add new "memory use marker" intrinsics. These indicate lifetimes and invariant sections of memory objects. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83953 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.html | 131 ++++++++++++++++++++++++++++++++++ include/llvm/Intrinsics.td | 16 +++++ test/Feature/memorymarkers.ll | 36 ++++++++++ 3 files changed, 183 insertions(+) create mode 100644 test/Feature/memorymarkers.ll diff --git a/docs/LangRef.html b/docs/LangRef.html index 1b1655e42fd..7adb89621f4 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -273,6 +273,14 @@
  • llvm.atomic.load.umin
  • +
  • Memory Use Markers +
      +
    1. llvm.lifetime.start
    2. +
    3. llvm.lifetime.end
    4. +
    5. llvm.invariant.start
    6. +
    7. llvm.invariant.end
    8. +
    +
  • General intrinsics
    1. @@ -6980,6 +6988,129 @@ LLVM.

      + + + + +
      + +

      This class of intrinsics exists to information about the lifetime of memory + objects and ranges where variables are immutable.

      + +
      + + + + +
      + +
      Syntax:
      +
      +  declare void @llvm.lifetime.start(i64 <size>, i8* nocapture <ptr>)
      +
      + +
      Overview:
      +

      The 'llvm.lifetime.start' intrinsic specifies the start of a memory + object's lifetime.

      + +
      Arguments:
      +

      The first argument is a the size of the object, or -1 if it is variable + sized. The second argument is a pointer to the object.

      + +
      Semantics:
      +

      This intrinsic indicates that before this point in the code, the value of the + memory pointed to by ptr is dead. This means that it is known to + never be used and has an undefined value. A load from the pointer that is + preceded by this intrinsic can be replaced with + 'undef'.

      + +
      + + + + +
      + +
      Syntax:
      +
      +  declare void @llvm.lifetime.end(i64 <size>, i8* nocapture <ptr>)
      +
      + +
      Overview:
      +

      The 'llvm.lifetime.end' intrinsic specifies the end of a memory + object's lifetime.

      + +
      Arguments:
      +

      The first argument is a the size of the object, or -1 if it is variable + sized. The second argument is a pointer to the object.

      + +
      Semantics:
      +

      This intrinsic indicates that after this point in the code, the value of the + memory pointed to by ptr is dead. This means that it is known to + never be used and has an undefined value. Any stores into the memory object + following this intrinsic may be removed as dead. + +

      + + + + +
      + +
      Syntax:
      +
      +  declare {}* @llvm.invariant.start(i64 <size>, i8* nocapture <ptr>) readonly
      +
      + +
      Overview:
      +

      The 'llvm.invariant.start' intrinsic specifies that the contents of + a memory object will not change.

      + +
      Arguments:
      +

      The first argument is a the size of the object, or -1 if it is variable + sized. The second argument is a pointer to the object.

      + +
      Semantics:
      +

      This intrinsic indicates that until an llvm.invariant.end that uses + the return value, the referenced memory location is constant and + unchanging.

      + +
      + + + + +
      + +
      Syntax:
      +
      +  declare void @llvm.invariant.end({}* <start>, i64 <size>, i8* nocapture <ptr>)
      +
      + +
      Overview:
      +

      The 'llvm.invariant.end' intrinsic specifies that the contents of + a memory object are mutable.

      + +
      Arguments:
      +

      The first argument is the matching llvm.invariant.start intrinsic. + The second argument is a the size of the object, or -1 if it is variable + sized and the third argument is a pointer to the object.

      + +
      Semantics:
      +

      This intrinsic indicates that the memory is mutable again.

      + +
      +
      General Intrinsics diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 9b0c876d72f..bfa924cd866 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -421,6 +421,22 @@ def int_atomic_load_umax : Intrinsic<[llvm_anyint_ty], [IntrWriteArgMem, NoCapture<0>]>, GCCBuiltin<"__sync_fetch_and_umax">; +//===------------------------- Memory Use Markers -------------------------===// +// +def int_lifetime_start : Intrinsic<[llvm_void_ty], + [llvm_i64_ty, llvm_ptr_ty], + [IntrWriteArgMem, NoCapture<1>]>; +def int_lifetime_end : Intrinsic<[llvm_void_ty], + [llvm_i64_ty, llvm_ptr_ty], + [IntrWriteArgMem, NoCapture<1>]>; +def int_invariant_start : Intrinsic<[llvm_descriptor_ty], + [llvm_i64_ty, llvm_ptr_ty], + [IntrReadArgMem, NoCapture<1>]>; +def int_invariant_end : Intrinsic<[llvm_void_ty], + [llvm_descriptor_ty, llvm_i64_ty, + llvm_ptr_ty], + [IntrWriteArgMem, NoCapture<2>]>; + //===-------------------------- Other Intrinsics --------------------------===// // def int_flt_rounds : Intrinsic<[llvm_i32_ty]>, diff --git a/test/Feature/memorymarkers.ll b/test/Feature/memorymarkers.ll new file mode 100644 index 00000000000..06b8376678f --- /dev/null +++ b/test/Feature/memorymarkers.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as -disable-output < %s + +%"struct.std::pair" = type { i32, i32 } + +declare void @_Z3barRKi(i32*) + +declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind +declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind +declare {}* @llvm.invariant.start(i64, i8* nocapture) readonly nounwind +declare void @llvm.invariant.end({}*, i64, i8* nocapture) nounwind + +define i32 @_Z4foo2v() nounwind { +entry: + %x = alloca %"struct.std::pair" + %y = bitcast %"struct.std::pair"* %x to i8* + + ;; Constructor starts here (this isn't needed since it is immediately + ;; preceded by an alloca, but shown for completeness). + call void @llvm.lifetime.start(i64 8, i8* %y) + + %0 = getelementptr %"struct.std::pair"* %x, i32 0, i32 0 + store i32 4, i32* %0, align 8 + %1 = getelementptr %"struct.std::pair"* %x, i32 0, i32 1 + store i32 5, i32* %1, align 4 + + ;; Constructor has finished here. + %inv = call {}* @llvm.invariant.start(i64 8, i8* %y) + call void @_Z3barRKi(i32* %0) nounwind + %2 = load i32* %0, align 8 + + ;; Destructor is run here. + call void @llvm.invariant.end({}* %inv, i64 8, i8* %y) + ;; Destructor is done here. + call void @llvm.lifetime.end(i64 8, i8* %y) + ret i32 %2 +}