Niddodi, Chaitra via llvm-dev
2020-Oct-01 03:50 UTC
[llvm-dev] Creating a global variable for a struct array
Thank you very much. The code to initialize h1 to non-zero values was what I was looking for. It's almost working except for a type mismatch wrt dlist* llist field of h1. dlist static_lst[10] = { {1, 5, NULL}, ... }; dhash h1[10] = {{"myfile.txt", static_lst}, ... }; Along the lines of the code you had sent, I created a GlobalVariable* llist of type [10 x %struct.dlist]* for the field dlist* llist in h1. But this results in an LLVM ERROR: Type mismatch in constant table!. How do I fix this error ? Thanks, Chaitra ________________________________ From: Tim Northover <t.p.northover at gmail.com> Sent: Wednesday, September 30, 2020 4:09 AM To: Niddodi, Chaitra <chaitra at illinois.edu> Cc: llvm-dev at lists.llvm.org <llvm-dev at lists.llvm.org> Subject: Re: [llvm-dev] Creating a global variable for a struct array On Wed, 30 Sep 2020 at 01:47, Niddodi, Chaitra <chaitra at illinois.edu> wrote:> Let me clarify my question.Some C or C++ code showing what you want to do in LLVM would really be most helpful there.> I have a struct array h1 as follows: > dhash h1[10]; > > I want to get a Constant* to variable h1.Do you mean you want to create a GlobalVariable "h1" with a Constant* initializer? If so, we need to know what you want to initialize it to. Writing IR for dhash h1[10] = {0}; would be very different from dlist static_lst = {1, 5, NULL}; dhash h1[10] = {{"myfile.txt", &static_list}, 0 };> It looks like I can use ConstantStruct::get(StructType*, ArrayRef<Constant *>) to do this.It would be involved in the second example above, but because h1 is an array you'd need a whole ContantArray of them.> My question is how to get the second argument of type ArrayRef<Constant *> from the above variable h1.In the second example I gave above you'd write something like // First create a global variable to hold the filename string. Constant *FileNameInit = ConstantDataArray::getString("myfile.txt"); Constant *FileName = new GlobalVariable(Module, FileNameInit->getType(), true, GlobalValue::PrivateLinkage, FileNameInit, ".str"); FileName = ConstantExpr::getBitCast(FileName, Int8PtrTy); // Look up the previously created static_list variable (code to produce it omitted for brevity). GlobalVariable *StaticList = Module->getNamedValue("static_list"); // Create the ConstantStruct that will initialize the first element of the array. Constant *FirstInitArr[] = { FileName, StaticList }; ConstantStruct *FirstInit = ConstantStruct::get(DHashTy, FirstInitArr); // Create an all-zero struct for the rest of the array. Constant *OtherInits = ConstantAggregateZero::get(DHashTy); // Create the global variable. Type *H1Ty = ArrayType::get(DHashTy, 10); Constant *H1InitArr[] = {FirstInit, OtherInits, OtherInits, OtherInits, OtherInits, OtherInits, OtherInits, OtherInits, OtherInits, OtherInits}; Constant *H1Init = ConstantArray::get(H1Ty, H1InitArr); GlobalVariable *H1 = new GlobalVariable(Module, H1Ty, false, GlobalVariable::ExternalLinkage, H1Init, "h1"); which would produce LLVM IR looking like this: @.str = private unnamed_addr constant [11 x i8] c"myfile.txt\00" @h1 = global [10 x %dhash] [%dhash { i8* bitcast([11 x i8]* @.str to i8*), %dlist* @static_list}, %dhash zeroinitializer, %dhash zeroinitializer, ...} I think the critical point that might be missing is that if you have a pointer you want to initialize to something other than NULL (in this case the filename and the dlist pointer), you're going to need a separate global variable that provides real storage for it. You can't create a ConstantStruct and use that directly because a ConstantStruct has %struct type, but your field is %struct*. Or I might have gone off at a wild tangent that has nothing to do with what you're asking. Cheers. Tim. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201001/9f959c9f/attachment.html>
Tim Northover via llvm-dev
2020-Oct-01 08:15 UTC
[llvm-dev] Creating a global variable for a struct array
On Thu, 1 Oct 2020 at 04:50, Niddodi, Chaitra <chaitra at illinois.edu> wrote:> Along the lines of the code you had sent, I created a GlobalVariable* llist of type [10 x %struct.dlist]* for the field dlist* llist in h1. But this results in an LLVM ERROR: Type mismatch in constant table!.The type you pass to GlobalVariable's constructor for that variable should be "[10 x %struct.dlist]" because that's what you want storage for. Then the GlobalVariable itself will be a Constant of type "[10 x %struct.dlist]*". Since that error is coming from the bitcode reader, I suspect you might have built a version of LLVM without assertions enabled (fixed with -DLLVM_ENABLE_ASSERTIONS=ON in CMake, or a debug build) so the crash you'd normally get when actually constructing the constants is deferred. Hopefully if you turn assertions on it'll point to the exact line the error is happening on and be much easier to fix. Cheers. Tim.
Niddodi, Chaitra via llvm-dev
2020-Oct-01 15:00 UTC
[llvm-dev] Creating a global variable for a struct array
>The type you pass to GlobalVariable's constructor for that variableshould be "[10 x %struct.dlist]" because that's what you want storage for. Then the GlobalVariable itself will be a Constant of type "[10 x %struct.dlist]*". Yes, I verified that this is the case. I enabled assertions and the error seems to occur while creating GlobalVariable for both struct dhash and struct dlist. Here is a simpler version of the code causing error: //struct dhash typedef struct dhash{ char* filenm; int n; }dhash; //create global variable to hold filename string Constant *filenmInit = ConstantDataArray::getString(M.getContext(), "myfile.txt"); Constant *filenmConst = new GlobalVariable(M, filenmInit->getType(), false, GlobalVariable::ExternalLinkage, filenmInit, ".filenm"); //create global variable for int Constant* intInit = ConstantInt::get(Type::getInt32Ty(M.getContext()), 10); Constant* intConst = new GlobalVariable(M, intInit->getType(), false, GlobalVariable::ExternalLinkage, intInit, ".int"); //create ConstantStruct for each hashtable entry Constant *dhashInit[] = {filenmConst, intConst}; Constant *dhashConst = ConstantStruct::get(dhashTy, dhashInit); Constant* htabInitArr[2]; htabInitArr[0] = dhashConst; htabInitArr[1] = dhashConst; ArrayType *htabTy = ArrayType::get(dhashTy, 2); Constant *htabInit = ConstantArray::get(htabTy, makeArrayRef(htabInitArr,2)); GlobalVariable *htabConst = new GlobalVariable(M, htabInit->getType(), false, GlobalVariable::ExternalLinkage, htabInit, "htab"); Here is the error message: opt: /home/chaitra/llvm-5-src/lib/IR/Constants.cpp:879: llvm::ConstantAggregate::ConstantAggregate(llvm::CompositeType*, llvm::Value::ValueTy, llvm::ArrayRef<llvm::Constant*>): Assertion `V[I]->getType() == T->getTypeAtIndex(I) && "Initializer for composite element doesn't match!"' failed. #0 0x0000000001e558fa (opt+0x1e558fa) #1 0x0000000001e5366e (opt+0x1e5366e) #2 0x0000000001e537e2 (opt+0x1e537e2) #3 0x00007f8a98a55390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390) #4 0x00007f8a977c7438 gsignal /build/glibc-e6zv40/glibc-2.23/signal/../sysdeps/unix/sysv/linux/raise.c:54:0 #5 0x00007f8a977c903a abort /build/glibc-e6zv40/glibc-2.23/stdlib/abort.c:91:0 #6 0x00007f8a977bfbe7 __assert_fail_base /build/glibc-e6zv40/glibc-2.23/assert/assert.c:92:0 #7 0x00007f8a977bfc92 (/lib/x86_64-linux-gnu/libc.so.6+0x2dc92) #8 0x000000000189c982 (opt+0x189c982) #9 0x000000000189cc7c (opt+0x189cc7c) #10 0x00000000018a93e0 (opt+0x18a93e0) #11 0x00000000018a95f3 (opt+0x18a95f3) #12 0x00007f8a9758e59a iospecns::storage_bitcode::runOnModule(llvm::Module&) (/home/chaitra/Desktop/iospec_test/test/build/proj/libstorage_bitcode.so+0x459a) #13 0x00000000019473ad (opt+0x19473ad) #14 0x00000000006db61c (opt+0x6db61c) #15 0x00007f8a977b2840 __libc_start_main /build/glibc-e6zv40/glibc-2.23/csu/../csu/libc-start.c:325:0 #16 0x0000000000747519 (opt+0x747519) Stack dump: 0. Program arguments: opt -load /home/chaitra/Desktop/iospec_test/test/build/proj/libstorage_bitcode.so -storage_bitcode 1. Running pass 'storage_bitcode' on module '<stdin>'. Aborted (core dumped) Thanks, Chaitra -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201001/872534bf/attachment.html>