Johan Wehrli via llvm-dev
2016-Aug-24 11:27 UTC
[llvm-dev] Change GlobalValue Type/Initializer
Hi, I am trying to update the initializer of a global value and I have encounter two issues: The first one is that I can not change the type of the global value. Let say that I have the following variable: @.str = private unnamed_addr constant [6 x i8] c”Test0A\00", align 1 How can I change the ”Test0A\00” to ”OtherTest0A\00”. Is this possible? I know that you can change the initializer with setInitializer but the global value’s type will not be the same. For now, the only way I found was to create a new global value and to change all theses uses. The second problem that I have is with the function Verifier::visitGlobalVariable. Sometimes, the verifier tells me that the initializer type does not match the global variable type even when this is the case. This function will do the following check: if (GV.hasInitializer()) { Assert(GV.getInitializer()->getType() == GV.getType()->getElementType(), "Global variable initializer type does not match global " "variable type!", &GV); But I did not find any overload for the comparator operator (in the type class). So this will only check if the addresses of the type are the same and not if this is the same type. To have the same type, I need to create the initializer with the same context as the global variable: LLVMContext &C = gv->getContext(); ConstantDataArray *data = cast<ConstantDataArray>(ConstantDataArray::getString(C, ref, false)); gv->setInitializer(data); Is this normal? I am missing something? Greetings, JOHAN WEHRLI - Product and development Rue Galilée 7 CH-1400 Yverdon-les-Bains https://strong.codes <https://strong.codes/> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160824/a094b24c/attachment.html>
Mehdi Amini via llvm-dev
2016-Aug-24 14:55 UTC
[llvm-dev] Change GlobalValue Type/Initializer
> On Aug 24, 2016, at 4:27 AM, Johan Wehrli via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi, > > I am trying to update the initializer of a global value and I have encounter two issues: > > The first one is that I can not change the type of the global value. Let say that I have the following variable: @.str = private unnamed_addr constant [6 x i8] c”Test0A\00", align 1 > > How can I change the ”Test0A\00” to ”OtherTest0A\00”. Is this possible? I know that you can change the initializer with setInitializer but the global value’s type will not be the same. > For now, the only way I found was to create a new global value and to change all theses uses.That’s the right thing to do: you need to create a new GV and replace the old one with the new one.> > The second problem that I have is with the function Verifier::visitGlobalVariable. Sometimes, the verifier tells me that the initializer type does not match the global variable type even when this is the case. > > This function will do the following check: > > if (GV.hasInitializer()) { > Assert(GV.getInitializer()->getType() == GV.getType()->getElementType(), > "Global variable initializer type does not match global " > "variable type!", > &GV); > > But I did not find any overload for the comparator operator (in the type class). So this will only check if the addresses of the type are the same and not if this is the same type. > > To have the same type, I need to create the initializer with the same context as the global variable: > > LLVMContext &C = gv->getContext(); > ConstantDataArray *data = cast<ConstantDataArray>(ConstantDataArray::getString(C, ref, false)); > gv->setInitializer(data); > > Is this normal? I am missing something?Yes it is normal you *have* to use the same context to manipulate IR inside a Module. The context owns the module and destroying the context destroys everything that is created in the context. It is not clear to me what other context you could even manage to use here conceptually. Anyway it is rooted quite deeply in LLVM that type can be compared by pointer thanks to this context uniquing. You can have different LLVMContext when you manipulate multiple Modules (Context are here to enable multi-threading environment), but you won’t be able to compare type from one module to the other for example. — Mehdi -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160824/c58ab763/attachment.html>
Johan Wehrli via llvm-dev
2016-Aug-24 15:18 UTC
[llvm-dev] Change GlobalValue Type/Initializer
Hi Mehdi, Thank you for you answer.> Yes it is normal you *have* to use the same context to manipulate IR inside a Module. The context owns the module and destroying the context destroys everything that is created in the context. It is not clear to me what other context you could even manage to use here conceptually.Actually I was using llvm::getGlobalContext() in order to get the context. It seems that this is not the same context as gv->getContext(). Greetings, JOHAN WEHRLI - Product and development Rue Galilée 7 CH-1400 Yverdon-les-Bains https://strong.codes <https://strong.codes/>> On 24 Aug 2016, at 16:55, Mehdi Amini <mehdi.amini at apple.com> wrote: > >> >> On Aug 24, 2016, at 4:27 AM, Johan Wehrli via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Hi, >> >> I am trying to update the initializer of a global value and I have encounter two issues: >> >> The first one is that I can not change the type of the global value. Let say that I have the following variable: @.str = private unnamed_addr constant [6 x i8] c”Test0A\00", align 1 >> >> How can I change the ”Test0A\00” to ”OtherTest0A\00”. Is this possible? I know that you can change the initializer with setInitializer but the global value’s type will not be the same. >> For now, the only way I found was to create a new global value and to change all theses uses. > > That’s the right thing to do: you need to create a new GV and replace the old one with the new one. > > > >> >> The second problem that I have is with the function Verifier::visitGlobalVariable. Sometimes, the verifier tells me that the initializer type does not match the global variable type even when this is the case. >> >> This function will do the following check: >> >> if (GV.hasInitializer()) { >> Assert(GV.getInitializer()->getType() == GV.getType()->getElementType(), >> "Global variable initializer type does not match global " >> "variable type!", >> &GV); >> >> But I did not find any overload for the comparator operator (in the type class). So this will only check if the addresses of the type are the same and not if this is the same type. >> >> To have the same type, I need to create the initializer with the same context as the global variable: >> >> LLVMContext &C = gv->getContext(); >> ConstantDataArray *data = cast<ConstantDataArray>(ConstantDataArray::getString(C, ref, false)); >> gv->setInitializer(data); >> >> Is this normal? I am missing something? > > Yes it is normal you *have* to use the same context to manipulate IR inside a Module. The context owns the module and destroying the context destroys everything that is created in the context. It is not clear to me what other context you could even manage to use here conceptually. > Anyway it is rooted quite deeply in LLVM that type can be compared by pointer thanks to this context uniquing. > > You can have different LLVMContext when you manipulate multiple Modules (Context are here to enable multi-threading environment), but you won’t be able to compare type from one module to the other for example. > > — > Mehdi-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160824/710777c1/attachment.html>
Seemingly Similar Threads
- Change GlobalValue Type/Initializer
- [LLVMdev] How to cast Value* to ConstantDataArray*
- [LLVMdev] How to cast Value* to ConstantDataArray*
- Create a BlockAddress array from LLVM Pass
- [LLVMdev] Calling a function with a pointer to a global char array as argument