question

When I tried to compile the program, I got this error:

../../../include/llvm/Analysis/DSGraph.h: In member function `virtual bool
   <unnamed>::GlobalMemLeakage::run(Module&)':
../../../include/llvm/Analysis/DSGraph.h:38: `void
DSGraph::operator=(const
   DSGraph&)' is private
MemLeakage.cpp:87: within this context
gmake: *** [Debug/MemLeakage.o] Error 1

I don't understand what this means. Basically what I did is I defined:
map<Function *, DSGraph> funsetmap;
and I was trying to assign the DSGraph for each function to the map.
funsetmap[&F] = dsg;
Could you tell me what's wrong how to fix this?

Another question is that when I iterate on the graph using this
  for (DSNode::iterator I = N->begin(), E = N->end(); I != E; ++I)
    if (I->getNode())
      visit(I->getNode(), I->getOffset());
The return type of I->getNode() is 'const DSNode *' type. Is there a
'DSNode *' type iterator?

Besides, Can I use the following code to visit the children of N?
   for( unsigned i=0; i < N->getNumLinks(); i++) {
  visit( N->getLink() )
   }

Thanks,
Jerry

Also sprach Xiaodong Li:
}
} When I tried to compile the program, I got this error:
}
} ../../../include/llvm/Analysis/DSGraph.h: In member function `virtual bool
} <unnamed>::GlobalMemLeakage::run(Module&)':
} ../../../include/llvm/Analysis/DSGraph.h:38: `void
} DSGraph::operator=(const
} DSGraph&)' is private
} MemLeakage.cpp:87: within this context
} gmake: *** [Debug/MemLeakage.o] Error 1
}
} I don't understand what this means. Basically what I did is I defined:
} map<Function *, DSGraph> funsetmap;
} and I was trying to assign the DSGraph for each function to the map.
} funsetmap[&F] = dsg;
} Could you tell me what's wrong how to fix this?
}
You're invoking the copy constructor in this code snippet:

    funsetmap[&F] = dsg;

That is, the copy constructor for dsg (which I take to be a DSGraph
object). Ways around this:

    - Store a pointer to DSGraph instead of the DSGraph object. So
      something like this:

        map<Function *, DSGraph *> funsetmap;

        // code

        funsetmap[&F] = &dsg;

      You have to be careful not to store local variables and pass them
      back from a function, of course.

    - Create a wrapper class for DSGraph and have its copy constructor
      clone the DSGraph object for you. This way is a bit more
      complicated and might not really be necessary for what you need to
      do though...

Thanks Bill. One more question, when I use the DSNode iterator to
traverse a node's children. The return value of I.getNode() can only
be 'const DSNode *', I cannot use 'DSNode *' type. So as a result, I
always get error message like this:

