[llvm-dev] Creating a global variable for a struct array
Tim Northover via llvm-dev
llvm-dev at lists.llvm.org
Wed Sep 30 02:09:08 PDT 2020
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.
More information about the llvm-dev
mailing list