newbie question for type comparison

Hi,

I want to extract all instruction of the form "alloca %struct.S", where
$struct.S is defined as a struct

  %struct.S = type { i32, i32 }

I'm using the following loop:

for(inst_iterator i = inst_begin(F), e = inst_end(F); i!= e; i++)
{
  AllocaInst* ai;
        if( (ai = dyn_cast<AllocaInst>(&*i))){
          if(ai->getOperand(0)->getType()->getTypeID() ==
    Type::StructTyID)
      allocs.push_back(ai);
         }
}

However, I had the impression that the type comparison can be done by a
pointer comparison. Can anyone please suggest me a better way to do it?

Also, I want to get the size of %struct.S, should I use the following
code?

const TargetData &TD = getAnalysis<TargetData>();
unsigned StructSize =
         TD.getABITypeSizeInBits(ai->getOperand(0)->getType());

Thanks a lot.
Lu

Lu Zhao wrote:

Hi,

I want to extract all instruction of the form "alloca %struct.S", where
$struct.S is defined as a struct

        %struct.S = type { i32, i32 }

I'm using the following loop:

for(inst_iterator i = inst_begin(F), e = inst_end(F); i!= e; i++)
{
        AllocaInst* ai;
        if( (ai = dyn_cast<AllocaInst>(&*i))){
          if(ai->getOperand(0)->getType()->getTypeID() ==
                Type::StructTyID)
                        allocs.push_back(ai);
         }
}
  

I might be misunderstanding something, but the above code finds all alloca instructions that allocate structure types. This is not quite what you want if you're looking specifically for type {i32, i32}.

To search specifically for that type, do the following:

1) Create a "new" structure type representing {i32. i32} using the static StructType::get() method. I think the code would look something like this:

Type * MyStructType = StructType::get (Type::Int32Ty, Type::Int32Ty, 0);

2) Compare the pointer of MyStructType to the pointer for the alloca's allocation type:

if (ai->getOperand(0)->getType() == MyStructType)

The above works because LLVM will only create one instance of each type (i.e. if there's already a {i32, i32}, StructType::get() returns a pointer to that instead of creating a new object). This is what allows the pointer comparison to work.

However, I had the impression that the type comparison can be done by a
pointer comparison. Can anyone please suggest me a better way to do it?

Also, I want to get the size of %struct.S, should I use the following
code?

const TargetData &TD = getAnalysis<TargetData>();
unsigned StructSize =
         TD.getABITypeSizeInBits(ai->getOperand(0)->getType());
  

There are different interpretations of "size" that TargetData supports, but without knowing what you're trying to do, I'd have to guess that this is probably what you want.

-- John T.

Hi John,

Thank you a lot. That clarifies some my confusions. What I want to do
is to use both methods, get ALL struct allocation and a SPECIFIC struct
allocation, at different situations. Here, I've got a couple of more
questions.

1. For getting ALL struct allocation, when I use

        if( (AI = dyn_cast<AllocaInst>(&*i)))
          if(AI->getOperand(0)->getType()->getTypeID() ==
Type::StructTyID) {

to get all alloca instructions allocating a structure, it does not
work. In my gdb session, I've got the following dumps:

(gdb) call AI->dump()
        %s = alloca %struct.S ; <%struct.S*> [#uses=4]
(gdb) call AI->getOperand(0)->dump()
i32 1
(gdb) call AI->getOperand(0)->getType()->dump()
i32

AI->getOperand(0)->getType() returns i32 instead of what I expect,
{i32, i32}.

2. For TargetData size, for those struct allocations that I don't know
its size in advance, I want to get its size and use the size in a memcpy
function, which makes a copy of the struct. Is the ABI type size the
correct one?

Thanks.
Lu

Lu Zhao wrote:

Hi John,

Thank you a lot. That clarifies some my confusions. What I want to do
is to use both methods, get ALL struct allocation and a SPECIFIC struct
allocation, at different situations. Here, I've got a couple of more
questions.

1. For getting ALL struct allocation, when I use

        if( (AI = dyn_cast<AllocaInst>(&*i)))
          if(AI->getOperand(0)->getType()->getTypeID() ==
Type::StructTyID) {

to get all alloca instructions allocating a structure, it does not
work. In my gdb session, I've got the following dumps:
  

I'm not sure why the above doesn't work. My best guess is that the allocated type is not an operand (since it is not an LLVM Value) but is an attribute (for lack of a better word) of the alloca instruction.

My suggestion is to use the getAllocatedType() method of the AllocaInst class. I'm pretty sure it does what you want:

if (AI->getAllocatedType()->getTypeID() == Type::StructTyID)

(gdb) call AI->dump()
        %s = alloca %struct.S ; <%struct.S*> [#uses=4]
(gdb) call AI->getOperand(0)->dump()
i32 1
(gdb) call AI->getOperand(0)->getType()->dump()
i32

AI->getOperand(0)->getType() returns i32 instead of what I expect,
{i32, i32}.

2. For TargetData size, for those struct allocations that I don't know
its size in advance, I want to get its size and use the size in a memcpy
function, which makes a copy of the struct. Is the ABI type size the
correct one?
  

Yes, getABITypeSize() is what you want since it returns the amount of memory allocated by an alloca instruction for the given type.

If you haven't used it already, you may want to use the LLVM Doxygen documentation (http://llvm.org/doxygen/hierarchy.html). It has lots of information on the LLVM API, and it gets rebuilt nightly to reflect recent changes in the LLVM programming API.

-- John T.

Hi,

2. For TargetData size, for those struct allocations that I don't know
its size in advance, I want to get its size and use the size in a memcpy
function, which makes a copy of the struct. Is the ABI type size the
correct one?

yes ABI size is the right one to use for alloca.

Ciao,

Duncan.

1. For getting ALL struct allocation, when I use

       if( (AI = dyn_cast<AllocaInst>(&*i)))
         if(AI->getOperand(0)->getType()->getTypeID() ==
Type::StructTyID) {

to get all alloca instructions allocating a structure, it does not
work. In my gdb session, I've got the following dumps:

I'm not sure why the above doesn't work. My best guess is that the
allocated type is not an operand (since it is not an LLVM Value) but is
an attribute (for lack of a better word) of the alloca instruction.

Correct.

My suggestion is to use the getAllocatedType() method of the AllocaInst
class. I'm pretty sure it does what you want:

if (AI->getAllocatedType()->getTypeID() == Type::StructTyID)

Better: if (isa<StructType>) or if (StructType *sT = dyn_cast<StructType>).

— Gordon

Gordon Henriksen wrote:

1. For getting ALL struct allocation, when I use

       if( (AI = dyn_cast<AllocaInst>(&*i)))
         if(AI->getOperand(0)->getType()->getTypeID() ==
Type::StructTyID) {

to get all alloca instructions allocating a structure, it does not
work. In my gdb session, I've got the following dumps:

I'm not sure why the above doesn't work. My best guess is that the
allocated type is not an operand (since it is not an LLVM Value) but
is
an attribute (for lack of a better word) of the alloca instruction.
    
Correct.

My suggestion is to use the getAllocatedType() method of the
AllocaInst
class. I'm pretty sure it does what you want:

if (AI->getAllocatedType()->getTypeID() == Type::StructTyID)

Better: if (isa<StructType>) or if (StructType *sT =
dyn_cast<StructType>).
  

Just out of curiosity, what is it better? Does it use less virtual function calls?

-- John T.

No (it calls getTypeID) but it's more readable and in general respects subtypes.

— Gordon