MemLeakage.cpp:159: invalid conversion from `const DSNode*' to `DSNode*'
MemLeakage.cpp:159: initializing argument 1 of `void
   <unnamed>::GlobalMemLeakage::KillSetInsert(DSNode*, BBsets&)'

How to use a 'Node *' type iterator? Or is there any other way to traverse
the DSGraph?

thanks,
Jerry

be 'const DSNode *', I cannot use 'DSNode *' type. So as a result, I
always get error message like this:
How to use a 'Node *' type iterator? Or is there any other way to traverse
the DSGraph?

I will have to add a new version of the iterator. I'll do this sometime
early next week. In the meantime, just cast stuff like crazy. :slight_smile:

-Chris

Also sprach Xiaodong Li:
} Thanks Bill. One more question, when I use the DSNode iterator to
} traverse a node's children. The return value of I.getNode() can only
} be 'const DSNode *', I cannot use 'DSNode *' type. So as a result, I
} always get error message like this:
}
} MemLeakage.cpp:159: invalid conversion from `const DSNode*' to `DSNode*'
} MemLeakage.cpp:159: initializing argument 1 of `void
} <unnamed>::GlobalMemLeakage::KillSetInsert(DSNode*, BBsets&)'
}
} How to use a 'Node *' type iterator? Or is there any other way to traverse
} the DSGraph?
}
I don't know too much about the DSGraph module, so I didn't respond to
that part of your question :-).

However, a few things which will help. If you don't need to modify the
DSNode *, then use a const_iterator instead and pass everything to
functions which take const DSNode *.

If you do need to modify it, then you may have to rely upon a
const_cast<>() to remove the const from the object. So, you'll have code
which looks like this I think:

    for (DSGraph::iterator B = dsg.begin(), E = dsg.end(); B != E; ++B) {
        DSGraph *D = const_cast<DSGraph *>(*B);

        // code...

        KillSetInsert(D);

        // more code...
    }

that may work...

Bill has a good point here. You probably don't need to modify the DSGraph
for your project, so using const DSNode's directly is the right way to
go...

-Chris

I tried to used the getScalarMap function of the DSGraph to get the nodes
that the scalars point to in a function. But the getScalarMap returns a
null map always. Is there any problem in the getScalarMap function or is
there any "protocol" to be followed while using the function?

Thanks,
Ganesh

I tried to used the getScalarMap function of the DSGraph to get the nodes
that the scalars point to in a function. But the getScalarMap returns a
null map always. Is there any problem in the getScalarMap function or is
there any "protocol" to be followed while using the function?

DSGraph::getScalarMap returns a reference to the map, so this cannot be
null. Do you mean that all of the "entries" in the map are null? If so,
remember that DSGraphs are built in the context of some function (as
indicated by hasFunction/getFunction), so only scalars in that context
will be in the map...

-Chris

Specifically we did the following:

  ......
  DSGraph* DSG = getAnalysis<BUDataStructures>().getDSGraph( F );
  std::map< Value*, DSNodeHandle> scalarmap = DSG->getScalarMap();
  ......

The scalarmap is always empty. I printed the size of the map which came
out to be zero always. But the getNodeForValue works correctly for the
same DSG, which means that the scalarmap cannot be empty. But we always
have an empty scalarmap being returned.

Thanks,
Ganesh

  ......
  DSGraph* DSG = getAnalysis<BUDataStructures>().getDSGraph( F );
  std::map< Value*, DSNodeHandle> scalarmap = DSG->getScalarMap();
  ......

The scalarmap is always empty. I printed the size of the map which came
out to be zero always. But the getNodeForValue works correctly for the
same DSG, which means that the scalarmap cannot be empty. But we always
have an empty scalarmap being returned.

Try capturing a reference to the map instead of copying it:

std::map<Value*, DSNodeHandle> &scalarmap = DSG->getScalarMap();

-Chris

Chris,

We tried that too...but still it returns an empty map.

We also saw that Scalar Type has been removed from the DSNode types. Why
is that?

Thanks,
Ganesh

We tried that too...but still it returns an empty map.

I'm not sure what's going on then. :slight_smile: I think that Vikram is planning to
update CVS soon, you might try that, as there has been significant
updates. I'm not sure why getNodeForValue would work for you but
getScalarMap doesn't... getNodeForValue USES the scalar map! :slight_smile:

We also saw that Scalar Type has been removed from the DSNode types. Why
is that?

Originally, LLVM values were represented in the DSGraph as DSNodes with
the Scalar field set. Thus you would have something like this:

X: ( int*%X )
       >
       >
       v
       >
       >
       v
B: [ H int]

IOW, X in the scalar map would point to a "scalar" node (A), which would
point to the actual data the scalar points to (B). This was wasteful
because scalars in LLVM can never alias each other, thus they don't need
to be in the graphs. We changed the graph to now represent this situation
like this:

    ( int*%X )
       >
       >
       v
B: [ H int]

Now X is represented ONLY in the scalar map, and it points to whatever the
scalar points to. Because the scalar nodes don't exist in the graph
anymore, we dropped the flag.

-Chris

> > ......
> > DSGraph* DSG = getAnalysis<BUDataStructures>().getDSGraph( F );
> > std::map< Value*, DSNodeHandle> scalarmap = DSG->getScalarMap();
> > ......
> >
> > The scalarmap is always empty. I printed the size of the map which came
> > out to be zero always. But the getNodeForValue works correctly for the
> > same DSG, which means that the scalarmap cannot be empty. But we always
> > have an empty scalarmap being returned.
>
> Try capturing a reference to the map instead of copying it:
>
> std::map<Value*, DSNodeHandle> &scalarmap = DSG->getScalarMap();
>
> -Chris
>
>
> >
> > > > I tried to used the getScalarMap function of the DSGraph to get the nodes
> > > > that the scalars point to in a function. But the getScalarMap returns a
> > > > null map always. Is there any problem in the getScalarMap function or is
> > > > there any "protocol" to be followed while using the function?
> > >
> > > DSGraph::getScalarMap returns a reference to the map, so this cannot be
> > > null. Do you mean that all of the "entries" in the map are null? If so,
> > > remember that DSGraphs are built in the context of some function (as
> > > indicated by hasFunction/getFunction), so only scalars in that context
> > > will be in the map...
> > >
> > > -Chris
> > >
> > > --
> > > http://llvm.cs.uiuc.edu/
> > > http://www.nondot.org/~sabre/Projects/
> > >
> > > _______________________________________________
> > > LLVM Developers mailing list
> > > LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
> > > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> > >
> >
>
> -Chris
>
> --
> http://llvm.cs.uiuc.edu/
> http://www.nondot.org/~sabre/Projects/
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
>

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris

Is there a way get the register on the LHS of a llvm instruction? (in
case there is one)

for example, given a "free %reg773", I want to find the matching
"%something = malloc %", where %something is not necessarily %reg773.
One way I found was to inmediately follow the use-def chain up from
the free to the malloc. But instead, I want to put %reg773 in a set
(possibly with many other %things), and when I find
"%something = malloc" look for %something in the set. One way to do it
(as far as I see) is to store the "defs" in the set. But I was
thinking about storing only the "%reg" (the name, a unique
identifier), but I don't see how to get it from an Instruction.

I'm not sure the above explanation makes much sense. Too much
caffeine, I guess.

thanks in advance
nicolas

Also sprach Juan Nicolas Ruiz:
} Is there a way get the register on the LHS of a llvm instruction? (in
} case there is one)
}
} for example, given a "free %reg773", I want to find the matching
} "%something = malloc %", where %something is not necessarily %reg773.
} One way I found was to inmediately follow the use-def chain up from
} the free to the malloc. But instead, I want to put %reg773 in a set
} (possibly with many other %things), and when I find
} "%something = malloc" look for %something in the set. One way to do it
} (as far as I see) is to store the "defs" in the set. But I was
} thinking about storing only the "%reg" (the name, a unique
} identifier), but I don't see how to get it from an Instruction.
}
You can get the name of an instruction with the "getName()" method.
However, it's been pointed out that names are rather meaningless in LLVM
and aren't guaranteed to be unique. Why not store a Value* instead? (Or
Instruction* if you prefer)

I'm not sure if this solves your problem, though...

If I understand this right, you want to find the malloc that created the
object(s) being freed by a free instruction. That requires alias
information, and you can do this using DS Graphs:

(1) To find matching mallocs in the same function:

  for each Instruction* I that is a malloc:
     Check if I points to the same DS node as the argument of the
free

  Obviously this is expensive if you don't already know have a set
of mallocs to test. You don't want to loop over all the instructions in
the procedure.

(2) To find matching mallocs in other functions:

       This is more work. You have to match the DS Node pointed to by
the free to DS nodes in other functions and look for mallocs that point
to the corresponding DS node in other functions.

More generally, (if you really need to do this kind of search) I think
you should try to make it faster by keeping track of malloc instructions
for each DS Node in some appropriate data structure.

--Vikram
http://www.cs.uiuc.edu/~vadve

You can get the name of an instruction with the "getName()" method.
However, it's been pointed out that names are rather meaningless in LLVM
and aren't guaranteed to be unique.

Just to emphasize a bit here, names _are completely meaningless in LLVM_
and are meant for debugging purposes only. Do not count on them even
existing! :slight_smile: Specifically, try running 'opt -strip' on a bytecode file
and see what happens (a hint, it removes all names, making _every
instruction_ have the name "").

Why not store a Value* instead? (Or Instruction* if you prefer)

In general, in LLVM this is the right way to go. Instructions are
uniquely identified by their address, so any time you'd like to use a
name, please use a Value*. :slight_smile:

Thanks for bringing this up Bill,

-Chris