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