I'm trying to work out the size of a struct so that I can pass this to the 'llvm.memcpy' intrinsic. It's easy to find out how I'm supposed to do this, as I keep seeing the following: %Size = getelementptr %T* null, int 1 %SizeI = cast %T* %Size to uint But I'm unsure how I actually do this in the C++ API. Is the 'null' here a llvm::ConstantPointerNull? Any help here would be much appreciated. Additionally, I was wondering whether I can use this method to find out the size of variable-length arrays, such as [0 x i32], for example? I've tried doing this and am obviously doing something wrong. %Size = getelementptr [0 x i32]* %1, i32* null, i32 1 %SizeI = ptrtoint i32* %Size to i64 This gives entirely the wrong result, and I'm not surprised, as it doesn't look correct. Should I instead be implementing these arrays with a size associated with them? Something like { i32, [0 x i32]}, for instance? Cheers, Fraser -- View this message in context: http://old.nabble.com/Size-of-structs---arrays-tp33341964p33341964.html Sent from the LLVM - Dev mailing list archive at Nabble.com.
On Wed, Feb 22, 2012 at 1:56 PM, Fraser Cormack <frasercrmck at gmail.com> wrote:> > I'm trying to work out the size of a struct so that I can pass this to the > 'llvm.memcpy' intrinsic. It's easy to find out how I'm supposed to do this, > as I keep seeing the following: > > %Size = getelementptr %T* null, int 1 > %SizeI = cast %T* %Size to uint > > But I'm unsure how I actually do this in the C++ API. Is the 'null' here a > llvm::ConstantPointerNull? Any help here would be much appreciated.Try llvm::Constant::getNullValue().> Additionally, I was wondering whether I can use this method to find out the > size of variable-length arrays, such as [0 x i32], for example? I've tried > doing this and am obviously doing something wrong. > > %Size = getelementptr [0 x i32]* %1, i32* null, i32 1 > %SizeI = ptrtoint i32* %Size to i64 > > This gives entirely the wrong result, and I'm not surprised, as it doesn't > look correct. Should I instead be implementing these arrays with a size > associated with them? Something like { i32, [0 x i32]}, for instance?Yes; [0 x i32] isn't really a variable-length array, just a placeholder for an array of unknown size. You have to track the size yourself. -Eli
Eli Friedman-2 wrote:> > > Try llvm::Constant::getNullValue(). > >I'm trying this: llvm::Constant* one llvm::Constant::getNullValue(llvm::IntegerType::get(mod->getContext(), 64)); llvm::ConstantInt* two = llvm::ConstantInt::get(mod->getContext(), llvm::APInt(32, llvm::StringRef("1"), 10)); std::vector<llvm::Value*> indices; indices.push_back(one); indices.push_back(two); llvm::Value* size = builder->CreateGEP(struct_ptr, indices); llvm::Value* size_int = builder->CreatePtrToInt(size, llvm::IntegerType::get(mod->getContext(), 64)) And I'm getting the assertion error "Invalid GetElementPtrInst indices for type!"'. 'struct_ptr' is a pointer to the struct I'm trying to size. I've also tried using getNullValue on the struct's own type. Sorry to ask so directly, but I'd quite like to get this sorted. -- View this message in context: http://old.nabble.com/Size-of-structs---arrays-tp33341964p33374459.html Sent from the LLVM - Dev mailing list archive at Nabble.com.
Eli Friedman-2 wrote:> > > Try llvm::Constant::getNullValue(). > >I'm trying this: llvm::Constant* one llvm::Constant::getNullValue(llvm::IntegerType::get(mod->getContext(), 64)); llvm::ConstantInt* two = llvm::ConstantInt::get(mod->getContext(), llvm::APInt(32, llvm::StringRef("1"), 10)); std::vector<llvm::Value*> indices; indices.push_back(one); indices.push_back(two); llvm::Value* size = builder->CreateGEP(struct_ptr, indices); llvm::Value* size_int = builder->CreatePtrToInt(size, llvm::IntegerType::get(mod->getContext(), 64)) And I'm getting the assertion error "Invalid GetElementPtrInst indices for type!"'. 'struct_ptr' is a pointer to the struct I'm trying to size. I've also tried using getNullValue on the struct's own type. Sorry to ask so directly, but I'd quite like to get this sorted. -- View this message in context: http://old.nabble.com/Size-of-structs---arrays-tp33341964p33374460.html Sent from the LLVM - Dev mailing list archive at Nabble.com.
Hi Fraser,> I'm trying to work out the size of a struct so that I can pass this to the > 'llvm.memcpy' intrinsic. It's easy to find out how I'm supposed to do this, > as I keep seeing the following: > > %Size = getelementptr %T* null, int 1 > %SizeI = cast %T* %Size to uint > > But I'm unsure how I actually do this in the C++ API. Is the 'null' here a > llvm::ConstantPointerNull? Any help here would be much appreciated.you can use ConstantExpr::getSizeOf.> Additionally, I was wondering whether I can use this method to find out the > size of variable-length arrays, such as [0 x i32], for example? I've tried > doing this and am obviously doing something wrong. > > %Size = getelementptr [0 x i32]* %1, i32* null, i32 1 > %SizeI = ptrtoint i32* %Size to i64 > > This gives entirely the wrong result,This will return zero, since this array has size zero. It is not a variable length array, it is an array with length zero. and I'm not surprised, as it doesn't> look correct. Should I instead be implementing these arrays with a size > associated with them? Something like { i32, [0 x i32]}, for instance?You need to know the length somehow. This is one way. Ciao, Duncan.
Eli Friedman-2 wrote:> > > Try llvm::Constant::getNullValue(). > >Thanks, that's working nicely (so far). Eli Friedman-2 wrote:> > > Yes; [0 x i32] isn't really a variable-length array, just a > placeholder for an array of unknown size. You have to track the size > yourself. > >This is working, too, however I'm getting a segmentation fault at runtime. %MainClass = type { { i32, [0 x i32] } } %this = alloca %MainClass* %0 = alloca { i32, [5 x i32] } ... Here, I store 5 into %0[0] and a constant array into %0[1]. This runs without error. %7 = load %MainClass** %this %8 = getelementptr inbounds %MainClass* %7, i32 0, i32 0 %9 = getelementptr inbounds { i32, [0 x i32] }* %8, i32 0, i32 0 %10 = getelementptr inbounds { i32, [5 x i32] }* %0, i32 0, i32 0 %11 = load i32* %10 store i32 %11, i32* %9 %12 = getelementptr inbounds { i32, [0 x i32] }* %8, i32 0, i32 1 %13 = getelementptr inbounds { i32, [5 x i32] }* %0, i32 0, i32 1 %14 = bitcast [0 x i32]* %12 to i8* %15 = bitcast [5 x i32]* %13 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* %14, i8* %15, i64 20, i32 4, i1 false) ret void I can't see anything wrong with this bytecode (except for being verbose), and I don't blame you if you don't want to debug it yourself, but I thought I'd post it anyway. If I access a value of MainClass's array after the transfer, and print it out, then it does so successfully, then continues to segfault. So it looks like it's copied the memory okay, but I've corrupted something in the process.. -- View this message in context: http://old.nabble.com/Size-of-structs---arrays-tp33341964p33381946.html Sent from the LLVM - Dev mailing list archive at Nabble.com.