Patrick Meredith
2004-Jun-17 12:15 UTC
[LLVMdev] generating instructions with embedded ConstantExprs from within LLVM
How is this done? Everything logical I have tried has failed, here was one attempt: Constant *C = (Constant*) ConstantArray::get(inst2string(I)); //fucnction defined elsewhere //generates a correct Global string GlobalVariable *str = new GlobalVariable(C->getType(), true, GlobalValue::InternalLinkage, C, mkStrName( strNumber++ ), &M); std::vector<Value*> params; //params to a CallInst std::vector<Value*> indices; //indices to gep indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); Constant *gep = ConstantExpr::getGetElementPtr( (Constant*) str, indices); params.push_back((Value*) gep ); CallInst *CI = new CallInst(printf, params, std::string(""), I); This resulted in a "no such type plane" assertion. Currently I am doing this as two seperate instructions, which works, but slows down the rest of my pass. ~Patrick -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040617/0d1d9b5c/attachment.html>
Chris Lattner
2004-Jun-17 12:24 UTC
[LLVMdev] generating instructions with embedded ConstantExprs from within LLVM
On Thu, 17 Jun 2004, Patrick Meredith wrote:> How is this done? Everything logical I have tried has failed, here was > one attempt:Can you give a few more details about what you are doing? Are you running the verifier before writing out bytecode? Is your code operating as a pass? Can you send a dump of the generated LLVM code?> Constant *C = (Constant*) ConstantArray::get(inst2string(I)); //fucnction defined elsewhereOne comment about this code: you don't need to have all of these casts. In particular, above you don't need the (Constant*) cast, and you don't need the (Value*) casts below.> //generates a correct Global string > GlobalVariable *str = new GlobalVariable(C->getType(), true, > GlobalValue::InternalLinkage, > C, mkStrName( strNumber++ ), &M);You probably don't need mkStrName here. Just use a constant name like "debugstr" or whatever. The symbol table class will autonumber them for you to keep them unique, and is likely to be more efficient than this implementation.> std::vector<Value*> params; //params to a CallInst > std::vector<Value*> indices; //indices to gep > indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); > indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); > Constant *gep = ConstantExpr::getGetElementPtr( (Constant*) str, indices);This looks fine, but you can drop the casts.> params.push_back((Value*) gep ); > > CallInst *CI = new CallInst(printf, params, std::string(""), I);You can just pass in "" here instead of std::string("") btw.> This resulted in a "no such type plane" assertion. Currently I am > doing this as two seperate instructions, which works, but slows down the > rest of my pass.I'm really not sure what's going on without more detail. In particular, this assertion can happen if you attempt to write an invalid LLVM module to bytecode. Make sure that the type of the gep value matches the first argument to printf. If you run the verifier it should catch problems like this (the verifier should automatically be run if you're a pass running from opt), If the verifier doesn't catch the problem, then it's a bug in the verifier and please let me know! -Chris -- http://llvm.cs.uiuc.edu/ http://www.nondot.org/~sabre/Projects/
Chris Lattner
2004-Jun-17 12:28 UTC
[LLVMdev] generating instructions with embedded ConstantExprs from within LLVM
On Thu, 17 Jun 2004, Patrick Meredith wrote:> How is this done? Everything logical I have tried has failed, here was > one attempt: > > Constant *C = (Constant*) ConstantArray::get(inst2string(I)); //fucnction defined elsewhere > > //generates a correct Global string > GlobalVariable *str = new GlobalVariable(C->getType(), true, > GlobalValue::InternalLinkage, > C, mkStrName( strNumber++ ), &M);...> Constant *gep = ConstantExpr::getGetElementPtr( (Constant*) str, indices);Sorry for responding twice. As soon as I sent that I realized the problem. The problem is that the cast on the bottom line here is masking the bug. In particular, you can't use the address of global variables as constants (yet: see PR122). This is definitely a bug in LLVM that you can't do this, but we do have a gross work-around. In particular, to get the address of a global value as a constant, use the ConstantPointerRef class: Constant *strconst = ConstantPointerRef::get(str); Constant *gep = ConstantExpr::getGetElementPtr(strconst, indices); In the future, the GlobalValue class will derive from the Constant class, making this unnecessary. Since the "value" of a GlobalValue is the *address* of the global, and since this is a link-time constant, it makes sense for it to derive from the Constant class. Sorry for the confusion, you have every right to expect things to work this way. In the future they will, as part of PR122. :) -Chris -- http://llvm.cs.uiuc.edu/ http://www.nondot.org/~sabre/Projects/
Patrick Meredith
2004-Jun-17 12:45 UTC
[LLVMdev] generating instructions with embedded ConstantExprs from within LLVM
----- Original Message ----- From: "Chris Lattner" <sabre at nondot.org> To: <llvmdev at cs.uiuc.edu> Sent: Thursday, June 17, 2004 12:34 PM Subject: Re: [LLVMdev] generating instructions with embedded ConstantExprs from within LLVM> On Thu, 17 Jun 2004, Patrick Meredith wrote: > > > How is this done? Everything logical I have tried has failed, here was > > one attempt: > > Can you give a few more details about what you are doing? Are you running > the verifier before writing out bytecode? Is your code operating as a > pass? Can you send a dump of the generated LLVM code?I'm running this as a pass from opt (even though it's not really an optimization). What it does is go thourgh and find parts of code that is a program fragment, these it converts to a format string for printf, that's why I need the gep and the printf calls. I no longer have this version of the code so I can't really send it ;) Right now I am just generating two seperate instructions, i.e. %gep_x = getelementptr... ;<sbyte* from sbyte array> call int %printf(sbyte* %gep_x, ..... This works fine, and aside from getting this thing to make strings for every type of instruction it works great (note: this is a cheap hack Vikram and I came up with, using printf's to dynamically generate code is not our final plan ;) )> > Constant *C = (Constant*) ConstantArray::get(inst2string(I));//fucnction defined elsewhere> > One comment about this code: you don't need to have all of these casts. > In particular, above you don't need the (Constant*) cast, and you don't > need the (Value*) casts below.I always over-cast, it's clearer for me to read, but probably for no one else (and static pointer casts are just noops). I'll take those out.> > //generates a correct Global string > > GlobalVariable *str = new GlobalVariable(C->getType(), true, > > GlobalValue::InternalLinkage, > > C, mkStrName( strNumber++ ), &M); > > You probably don't need mkStrName here. Just use a constant name like > "debugstr" or whatever. The symbol table class will autonumber them for > you to keep them unique, and is likely to be more efficient than this > implementation.I did not realize that, thanks :)> > std::vector<Value*> params; //params to a CallInst > > std::vector<Value*> indices; //indices to gep > > indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); > > indices.push_back((Value*) (ConstantInt::get(Type::IntTy, 0))); > > Constant *gep = ConstantExpr::getGetElementPtr( (Constant*) str,indices);> > This looks fine, but you can drop the casts. > > > params.push_back((Value*) gep ); > > > > CallInst *CI = new CallInst(printf, params, std::string(""), I); > > You can just pass in "" here instead of std::string("") btw. > > > This resulted in a "no such type plane" assertion. Currently I am > > doing this as two seperate instructions, which works, but slows down the > > rest of my pass. > > I'm really not sure what's going on without more detail. In particular, > this assertion can happen if you attempt to write an invalid LLVM module > to bytecode. Make sure that the type of the gep value matches the first > argument to printf. If you run the verifier it should catch problems like > this (the verifier should automatically be run if you're a pass running > from opt), If the verifier doesn't catch the problem, then it's a bug in > the verifier and please let me know! > > -Chris > > -- > http://llvm.cs.uiuc.edu/ > http://www.nondot.org/~sabre/Projects/ > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
Patrick Meredith
2004-Jun-17 12:48 UTC
[LLVMdev] generating instructions with embedded ConstantExprs from within LLVM
----- Original Message ----- From: "Chris Lattner" <sabre at nondot.org> To: <llvmdev at cs.uiuc.edu> Sent: Thursday, June 17, 2004 12:38 PM Subject: Re: [LLVMdev] generating instructions with embedded ConstantExprs from within LLVM> On Thu, 17 Jun 2004, Patrick Meredith wrote: > > > How is this done? Everything logical I have tried has failed, here was > > one attempt: > > > > Constant *C = (Constant*) ConstantArray::get(inst2string(I));//fucnction defined elsewhere> > > > //generates a correct Global string > > GlobalVariable *str = new GlobalVariable(C->getType(), true, > > GlobalValue::InternalLinkage, > > C, mkStrName( strNumber++ ), &M); > ... > > Constant *gep = ConstantExpr::getGetElementPtr( (Constant*) str,indices);> > Sorry for responding twice. As soon as I sent that I realized the > problem. The problem is that the cast on the bottom line here is masking > the bug. In particular, you can't use the address of global variables as > constants (yet: see PR122). This is definitely a bug in LLVM that you > can't do this, but we do have a gross work-around. In particular, to get > the address of a global value as a constant, use the ConstantPointerRef > class: > > Constant *strconst = ConstantPointerRef::get(str); > Constant *gep = ConstantExpr::getGetElementPtr(strconst, indices); > > In the future, the GlobalValue class will derive from the Constant class, > making this unnecessary. Since the "value" of a GlobalValue is the > *address* of the global, and since this is a link-time constant, it makes > sense for it to derive from the Constant class.Ohh thanks, I noticed that it didn't derive from Constant but I didn't see any way around it. I should have realized that that was the problem.> Sorry for the confusion, you have every right to expect things to work > this way. In the future they will, as part of PR122. :) > > -Chris > > -- > http://llvm.cs.uiuc.edu/ > http://www.nondot.org/~sabre/Projects/ > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev