Special cases may sometimes be more easily handled algorithmically. Knowledge-based methods should be reserved for cases where the algorithms fail because of intractability or lack of information. System designers should be prepared to pay the price of installing the appropriate algorithms when scaling up.
Sinapse uses some simple methods to effect certain kinds of optimizations. To ensure that reasonably high-performance code is generated, a kind of knowledge-based code motion is used to move initialization code for refined components out of loops. Other special mechanisms were installed to allow results of computations in generated programs to be stored and reused at later points. These mechanisms have the advantage of being easy to define and install, which is attractive for small examples.
Both of these mechanisms are subsumed by conventional compiler optimization techniques that couple code motion with common subexpression elimination. The knowledge-based versions are somewhat fragile, and KB encoders of algorithms had to think carefully about how to use them. The compiler methods simply work without thought; this makes the system more robust, and it makes KB augmentation faster because less has to be explicitly encoded.
There will still be cases where compiler methods fail because the cost of inference is simply too high. In these cases, knowledge can play a useful role.