Hi Basile,
But I don't understand how Ggc could be avoided (and I am not sure to understand how even LLVM can avoid any kind of garbage collection in the long run).
I doubt LLVM will ever need garbage collection, because the way it is designed makes memory management easy. I already mentioned the use of containers, but of course containers can't handle everything. So consider a typical thing you might want to do: replace an instruction I1 by a different one I2 (for example because you understood that I1 simplifies to the simpler instruction I2) and delete I1. You can think of an LLVM instruction as being a gimple statement. One of the design points of LLVM is that instructions always know about all users of the instruction (def-use chains are built in). Thus you can do I1->replaceAllUsesWith(I2); and at this point everything using I1 as an operand now uses I2 instead. Thus the only place still referring to I1 is the function that the instruction I1 is linked into. You can unlink it and free the memory for I1 as follows I1->eraseFromParent(); And that's it. The price you pay for this simplicity is the need to keep track of uses - and this does cost compilation time (clear to anyone who does some profiling of LLVM) but it isn't that big. The big advantage is that memory management is easy - so easy that I suspect many LLVM users never thought about the design choices (and trade-offs) that make it possible. Ciao, Duncan. PS: You may wonder about copies of I1 cached in a map or whatnot, where it can be tricky (eg breaks an abstraction) or expensive to flush I1 from the data structure. This situation is handled conveniently by an extension of the above mechanism where in essence your copy of I1 in the data structure can register itself as an additional user of I1. When I1 is replaced by I2 then (according to how you chose to set things up) either the copy in the data structure gets turned into I2, or nulled out, or a special action of your choice is performed.