OSDN Git Service

Add support for global variables in an address space for llvm-c and ocaml.
authorErick Tryzelaar <idadesub@users.sourceforge.net>
Sun, 28 Feb 2010 09:46:13 +0000 (09:46 +0000)
committerErick Tryzelaar <idadesub@users.sourceforge.net>
Sun, 28 Feb 2010 09:46:13 +0000 (09:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97377 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/ocaml/llvm/llvm.ml
bindings/ocaml/llvm/llvm.mli
bindings/ocaml/llvm/llvm_ocaml.c
include/llvm-c/Core.h
lib/VMCore/Core.cpp
test/Bindings/Ocaml/vmcore.ml

index 7017b4a..1667427 100644 (file)
@@ -371,8 +371,14 @@ external set_global_constant : bool -> llvalue -> unit
 (*--... Operations on global variables .....................................--*)
 external declare_global : lltype -> string -> llmodule -> llvalue
                         = "llvm_declare_global"
+external declare_qualified_global : lltype -> string -> int -> llmodule ->
+                                    llvalue
+                                  = "llvm_declare_qualified_global"
 external define_global : string -> llvalue -> llmodule -> llvalue
                        = "llvm_define_global"
+external define_qualified_global : string -> llvalue -> int -> llmodule ->
+                                   llvalue
+                                 = "llvm_define_qualified_global"
 external lookup_global : string -> llmodule -> llvalue option
                        = "llvm_lookup_global"
 external delete_global : llvalue -> unit = "llvm_delete_global"
index c7fa30a..48c6ccd 100644 (file)
@@ -1003,19 +1003,35 @@ external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
 (** {7 Operations on global variables} *)
 
 (** [declare_global ty name m] returns a new global variable of type [ty] and
-    with name [name] in module [m]. If such a global variable already exists,
-    it is returned. If the type of the existing global differs, then a bitcast
-    to [ty] is returned. *)
+    with name [name] in module [m] in the default address space (0). If such a
+    global variable already exists, it is returned. If the type of the existing
+    global differs, then a bitcast to [ty] is returned. *)
 external declare_global : lltype -> string -> llmodule -> llvalue
                         = "llvm_declare_global"
 
+(** [declare_qualified_global ty name as m] returns a new global variable of
+    type [ty] and with name [name] in module [m] in the address space [as]. If
+    such a global variable already exists, it is returned. If the type of the
+    existing global differs, then a bitcast to [ty] is returned. *)
+external declare_qualified_global : lltype -> string -> int -> llmodule ->
+                                    llvalue
+                                  = "llvm_declare_qualified_global"
+
 (** [define_global name init m] returns a new global with name [name] and
-    initializer [init] in module [m]. If the named global already exists, it is
-    renamed.
+    initializer [init] in module [m] in the default address space (0). If the
+    named global already exists, it is renamed.
     See the constructor of [llvm::GlobalVariable]. *)
 external define_global : string -> llvalue -> llmodule -> llvalue
                        = "llvm_define_global"
 
+(** [define_qualified_global name init as m] returns a new global with name
+    [name] and initializer [init] in module [m] in the address space [as]. If
+    the named global already exists, it is renamed.
+    See the constructor of [llvm::GlobalVariable]. *)
+external define_qualified_global : string -> llvalue -> int -> llmodule ->
+                                   llvalue
+                                 = "llvm_define_qualified_global"
+
 (** [lookup_global name m] returns [Some g] if a global variable with name
     [name] exists in module [m]. If no such global exists, returns [None].
     See the [llvm::GlobalVariable] constructor. *)
index 3964ff7..d97523d 100644 (file)
@@ -697,6 +697,20 @@ CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
   return LLVMAddGlobal(M, Ty, String_val(Name));
 }
 
+/* lltype -> string -> int -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
+                                                    value AddressSpace,
+                                                    LLVMModuleRef M) {
+  LLVMValueRef GlobalVar;
+  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
+    if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
+      return LLVMConstBitCast(GlobalVar,
+                              LLVMPointerType(Ty, Int_val(AddressSpace)));
+    return GlobalVar;
+  }
+  return LLVMAddGlobal(M, Ty, String_val(Name));
+}
+
 /* string -> llmodule -> llvalue option */
 CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
   CAMLparam1(Name);
@@ -718,6 +732,19 @@ CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
   return GlobalVar;
 }
 
