preserve and keep attributes are grest for specific signals that you want to see after optimization.
Another way to preserve the entire hierarchical boundary very strictly is to define the blocks as separate partitions for incremental compilation. In Project Navigator, right-click > Set as Design Partition. You don't have to make any settings for the Design Partitions if you don't care about preserving fitter results, but know that by default post-synthesis results are reused in the next compile unless you change the source code (that is, settings do not trigger recompilation).
Note that making them partitions will prevent *any* cross-boundary optimizations including constant connections or unused ports - so be sure you really do want your logic blocks to be totally separate.
I think the docs say something about this too... Yep here it is. From
http://www.altera.com/literature/hb/qts/qts_qii51008.pdf:
A design partition represents a portion of the design that you want to
synthesize and fit incrementally. Incremental compilation maintains the
hierarchical boundaries of design partitions, so you can use design
partitions if you need to preserve hierarchical boundaries through the
synthesis and fitting process. For example, if you are performing formal
verification, you must use partitions with the full incremental
compilation flow to ensure that no optimizations occur across specific
design hierarchies.
Beginning with the Quartus II software version 6.0, Altera
recommends that you use Design Partition assignments instead
of the Preserve Hierarchical Boundary logic option, which may
be removed in future versions of the Quartus II software.