Advertisement
Guest User

Untitled

a guest
Jul 7th, 2019
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
LLVM 3.55 KB | None | 0 0
  1. ; Generic Foo definition
  2. @Foo(?) = {
  3.   i1  ; actual type. There can be only two types (Int32 or Float32), ~>, it's i1
  4.   i8* ; pointer to the actual instance
  5. }
  6.  
  7. ; Specialized Foo(Int32) definition
  8. @Foo(Int32) = {
  9.   i32 ; @bar : Int32
  10.   i64 ; @common : Int64
  11. }
  12.  
  13. ; Foo(Int32).initialize(@bar: Int32, @common : Int64)
  14. define void @Foo(Int32).initialize(noalias sret @Foo(Int32) %ptr, i32 %bar, i64 %common) {
  15.  
  16.   ; Store @bar
  17.   %bar.ptr = getelementptr @Foo(Int32), @Foo(Int32)* %ptr, i32 0
  18.   store i32 %bar, i32* %bar.ptr
  19.  
  20.   ; Store @common
  21.   %common.ptr = getelementptr @Foo(Int32), @Foo(Int32)* %ptr, i32 1
  22.   store i64 %common, i64* %common.ptr
  23.  
  24.   ret void
  25. }
  26.  
  27. ; Specialized Foo(Float32) definition
  28. @Foo(Float32) = {
  29.   float ; @bar : Float32
  30.   i64    ; @common : Int64
  31. }
  32.  
  33. ; Foo(Float32).initialize(@bar: Float32, @common : Int64)
  34. define void @Foo(Float32).initialize(noalias sret @Foo(Float32) %ptr, float %bar, i64 %common) {
  35.   ; ditto
  36. }
  37.  
  38. @Bar = {
  39.   @Foo(?), ; @foo : Foo(?)
  40. }
  41.  
  42. ; Bar.new(@foo : Foo(?))
  43. define void @Bar.initialize(noalias sret @Bar %ptr, @Foo(?)* %foo) {
  44.  
  45.   ; Store @foo : Foo(?)
  46.   %foo.ptr = getelementptr @Bar, @Bar* %ptr, i32 0
  47.   store @Foo(?) %foo, @Foo(?)* %foo.ptr
  48.  
  49.   ret void
  50. }
  51.  
  52. ; Return Foo(Int32)@bar : Int32 value
  53. define i32 @Foo(Int32)@bar(@Foo(?)* %foo.union) {
  54. %entry:
  55.   ; Get pointer to the type value
  56.   %type.ptr = getelementptr @Foo(?), @Foo(?)* %foo.union, i32 0
  57.   %type = load i1, i1* %type.ptr ; Load the type value
  58.  
  59.   ; Proceed if it's Foo(Int32), unreacheable otherwise
  60.   switch i1 %type, %unreacheable [ i1 0, %proceed, i1 1 %unreacheable ]
  61. %proceed:
  62.   %bar.ptr = getelementptr @Foo(Int32), @Foo(Int32)* %foo.union, i32 1
  63.   %bar = load i32, i32* %bar.ptr
  64.   ret %bar
  65. %unreacheable
  66.   unreacheable
  67. }
  68.  
  69. ; Return Foo(?)@common : Int64 value, which offset depends on its actual type
  70. define i64 @Foo(?)@common(@Foo(?)* %foo.union) {
  71. %entry:
  72.   ; Get pointer to the type value
  73.   %type.ptr = getelementptr @Foo(?), @Foo(?)* %foo.union, i32 0
  74.   %type = load i1, i1* %type.ptr ; Load the type value
  75.   switch i1 %type, %unreacheable [ i1 0, %Foo(Int32), i1 1, %Foo(Float32) ]
  76. %Foo(Int32):
  77.   %common.ptr = getelementptr @Foo(Int32), @Foo(Int32)* %foo.union, i32 1
  78.   %common = load i64, i64* %common.ptr
  79.   ret %common
  80. %Foo(Float32):
  81.   %common.ptr = getelementptr @Foo(Float32), @Foo(Float32)* %foo.union, i32 1
  82.   %common = load i64, i64* %common.ptr
  83.   ret %common
  84. %unreacheable
  85.   unreacheable
  86. }
  87.  
  88. ; Main (entry) function
  89. define i32 @main() {
  90.   ; Skip a & b example
  91.  
  92.   %foo.union = alloca @Foo(?) ; Allocate Foo(?)
  93.   %foo = alloca @Foo(Int32)   ; Allocate Foo(Int32), as revealed by the compiler
  94.  
  95.   ; Put the actual Foo type (which is 1st = 0) into the union
  96.   %foo.union.type.ptr = getelementptr @Foo(?), @Foo(?)* %foo.union, i32 0
  97.   store i1 0, i1* %foo.union.type.ptr
  98.  
  99.   ; Put the actual Foo(Int32) instance into the union
  100.   %foo.union.instance.ptr = getelementptr @Foo(?), @Foo(?)* %foo.union, i32 1
  101.   store i8* %foo, i8* %foo.union.instance.ptr
  102.  
  103.   ; Initialize @foo : Foo(Int32)
  104.   call @Foo(Int32).initialize(@Foo(Int32)* %foo, i32 42, i64 100)
  105.  
  106.   %baz = alloca @Baz ; Allocate Baz
  107.  
  108.   ; Initialize baz : Baz
  109.   call @Baz.initialize(@Baz* %baz, @Foo(?)* %foo.union)
  110.  
  111.   ; Get the baz.foo pointer of type Foo(?)
  112.   %baz.foo.ptr = getelementptr @Baz, @Baz* %baz, i32 0
  113.  
  114.   ; Load baz.foo.bar
  115.   %a = call i32 @Foo(Int32)@bar(%baz.foo.ptr)
  116.  
  117.   ; Load baz.foo.common
  118.   %b = call i64 @Foo(?)@common(%baz.foo.ptr)
  119.  
  120.   ; Sum
  121.   %sum = add i64 %a, %b
  122.  
  123.   ; Puts
  124.   call @puts(i64 %sum)
  125.  
  126.   ; Return
  127.   ret 0
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement