Emma Luciano via llvm-dev
2020-Jun-03 09:52 UTC
[llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder
I don't think it's the same problem as you described. By printing I
meant
calling printf function and passing my global variable as one of the
arguments.
My code:
Instruction* InstructionVisitor::incrementGlobalKey(Instruction* I) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
GlobalVariable* key =
I->getModule()->getNamedGlobal("globalKey");
if (key) {
LoadInst* load = Builder.CreateLoad(key);
Value* inc = Builder.CreateAdd(load, Builder.getInt64(1));
StoreInst* store = Builder.CreateStore(inc, key);
return store;
}
return I;
}
Instruction* InstructionVisitor::print(Instruction* I, const char* text,
Value* arg1, Value* arg2, Value* arg3, Value* arg4) {
Function* printfFn = I->getModule()->getFunction("printf");
if (printfFn) {
IRBuilder<> Builder(I->getContext());
Builder.SetInsertPoint(I->getNextNode());
Value* convertedText = Builder.CreateGlobalStringPtr(text);
std::vector <Value *> params;
params.push_back(convertedText);
if (arg1)
params.push_back(arg1);
if (arg2)
params.push_back(arg2);
if (arg3)
params.push_back(arg3);
if (arg4)
params.push_back(arg4);
return Builder.CreateCall(printfFn, params);
}
return I;
}
void InstructionVisitor::visitCallInst(CallInst &CI) {
if (isAllocationFn(&CI, &TLI)) {
Value* allocatedAddress = &CI;
Instruction* I = &CI;
Value* allocatedSize = I->getOperand(0);
Instruction* next = incrementGlobalKey(I);
GlobalVariable* key =
I->getModule()->getNamedGlobal("globalKey");
const char* message = "Allocated address: 0x%p, size: %d, key:
%lld\n";
print(next, message, allocatedAddress, allocatedSize, key->getOperand(0));
}
}
Code that I'm executing (source code) is:
int main()
{
char* buffer;
int size = 101;
buffer = new char[size];
printf("CHECK address: 0x%p, size: %d\n", buffer, size);
TestClass* test = new TestClass(1, 2);
printf("(CHECK address: 0x%p, size: %llu\n", test, sizeof(TestClass));
delete buffer;
delete test;
}
And program output after instrumentation:
Allocated address: 0x000001CD326C1B20, size: 101, key: 0
CHECK address: 0x000001CD326C1B20, size: 101
Allocated address: 0x000001CD326C1B90, size: 8, key: 0
CHECK address: 0x000001CD326C1B90, size: 8
Regards,
Emma Luciano
śr., 3 cze 2020 o 11:21 Eli Friedman <efriedma at quicinc.com> napisał(a):
> Suppose I have the following program:
>
>
>
> $ cat test.c
>
> int a = 0;
>
> int main() { a = 1; };
>
>
>
> Then I compile and run it:
>
> $ clang test.c
>
> $ ./a.out
>
>
>
> Then I print the contents of test.c again:
>
>
>
> $ cat test.c
>
> int a = 0;
>
> int main() { a = 1; }
>
>
>
> Why does it say “int a = 0;”? The program set it to 1, no?
>
>
>
> As far as I can tell, this is equivalent to your question… except it’s
> less obvious because the “source code” is an LLVM IR module in memory.
>
>
>
> Maybe you’re looking for ExecutionSession::lookup? The same way the
> tutorial computes the address of “main”, you can compute the runtime
> address of any other externally visible symbol.
>
>
>
> See also https://llvm.org/docs/ORCv2.html ,
> https://www.youtube.com/watch?v=hILdR8XRvdQ .
>
>
>
> -Eli
>
>
>
> *From:* llvm-dev <llvm-dev-bounces at lists.llvm.org> *On Behalf Of
*Emma
> Luciano via llvm-dev
> *Sent:* Wednesday, June 3, 2020 1:35 AM
> *To:* llvm-dev at lists.llvm.org
> *Subject:* [EXT] [llvm-dev] Fwd: I cannot change value of global variable
> in LLVM IR using IRBuilder
>
>
>
> Hi Everyone,
>
> I'm quite new to LLVM and I want to update value of global variable in
> LLVM IR. I created new global variable in ModulePass:
>
> bool runOnModule(llvm::Module &M) {
>
> IRBuilder<> Builder(M.getContext());
>
> Instruction *I = &*inst_begin(M.getFunction("main"));
>
> Builder.SetInsertPoint(I);
>
> M.getOrInsertGlobal("globalKey", Builder.getInt64Ty());
>
> GlobalVariable* gVar = M.getNamedGlobal("globalKey");
>
> gVar->setLinkage(GlobalValue::InternalLinkage);
>
> gVar->setAlignment(Align(8));
>
> gVar->setInitializer(Builder.getInt64(0));
>
> gVar->setConstant(false);
>
>
>
> for (Function &F : M.functions()) {
>
> InstructionVisitor visitor(DL,
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
>
> for (Instruction &I : instructions(F)) {
>
> visitor.visit(I);
>
> }
>
> }
>
> return true;
>
> }
>
> Later in InstructionVisitor I try to update it like that:
>
> IRBuilder<> Builder(I->getContext());
>
> Builder.SetInsertPoint(I->getNextNode());
>
>
>
> GlobalVariable* key =
I->getModule()->getNamedGlobal("globalKey");
>
>
>
> if (key) {
>
> LoadInst* load = Builder.CreateLoad(key);
>
> Value* inc = Builder.CreateAdd(load, Builder.getInt64(1));
>
> StoreInst* store = Builder.CreateStore(inc, key);
>
> }
>
> I print that global variable during execution of instrumented code. I
> access it's value by key->getOperand(0), but it's unchanged.
I'm using ORC
> JIT based on this tutorial:
> https://llvm.org/docs/tutorial/BuildingAJIT2.html and I run ModulePass
> from optimizeModule function from this tutorial.
>
> In IR it looks like that:
>
> %2 = load i64, i64* @globalKey
>
> %3 = add i64 %2, 1
>
> store i64 %3, i64* @globalKey
>
> I tried updating value of global variable, which was present in source
> code that I'm instrumenting. It didn't work either.
>
> I created corresponding stackoverflow topic:
>
https://stackoverflow.com/questions/62142574/how-can-i-update-global-variable-value-in-llvm-ir-using-irbuilder?fbclid=IwAR2X7uGhUjm_SN2UcxWYqaRQW2-cs6iPbMx2_tbKubeyYUkZ_pS6rkFfY9I
>
> I will be really grateful for help.
>
> Regards,
>
> Emma Luciano
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200603/13373eff/attachment.html>
David Blaikie via llvm-dev
2020-Jun-03 18:56 UTC
[llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder
I'm with Eli on this "GlobalVariable" is not the actual global variable in memory - it's the IR representation of the global variable before it is compiled to machine code & allocated in the running process - it always has the same value/isn't affected by the execution of loads and stores at runtime. On Wed, Jun 3, 2020 at 2:53 AM Emma Luciano via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > I don't think it's the same problem as you described. By printing I meant calling printf function and passing my global variable as one of the arguments. > > My code: > > Instruction* InstructionVisitor::incrementGlobalKey(Instruction* I) { > IRBuilder<> Builder(I->getContext()); > Builder.SetInsertPoint(I->getNextNode()); > > GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); > > if (key) { > LoadInst* load = Builder.CreateLoad(key); > Value* inc = Builder.CreateAdd(load, Builder.getInt64(1)); > StoreInst* store = Builder.CreateStore(inc, key); > return store; > } > return I; > } > > Instruction* InstructionVisitor::print(Instruction* I, const char* text, Value* arg1, Value* arg2, Value* arg3, Value* arg4) { > Function* printfFn = I->getModule()->getFunction("printf"); > if (printfFn) { > IRBuilder<> Builder(I->getContext()); > Builder.SetInsertPoint(I->getNextNode()); > Value* convertedText = Builder.CreateGlobalStringPtr(text); > > std::vector <Value *> params; > params.push_back(convertedText); > if (arg1) > params.push_back(arg1); > if (arg2) > params.push_back(arg2); > if (arg3) > params.push_back(arg3); > if (arg4) > params.push_back(arg4); > > return Builder.CreateCall(printfFn, params); > } > return I; > } > > void InstructionVisitor::visitCallInst(CallInst &CI) { > if (isAllocationFn(&CI, &TLI)) { > Value* allocatedAddress = &CI; > Instruction* I = &CI; > Value* allocatedSize = I->getOperand(0); > Instruction* next = incrementGlobalKey(I); > GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); > const char* message = "Allocated address: 0x%p, size: %d, key: %lld\n"; > print(next, message, allocatedAddress, allocatedSize, key->getOperand(0)); > } > } > > Code that I'm executing (source code) is: > int main() > { > char* buffer; > int size = 101; > buffer = new char[size]; > printf("CHECK address: 0x%p, size: %d\n", buffer, size); > TestClass* test = new TestClass(1, 2); > printf("(CHECK address: 0x%p, size: %llu\n", test, sizeof(TestClass)); > > delete buffer; > delete test; > } > > And program output after instrumentation: > > Allocated address: 0x000001CD326C1B20, size: 101, key: 0 > CHECK address: 0x000001CD326C1B20, size: 101 > Allocated address: 0x000001CD326C1B90, size: 8, key: 0 > CHECK address: 0x000001CD326C1B90, size: 8 > > Regards, > Emma Luciano > > śr., 3 cze 2020 o 11:21 Eli Friedman <efriedma at quicinc.com> napisał(a): >> >> Suppose I have the following program: >> >> >> >> $ cat test.c >> >> int a = 0; >> >> int main() { a = 1; }; >> >> >> >> Then I compile and run it: >> >> $ clang test.c >> >> $ ./a.out >> >> >> >> Then I print the contents of test.c again: >> >> >> >> $ cat test.c >> >> int a = 0; >> >> int main() { a = 1; } >> >> >> >> Why does it say “int a = 0;”? The program set it to 1, no? >> >> >> >> As far as I can tell, this is equivalent to your question… except it’s less obvious because the “source code” is an LLVM IR module in memory. >> >> >> >> Maybe you’re looking for ExecutionSession::lookup? The same way the tutorial computes the address of “main”, you can compute the runtime address of any other externally visible symbol. >> >> >> >> See also https://llvm.org/docs/ORCv2.html , https://www.youtube.com/watch?v=hILdR8XRvdQ . >> >> >> >> -Eli >> >> >> >> From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Emma Luciano via llvm-dev >> Sent: Wednesday, June 3, 2020 1:35 AM >> To: llvm-dev at lists.llvm.org >> Subject: [EXT] [llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder >> >> >> >> Hi Everyone, >> >> I'm quite new to LLVM and I want to update value of global variable in LLVM IR. I created new global variable in ModulePass: >> >> bool runOnModule(llvm::Module &M) { >> >> IRBuilder<> Builder(M.getContext()); >> >> Instruction *I = &*inst_begin(M.getFunction("main")); >> >> Builder.SetInsertPoint(I); >> >> M.getOrInsertGlobal("globalKey", Builder.getInt64Ty()); >> >> GlobalVariable* gVar = M.getNamedGlobal("globalKey"); >> >> gVar->setLinkage(GlobalValue::InternalLinkage); >> >> gVar->setAlignment(Align(8)); >> >> gVar->setInitializer(Builder.getInt64(0)); >> >> gVar->setConstant(false); >> >> >> >> for (Function &F : M.functions()) { >> >> InstructionVisitor visitor(DL, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F)); >> >> for (Instruction &I : instructions(F)) { >> >> visitor.visit(I); >> >> } >> >> } >> >> return true; >> >> } >> >> Later in InstructionVisitor I try to update it like that: >> >> IRBuilder<> Builder(I->getContext()); >> >> Builder.SetInsertPoint(I->getNextNode()); >> >> >> >> GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); >> >> >> >> if (key) { >> >> LoadInst* load = Builder.CreateLoad(key); >> >> Value* inc = Builder.CreateAdd(load, Builder.getInt64(1)); >> >> StoreInst* store = Builder.CreateStore(inc, key); >> >> } >> >> I print that global variable during execution of instrumented code. I access it's value by key->getOperand(0), but it's unchanged. I'm using ORC JIT based on this tutorial: https://llvm.org/docs/tutorial/BuildingAJIT2.html and I run ModulePass from optimizeModule function from this tutorial. >> >> In IR it looks like that: >> >> %2 = load i64, i64* @globalKey >> >> %3 = add i64 %2, 1 >> >> store i64 %3, i64* @globalKey >> >> I tried updating value of global variable, which was present in source code that I'm instrumenting. It didn't work either. >> >> I created corresponding stackoverflow topic: https://stackoverflow.com/questions/62142574/how-can-i-update-global-variable-value-in-llvm-ir-using-irbuilder?fbclid=IwAR2X7uGhUjm_SN2UcxWYqaRQW2-cs6iPbMx2_tbKubeyYUkZ_pS6rkFfY9I >> >> I will be really grateful for help. >> >> Regards, >> >> Emma Luciano > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Johannes Doerfert via llvm-dev
2020-Jun-03 20:17 UTC
[llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder
Right. Maybe I can put this a bit differently: A `llvm::GlobalVariable` is *not* the source variable but a pointer to the storage location of the source variable. This is the same for an `llvm::AllocaInst` that represents a local variable. Using a source variable means reading the `llvm::GlobalVariable` (or `llvm::AllocaInst`) that models the memory allocated for the source variable. Changing the variable corresponds to a write. Hope this helps :) On 6/3/20 1:56 PM, David Blaikie via llvm-dev wrote:> I'm with Eli on this "GlobalVariable" is not the actual global > variable in memory - it's the IR representation of the global variable > before it is compiled to machine code & allocated in the running > process - it always has the same value/isn't affected by the execution > of loads and stores at runtime. > > On Wed, Jun 3, 2020 at 2:53 AM Emma Luciano via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> I don't think it's the same problem as you described. By printing I meant calling printf function and passing my global variable as one of the arguments. >> >> My code: >> >> Instruction* InstructionVisitor::incrementGlobalKey(Instruction* I) { >> IRBuilder<> Builder(I->getContext()); >> Builder.SetInsertPoint(I->getNextNode()); >> >> GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); >> >> if (key) { >> LoadInst* load = Builder.CreateLoad(key); >> Value* inc = Builder.CreateAdd(load, Builder.getInt64(1)); >> StoreInst* store = Builder.CreateStore(inc, key); >> return store; >> } >> return I; >> } >> >> Instruction* InstructionVisitor::print(Instruction* I, const char* text, Value* arg1, Value* arg2, Value* arg3, Value* arg4) { >> Function* printfFn = I->getModule()->getFunction("printf"); >> if (printfFn) { >> IRBuilder<> Builder(I->getContext()); >> Builder.SetInsertPoint(I->getNextNode()); >> Value* convertedText = Builder.CreateGlobalStringPtr(text); >> >> std::vector <Value *> params; >> params.push_back(convertedText); >> if (arg1) >> params.push_back(arg1); >> if (arg2) >> params.push_back(arg2); >> if (arg3) >> params.push_back(arg3); >> if (arg4) >> params.push_back(arg4); >> >> return Builder.CreateCall(printfFn, params); >> } >> return I; >> } >> >> void InstructionVisitor::visitCallInst(CallInst &CI) { >> if (isAllocationFn(&CI, &TLI)) { >> Value* allocatedAddress = &CI; >> Instruction* I = &CI; >> Value* allocatedSize = I->getOperand(0); >> Instruction* next = incrementGlobalKey(I); >> GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); >> const char* message = "Allocated address: 0x%p, size: %d, key: %lld\n"; >> print(next, message, allocatedAddress, allocatedSize, key->getOperand(0)); >> } >> } >> >> Code that I'm executing (source code) is: >> int main() >> { >> char* buffer; >> int size = 101; >> buffer = new char[size]; >> printf("CHECK address: 0x%p, size: %d\n", buffer, size); >> TestClass* test = new TestClass(1, 2); >> printf("(CHECK address: 0x%p, size: %llu\n", test, sizeof(TestClass)); >> >> delete buffer; >> delete test; >> } >> >> And program output after instrumentation: >> >> Allocated address: 0x000001CD326C1B20, size: 101, key: 0 >> CHECK address: 0x000001CD326C1B20, size: 101 >> Allocated address: 0x000001CD326C1B90, size: 8, key: 0 >> CHECK address: 0x000001CD326C1B90, size: 8 >> >> Regards, >> Emma Luciano >> >> śr., 3 cze 2020 o 11:21 Eli Friedman <efriedma at quicinc.com> napisał(a): >>> Suppose I have the following program: >>> >>> >>> >>> $ cat test.c >>> >>> int a = 0; >>> >>> int main() { a = 1; }; >>> >>> >>> >>> Then I compile and run it: >>> >>> $ clang test.c >>> >>> $ ./a.out >>> >>> >>> >>> Then I print the contents of test.c again: >>> >>> >>> >>> $ cat test.c >>> >>> int a = 0; >>> >>> int main() { a = 1; } >>> >>> >>> >>> Why does it say “int a = 0;”? The program set it to 1, no? >>> >>> >>> >>> As far as I can tell, this is equivalent to your question… except it’s less obvious because the “source code” is an LLVM IR module in memory. >>> >>> >>> >>> Maybe you’re looking for ExecutionSession::lookup? The same way the tutorial computes the address of “main”, you can compute the runtime address of any other externally visible symbol. >>> >>> >>> >>> See also https://llvm.org/docs/ORCv2.html , https://www.youtube.com/watch?v=hILdR8XRvdQ . >>> >>> >>> >>> -Eli >>> >>> >>> >>> From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Emma Luciano via llvm-dev >>> Sent: Wednesday, June 3, 2020 1:35 AM >>> To: llvm-dev at lists.llvm.org >>> Subject: [EXT] [llvm-dev] Fwd: I cannot change value of global variable in LLVM IR using IRBuilder >>> >>> >>> >>> Hi Everyone, >>> >>> I'm quite new to LLVM and I want to update value of global variable in LLVM IR. I created new global variable in ModulePass: >>> >>> bool runOnModule(llvm::Module &M) { >>> >>> IRBuilder<> Builder(M.getContext()); >>> >>> Instruction *I = &*inst_begin(M.getFunction("main")); >>> >>> Builder.SetInsertPoint(I); >>> >>> M.getOrInsertGlobal("globalKey", Builder.getInt64Ty()); >>> >>> GlobalVariable* gVar = M.getNamedGlobal("globalKey"); >>> >>> gVar->setLinkage(GlobalValue::InternalLinkage); >>> >>> gVar->setAlignment(Align(8)); >>> >>> gVar->setInitializer(Builder.getInt64(0)); >>> >>> gVar->setConstant(false); >>> >>> >>> >>> for (Function &F : M.functions()) { >>> >>> InstructionVisitor visitor(DL, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F)); >>> >>> for (Instruction &I : instructions(F)) { >>> >>> visitor.visit(I); >>> >>> } >>> >>> } >>> >>> return true; >>> >>> } >>> >>> Later in InstructionVisitor I try to update it like that: >>> >>> IRBuilder<> Builder(I->getContext()); >>> >>> Builder.SetInsertPoint(I->getNextNode()); >>> >>> >>> >>> GlobalVariable* key = I->getModule()->getNamedGlobal("globalKey"); >>> >>> >>> >>> if (key) { >>> >>> LoadInst* load = Builder.CreateLoad(key); >>> >>> Value* inc = Builder.CreateAdd(load, Builder.getInt64(1)); >>> >>> StoreInst* store = Builder.CreateStore(inc, key); >>> >>> } >>> >>> I print that global variable during execution of instrumented code. I access it's value by key->getOperand(0), but it's unchanged. I'm using ORC JIT based on this tutorial: https://llvm.org/docs/tutorial/BuildingAJIT2.html and I run ModulePass from optimizeModule function from this tutorial. >>> >>> In IR it looks like that: >>> >>> %2 = load i64, i64* @globalKey >>> >>> %3 = add i64 %2, 1 >>> >>> store i64 %3, i64* @globalKey >>> >>> I tried updating value of global variable, which was present in source code that I'm instrumenting. It didn't work either. >>> >>> I created corresponding stackoverflow topic: https://stackoverflow.com/questions/62142574/how-can-i-update-global-variable-value-in-llvm-ir-using-irbuilder?fbclid=IwAR2X7uGhUjm_SN2UcxWYqaRQW2-cs6iPbMx2_tbKubeyYUkZ_pS6rkFfY9I >>> >>> I will be really grateful for help. >>> >>> Regards, >>> >>> Emma Luciano >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200603/86a3d83c/attachment.html>