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>