There are no existing attributes for this in upstream, but you       can hook isAllocLikeFunction to get the effect you're looking for.

    

Philip
    

    
    On 11/17/2017 05:17 AM, Siddharth Bhat       via llvm-dev wrote:
                         
Hello all,
        
I have a custom allocator, and would like to teach LLVM           about its semantics. In particular, I would like LLVM to kill           allocations that are "dead", similar to dead new in C++.
        
        

        
        
Consider this example:
        

        
        
; ModuleID =             ''
            source_filename = "Module"
            
            ; Function Attrs: inaccessiblememonly noinline norecurse             nounwind
            declare i8* @alloc(i64) local_unnamed_addr #0
            
            ; Function Attrs: inaccessiblememonly noinline norecurse             nounwind
            declare void @useClosure(i8*) local_unnamed_addr #1
            
            ; Function Attrs: alwaysinline norecurse nounwind
            define void @main() #1 {
            entry:
              %closure.raw = tail call noalias i8* @alloc(i64 8)
              %fn_slot = bitcast i8* %closure.raw to void ()**
              store void ()* @"case_ackerman(atom-3 atom-10)_alts", void             ()** %fn_slot, align 8, !invariant.group !0
              tail call void @useClosure(i8* %closure.raw)
              ;========
              ; dead
              %closure.raw.i = tail call noalias i8* @alloc(i64 24)
              %fn_slot.i = bitcast i8* %closure.raw.i to void ()**
              store void ()* @"case_aint()_alts", void ()** %fn_slot.i,             align 8, !invariant.group !0
              ;========
              ret void
            }
            
            ; Function Attrs: alwaysinline
            declare void @"case_aint()_alts"() #2
            
            ; Function Attrs: alwaysinline
            declare void @"case_ackerman(atom-3 atom-10)_alts"() #2
            
            attributes #0 = { inaccessiblememonly noinline norecurse             nounwind writeonly }
            attributes #1 = { alwaysinline norecurse nounwind }
            attributes #2 = { alwaysinline }
            
            !0 = distinct !{!0, !"closure_invariant_group"}
          -----
        

        
        
In my view, %closure.raw.i           is a dead allocation, because the memory returned by it is               not used anywhere. How do I communicate this fact to LLVM?
        

            
        
I               tried seeing how clang does it, but I'm not sure - it               doesn't seem to have any attribute that would help, except               perhaps builtin. Does LLVM               know about the special semantics of new?
            
        

            
        
Cheers,
        
~Siddharth.
          
             -- 
                      Sending this from my phone, please excuse any           typos!              
             
      
_______________________________________________
LLVM Developers mailing list
llvm-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
         
  ">

(original) (raw)

Thanks for the pointer!


On Wed 29 Nov, 2017, 18:50 Philip Reames, <listmail@philipreames.com> wrote:

There are no existing attributes for this in upstream, but you can hook isAllocLikeFunction to get the effect you're looking for.

Philip


On 11/17/2017 05:17 AM, Siddharth Bhat via llvm-dev wrote:
Hello all,
I have a custom allocator, and would like to teach LLVM about its semantics. In particular, I would like LLVM to kill allocations that are "dead", similar to dead new in C++.

Consider this example:

; ModuleID = ''
source\_filename = "Module"

; Function Attrs: inaccessiblememonly noinline norecurse nounwind
declare i8\* @alloc(i64) local\_unnamed\_addr #0

; Function Attrs: inaccessiblememonly noinline norecurse nounwind
declare void @useClosure(i8\*) local\_unnamed\_addr #1

; Function Attrs: alwaysinline norecurse nounwind
define void @main() #1 {
entry:
%closure.raw = tail call noalias i8\* @alloc(i64 8)
%fn\_slot = bitcast i8\* %closure.raw to void ()\*\*
store void ()\* @"case\_ackerman(atom-3 atom-10)\_alts", void ()\*\* %fn\_slot, align 8, !invariant.group !0
tail call void @useClosure(i8\* %closure.raw)
;========
; dead
%closure.raw.i = tail call noalias i8\* @alloc(i64 24)
%fn\_slot.i = bitcast i8\* %closure.raw.i to void ()\*\*
store void ()\* @"case\_aint()\_alts", void ()\*\* %fn\_slot.i, align 8, !invariant.group !0
;========
ret void
}

; Function Attrs: alwaysinline
declare void @"case\_aint()\_alts"() #2

; Function Attrs: alwaysinline
declare void @"case\_ackerman(atom-3 atom-10)\_alts"() #2

attributes #0 = { inaccessiblememonly noinline norecurse nounwind writeonly }
attributes #1 = { alwaysinline norecurse nounwind }
attributes #2 = { alwaysinline }

!0 = distinct !{!0, !"closure\_invariant\_group"}

\-----

In my view, %closure.raw.i is a dead allocation, because the memory returned by it is not used anywhere. How do I communicate this fact to LLVM?

I tried seeing how clang does it, but I'm not sure - it doesn't seem to have any attribute that would help, except perhaps builtin. Does LLVM know about the special semantics of new?

Cheers,
\~Siddharth.
--
Sending this from my phone, please excuse any typos!


\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
LLVM Developers mailing list  
llvm-dev@lists.llvm.org  
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev  

--
Sending this from my phone, please excuse any typos!