I think of CCI and Phoenix as being complementary because CCI is primarily about turning source text into IL and Phoenix is primarily about turning IL into machine code.
If I were to remove the ability of CCI to read method bodies from compiled assemblies, CCI would not be able to do anything Phoenix can do. One could conceivably use Phoenix as a
metadata reader for a source to IL compiler, and as a metadata + IL emitter for the same, but if you were to do so, you’d be in for a very big disappointment.
So, at one level, things are crystal clear: you use CCI when you want to produce IL and you use Phoenix when you want to produce machine code.
However, somewhat to
my surprise, the ability of CCI to also construct an object model for method bodies of compiled assemblies has been a big hit. So much so, that most people think exclusively of CCI as a metada+IL
OK, so when should
you use Phoenix? Do so if you are willing and able to master a very complex API and when performance/memory footprint is not a big concern for you. Do so if you need to perform basically the same analysis over managed and unmanaged code. Do so if you
need to and can leverage all of the information Phoenix computes in order to optimize IL into good machine code.