Why is BasicBlock's copy constructor private?

Hi,

LLVM provides basic graph traversal for its CFGs, but I need additional operations, such as iterating over the edges. I thought I would solve this problem using the Boost graph library. It should be relatively simple to walk an LLVM CFG and add the BasicBlock objects to a Boost graph declared as:

    typedef boost::directed_graph<llvm::BasicBlock> Graph;

Once constructed, this automatically gives me access to all kinds of sophisticated graph routines.

Unfortunately, the above code doesn't compile because Boost apparently needs the class to have a copy constructor, and BasicBlock's copy constructor is private. From BasicBlock.h:

class BasicBlock : ... {
private:
   ...
   BasicBlock(const BasicBlock &); // Do not implement
   void operator=(const BasicBlock &); // Do not implement
   ...
}

This causes a slew of errors related to Boost trying to call the copy constructor and failing. Making the copy constructor public causes the errors to disappear.

So why exactly is BasicBlock's copy constructor private? The ominous "Do not implement" warning leads me to think there is some sort of design issue that is preventing a copy constructor here. Is there any possibility of working around it?

Thanks,

Trevor

I think the problem is that LLVM deals largely in pointer types, so
things like BasicBlock aren't value types since objects with
equivalent contents cannot be used interchangeably.

For one, other blocks (and presumably the function) hold them by
pointer, so the copy wouldn't be reachable. Also, the instructions in
the basic block are held by pointer and refer to their arguments by
pointer, so copying them would mean intelligently updating the
instruction arguments, which is likely infeasible.

Given that LLVM is already managing the memory and presumably will do
so for the life of your graph processing, could you just use a
boost::directed_graph<llvm::BasicBlock*> instead?

Alternatively, perhaps you want "external adaptation" as described in
http://www.boost.org/doc/libs/1_42_0/libs/graph/doc/leda_conversion.html

HTH,
~ Scott

Hi Trever,

LLVM provides basic graph traversal for its CFGs, but I need
additional operations, such as iterating over the edges. I thought I
would solve this problem using the Boost graph library. It should be
relatively simple to walk an LLVM CFG and add the BasicBlock objects
to a Boost graph declared as:

     typedef boost::directed_graph<llvm::BasicBlock> Graph;

LLVM already has a "graph traits" abstraction, which can be used to
view the CFG as a graph (see: include/llvm/ADT/GraphTraits.h).

Ciao,

Duncan.

Yeah, that was one of the first things I tried:

for (Function::iterator i = function.begin(), e = function.end(); i != e; ++i) {
  BasicBlock *basicBlockPtr = &(*i);
  add_vertex(basicBlockPtr, timingGraph);
}

The "&(*i)" sure seems weird, but I don't know how else to grab a pointer to the BasicBlock from within the iterator.

Also, if I then try to extract a vertex from the graph:

BasicBlock *basicBlockPtr = timingGraph[0];
      
...the whole thing segfaults. So I'm basically stuck.

Trevor

Trevor,
Check the programming manual.
http://llvm.org/docs/ProgrammersManual.html#iterate_convert

Never mind; I was doing something dumb. (Some of the functions had no basic blocks, so the graphs were empty.)

Trevor