Iulia Stirb via llvm-dev
2019-Aug-31 13:54 UTC
[llvm-dev] Get constants of undefined types in IR
Hello all, I would like to obtain a constant that is initialized with a value of type cpu_set_t, a type which is defined by Pthreads. The problem is that a variable of this type cannot be cast to an int value, even in C source code. I tried get methods from Constant or ConstantInt classes, but with no result. How can I obtain such constant object in IR? Thank you, Iulia -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190831/3e5e8e50/attachment.html>
Tim Northover via llvm-dev
2019-Sep-02 06:41 UTC
[llvm-dev] Get constants of undefined types in IR
Hi Iulia, On Sat, 31 Aug 2019 at 14:55, Iulia Stirb via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I would like to obtain a constant that is initialized with a value of type cpu_set_t, a type which is defined by Pthreads. The problem is that a variable of this type cannot be cast to an int value, even in C source code. I tried get methods from Constant or ConstantInt classes, but with no result.cpu_set_t appears to be a Linux-specific concept, which actually makes this slightly easier because it would otherwise be highly platform specific. This version looks reasonable: https://android.googlesource.com/platform/bionic/+/f664034/libc/include/sched.h. It's not 100% canonical since it's outside the kernel, but has the advantage that all he details are in a single file. That file tells you a couple of things: 1. The underlying type is a struct containing an array of "unsigned long" sufficient for 32 or 1024 CPUs depending on the host. 2. The __CPU_ELT and __CPU_MASK defines tell you how that array corresponds to each particular numbered CPU (i.e. which element and which bit of that element you'd toggle to set CPU N).>From that it's fairly easy to check that Clang turns the type intosomething like "{ [16 x i64] }" and so that's what you'll have to construct piece by piece. 1. Work out the contents of each integer element according to those rules and get them with a ConstantInt::get. 2. Put them together into an array with ConstantArray::get 3. Put that array into a struct with ConstantStruct::get. Cheers. Tim.
Tim Northover via llvm-dev
2019-Sep-03 17:15 UTC
[llvm-dev] Get constants of undefined types in IR
Adding llvm-dev back. On Tue, 3 Sep 2019 at 18:02, Iulia Stirb <iulia_s24 at yahoo.com> wrote:> Thank very much you for your answer. Following the indications in your > mail, I obtained one of the 16th elements as below: > > static cpu_set_t getCpuAffinityElement(cpu_set_t affinity, int index) { > cpu_set_t mask; > CPU_ZERO(&mask); > for(int i = index * sizeof(unsigned long); i < (index + 1) * sizeof( > unsigned long); i++) { > CPU_SET(i,&mask); > } > CPU_AND(&affinity, &affinity, &mask); > return affinity; > } >That looks like a weird function, but it’s just within the realms of plausible so I’ll assume you know what you’re doing.>The problem is that the element is of type cpu_set_t and cannot be> converted to unsigned long. So, when I try to get the ConstantInt object > like below, I get an error saying that I cannot pass a cpu_set_t parameter > as second parameter of get method. > ConstantInt * elem = ConstantInt::get(Type::getInt64Ty(I.getContext > ()),affinityElement,false); >To use a real cpu_set_t from the host as part of a. ConstantInt like that you’ll have to look at its actual definition and access something like affinityElement.__bits[0]. The exact internals may vary with the header you’re using, but you’re fundamentally trying to do something ABI specific so you will have to get your hands dirty.> What I need is to insert in IR a call that has a cpu_set_t parameter, and > the parameter is already set (so I don't need to construct it). >An alternative might be to pass a pointer to the cpu_set_t you created above into the Module somehow (a global might work). It would sidestep the tricky annoying API for Constants in LLVM, and possibly even be a buffer against the structure changing in future. Cheers. Tim. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190903/f05ced3c/attachment-0001.html>
Iulia Stirb via llvm-dev
2019-Sep-03 18:39 UTC
[llvm-dev] Get constants of undefined types in IR
Hi Tim, My mistake not including the llvm-dev, excuse me. affinityElement.__bits[0] worked fine for me, thank you. I am new in using the API for Constants and I am facing the error "incomplete type is not allowed" on the last last of below code: Type * ET = IntegerType::getInt64Ty(I.getContext()); unsigned long size = cpuAffinityVector.size(); ArrayType * AT = ArrayType::get(ET,size); Internet gives different solutions for this error but none of them was appropriate for this case. Could you please help? Regards,Iulia On Tuesday, September 3, 2019, 8:15:26 PM GMT+3, Tim Northover <t.p.northover at gmail.com> wrote: Adding llvm-dev back. On Tue, 3 Sep 2019 at 18:02, Iulia Stirb <iulia_s24 at yahoo.com> wrote: Thank very much you for your answer. Following the indications in your mail, I obtained one of the 16th elements as below: static cpu_set_t getCpuAffinityElement(cpu_set_t affinity, int index) { cpu_set_t mask; CPU_ZERO(&mask); for(int i = index * sizeof(unsigned long); i < (index + 1) * sizeof(unsigned long); i++) { CPU_SET(i,&mask); } CPU_AND(&affinity, &affinity, &mask); return affinity; } That looks like a weird function, but it’s just within the realms of plausible so I’ll assume you know what you’re doing. The problem is that the element is of type cpu_set_t and cannot be converted to unsigned long. So, when I try to get the ConstantInt object like below, I get an error saying that I cannot pass a cpu_set_t parameter as second parameter of get method.ConstantInt * elem = ConstantInt::get(Type::getInt64Ty(I.getContext()),affinityElement,false); To use a real cpu_set_t from the host as part of a. ConstantInt like that you’ll have to look at its actual definition and access something like affinityElement.__bits[0]. The exact internals may vary with the header you’re using, but you’re fundamentally trying to do something ABI specific so you will have to get your hands dirty. What I need is to insert in IR a call that has a cpu_set_t parameter, and the parameter is already set (so I don't need to construct it). An alternative might be to pass a pointer to the cpu_set_t you created above into the Module somehow (a global might work). It would sidestep the tricky annoying API for Constants in LLVM, and possibly even be a buffer against the structure changing in future. Cheers. Tim. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190903/9cce31e9/attachment.html>