+/* string -> llvalue -> int -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
+                                                   LLVMValueRef Initializer,
+                                                   value AddressSpace,
+                                                   LLVMModuleRef M) {
+  LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
+                                                       LLVMTypeOf(Initializer),
+                                                       String_val(Name),
+                                                       Int_val(AddressSpace));
+  LLVMSetInitializer(GlobalVar, Initializer);
+  return GlobalVar;
+}
+
 /* llvalue -> unit */
 CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
   LLVMDeleteGlobal(GlobalVar);
index 17bd99d..bdbf3f2 100644 (file)
@@ -671,6 +671,9 @@ void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes);
 
 /* Operations on global variables */
 LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+                                         const char *Name,
+                                         unsigned AddressSpace);
 LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name);
 LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
 LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M);
index b15f039..abf2583 100644 (file)
@@ -1153,6 +1153,14 @@ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) {
                                  GlobalValue::ExternalLinkage, 0, Name));
 }
 
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+                                         const char *Name,
+                                         unsigned AddressSpace) {
+  return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false,
+                                 GlobalValue::ExternalLinkage, 0, Name, false,
+                                 AddressSpace));
+}
+
 LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) {
   return wrap(unwrap(M)->getNamedGlobal(Name));
 }
index 9a2f547..665c6f9 100644 (file)
@@ -493,28 +493,46 @@ let test_global_variables () =
   let (++) x f = f x; x in
   let fourty_two32 = const_int i32_type 42 in
 
-  (* RUN: grep {GVar01.*external} < %t.ll
-   *)
-  group "declarations";
-  insist (None == lookup_global "GVar01" m);
-  let g = declare_global i32_type "GVar01" m in
-  insist (is_declaration g);
-  insist (pointer_type float_type ==
-            type_of (declare_global float_type "GVar01" m));
-  insist (g == declare_global i32_type "GVar01" m);
-  insist (match lookup_global "GVar01" m with Some x -> x = g
-                                            | None -> false);
+  group "declarations"; begin
+    (* RUN: grep {GVar01.*external} < %t.ll
+     *)
+    insist (None == lookup_global "GVar01" m);
+    let g = declare_global i32_type "GVar01" m in
+    insist (is_declaration g);
+    insist (pointer_type float_type ==
+              type_of (declare_global float_type "GVar01" m));
+    insist (g == declare_global i32_type "GVar01" m);
+    insist (match lookup_global "GVar01" m with Some x -> x = g
+                                              | None -> false);
+
+    insist (None == lookup_global "QGVar01" m);
+    let g = declare_qualified_global i32_type "QGVar01" 3 m in
+    insist (is_declaration g);
+    insist (qualified_pointer_type float_type 3 ==
+              type_of (declare_qualified_global float_type "QGVar01" 3 m));
+    insist (g == declare_qualified_global i32_type "QGVar01" 3 m);
+    insist (match lookup_global "QGVar01" m with Some x -> x = g
+                                              | None -> false);
+  end;
   
-  (* RUN: grep {GVar02.*42} < %t.ll
-   * RUN: grep {GVar03.*42} < %t.ll
-   *)
-  group "definitions";
-  let g = define_global "GVar02" fourty_two32 m in
-  let g2 = declare_global i32_type "GVar03" m ++
+  group "definitions"; begin
+    (* RUN: grep {GVar02.*42} < %t.ll
+     * RUN: grep {GVar03.*42} < %t.ll
+     *)
+    let g = define_global "GVar02" fourty_two32 m in
+    let g2 = declare_global i32_type "GVar03" m ++
+           set_initializer fourty_two32 in
+    insist (not (is_declaration g));
+    insist (not (is_declaration g2));
+    insist ((global_initializer g) == (global_initializer g2));
+
+    let g = define_qualified_global "QGVar02" fourty_two32 3 m in
+    let g2 = declare_qualified_global i32_type "QGVar03" 3 m ++
            set_initializer fourty_two32 in
-  insist (not (is_declaration g));
-  insist (not (is_declaration g2));
-  insist ((global_initializer g) == (global_initializer g2));
+    insist (not (is_declaration g));
+    insist (not (is_declaration g2));
+    insist ((global_initializer g) == (global_initializer g2));
+  end;
 
   (* RUN: grep {GVar04.*thread_local} < %t.ll
    *)