From: Erick Tryzelaar Date: Sun, 28 Feb 2010 09:46:13 +0000 (+0000) Subject: Add support for global variables in an address space for llvm-c and ocaml. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=8e130b1d0d53346e05d0a1161a52c6d62de163c4 Add support for global variables in an address space for llvm-c and ocaml. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97377 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index 7017b4ada0d..16674274057 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -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" diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index c7fa30a96f2..48c6ccd648b 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -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. *) diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 3964ff7487f..d97523d60c6 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -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); diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 17bd99dacce..bdbf3f21f67 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -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); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index b15f039e38e..abf258391fc 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -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)); } diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml index 9a2f5475319..665c6f98b42 100644 --- a/test/Bindings/Ocaml/vmcore.ml +++ b/test/Bindings/Ocaml/vmcore.ml @@ -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 *)