If compilers have an inheritance of compilers(for example, a compiler needs to be compiled by another compiler, and that compiler needs to be compiled by another compiler, and so on) then if there is an inefficiency in one of the compilers up the line of inheritance(like the compiler's compiler's compiler's compiler), would the current compiler inherit that inefficiency?
No, because compiler runtime is irrelevant to quality of produced code.
It would not propagate.
It will only once slow down compiling time in flawed compiler, there is no possibility of making next compiler slower (it will be essentially the same one).
Let me give you example:
By analogy you have one recipe, chain of writters and one cook.
Writters are passing recipe one to another and their responsibility is to change words according to given dictionary.
None of then is making mistakes. But you can switch one of writters with slower writing one.
The cook gets the same recipe always, the only difference is time, and delay is caused by this inefficient writter (not by successor).
You should read this thread: C compiler, there are some awesome answers related to your question.
A chain of compilers, as you describe in your question can be illustrated by the T-diagram notation. This is usually used to illustrate the mechanisms of bootstrapping a compiler compiling itself. It is also used to explain a cross compiler, and porting a compiler.
The notation is also valuable in explaining how optimisation improvements can be incorporated into a compiler and how bug fixes propagate in those compilers.
Early in the development of such compilers, such as a Pascal compiler in Pascal, or a C compiler in C the question of how one could fix a bug in the compiler that caused incorrect code to be generated. In that case, surely, the compiler itself would then be faulty. How could such a faulty program be used to remove a fault in itself!
Similarly, if an optimisation is added to the generated code how can we ensure that compiler itself utilises that optimisation. These questions are exactly the same as what you asked about: the inheritance of inefficiency. The inheritance of efficiency and the inheritance of faults are the very same question.
The technique is illustrated below; to ensure that the improvement is properly incorporated (or the inefficiency removed) the binary and source for the compilers can be compared. They must be bit-for-bit identical. I have used this method myself to ensure that no faults are passed on, often by performing this process in a loop, re-generating the compiler. If it does not change it demonstrates that inefficiencies are not being propagated.
.--------------------------. .--------------------------. | Compiler 1 | | Compiler 3 | | Language -------> M-code | | Language -------> M-code | | | | | `-------. .--------------------------. .-------' | | Compiler 2 | | | Language | Language ------> M-code | M-code | | | | | `------------------. .------------------' | | ^ | M-code | should be | | |<-- identical --' `----------' Figure 3.4 A self-compiling compiler must be self-consistent
Today nobody would do this, but the very first C compiler compiled a limited subset of C, and was written in its own dialect of C. Then this compiler was translated into assembly language by hand, and the result was then used to compile its own code. The result was then used to compile itself again, the result should be the same as the first round (as a correctness check).
Once you have a capable compiler, you can write a more complete compiler (or one for a different language, or one which generates better code, or...) by using this first compiler to compile them.