Nat! via llvm-dev
2015-Oct-27 11:39 UTC
[llvm-dev] How to create global symbol from record offset
I would like to create something like this (x86_64) .section __DATA,__data .align 4 _a: .long 18 .globl _b _b: .long 48 If you like to notice, there is no alignment between _a and _b. _b is basically offseting into a record structure. ---- When I use two discrete structs, I get .aligns and I also don't trust the tools to keep the two globals together. %struct.a = type { i32 } %struct.b = type { i32 } @a = global %struct.a { i32 1 }, align 4 @b = global %struct.b { i32 848 }, align 4 ---- What I don't want is to introduce a global pointer like this %struct.c = type { %struct.a, %struct.b } %struct.a = type { i32 } %struct.b = type { i32 } @c = internal global %struct.c { %struct.a { i32 18 }, %struct.b { i32 48 } }, align 4 @p_b = global %struct.b* bitcast (i32* getelementptr inbounds (%struct.c* @c, i64 0, i32 1, i32 0) to %struct.b*), align 8 Thanks for any hints how to do this. Ciao Nat!
Joseph Tremoulet via llvm-dev
2015-Oct-27 15:17 UTC
[llvm-dev] How to create global symbol from record offset
Would a global alias be sufficient for you? E.g. -- %struct.a = type { i32 } %struct.b = type { i32 } %struct.c = type { %struct.a, %struct.b } @c = internal global %struct.c { %struct.a { i32 18 }, %struct.b { i32 48 } }, align 4 @a = alias %struct.a, %struct.a* getelementptr inbounds (%struct.c, %struct.c* @c, i64 0, i32 0) @b = alias %struct.b, %struct.b* getelementptr inbounds (%struct.c, %struct.c* @c, i64 0, i32 1) -- Gives -- .data .align 4 # @c c: .long 18 # 0x12 .long 48 # 0x30 .globl a a = c .globl b b = c+4 -- Where @a and @b can be referenced from code without introducing the extra level of indirection: -- declare void @bar(%struct.a *, %struct.b *) define void @foo() { call void @bar(%struct.a* @a, %struct.b* @b) ret void } -- foo: # @foo .Ltmp0: .seh_proc foo # BB#0: subq $40, %rsp .Ltmp1: .seh_stackalloc 40 .Ltmp2: .seh_endprologue leaq a(%rip), %rcx leaq b(%rip), %rdx callq bar -- -----Original Message----- From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Nat! via llvm-dev Sent: Tuesday, October 27, 2015 7:39 AM To: llvm-dev <llvm-dev at lists.llvm.org> Subject: [llvm-dev] How to create global symbol from record offset I would like to create something like this (x86_64) .section __DATA,__data .align 4 _a: .long 18 .globl _b _b: .long 48 If you like to notice, there is no alignment between _a and _b. _b is basically offseting into a record structure. ---- When I use two discrete structs, I get .aligns and I also don't trust the tools to keep the two globals together. %struct.a = type { i32 } %struct.b = type { i32 } @a = global %struct.a { i32 1 }, align 4 @b = global %struct.b { i32 848 }, align 4 ---- What I don't want is to introduce a global pointer like this %struct.c = type { %struct.a, %struct.b } %struct.a = type { i32 } %struct.b = type { i32 } @c = internal global %struct.c { %struct.a { i32 18 }, %struct.b { i32 48 } }, align 4 @p_b = global %struct.b* bitcast (i32* getelementptr inbounds (%struct.c* @c, i64 0, i32 1, i32 0) to %struct.b*), align 8 Thanks for any hints how to do this. Ciao Nat! _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2flists.llvm.org%2fcgi-bin%2fmailman%2flistinfo%2fllvm-dev%0a&data=01%7c01%7cjotrem%40microsoft.com%7c1665ed437fbb4f2c11e908d2dec349b7%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=KFqEyl3mrf9p4HCmo%2f9mbsgJUl%2bzEAsfW4ucRMwJ%2few%3d
Nat! via llvm-dev
2015-Oct-31 10:19 UTC
[llvm-dev] How to create global symbol from record offset
I have a problem getting this implemented, the following small test program invariably crashes with. Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast Help would be greatly appreciated. --- #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Constants.h" int main(int argc, char const *argv[]) { llvm::LLVMContext &Context = llvm::getGlobalContext(); llvm::Constant *Fields[3]; Fields[0] = llvm::ConstantInt::get(Context, llvm::APInt( 32, 18, true)); Fields[1] = llvm::ConstantInt::get(Context, llvm::APInt( 32, 48, true)); Fields[2] = llvm::ConstantInt::get(Context, llvm::APInt( 32, 1848, true)); llvm::Type * FieldTypes[3]; FieldTypes[0] = llvm::Type::getInt32Ty( Context); FieldTypes[1] = llvm::Type::getInt32Ty( Context); FieldTypes[2] = llvm::Type::getInt32Ty( Context); llvm::StructType *RecordType; RecordType = llvm::StructType::create(FieldTypes,"foo"); llvm::Constant *Foo; Foo = llvm::ConstantStruct::get( RecordType, Fields); llvm::Constant *Two; Two = llvm::ConstantInt::get( llvm::Type::getInt32Ty( Context), 2); llvm::Constant *C; C = llvm::ConstantExpr::getGetElementPtr( RecordType, Foo, Two); return( 0); } --- clang -g -std=c++14 `llvm-config --cflags` -c foo.cpp clang++ foo.o `llvm-config --cxxflags --ldflags --libs core --system-libs` -o foo