title: Compiler code optimization: AST vs. IR
body: <p>, where I define IR as a 3-address code type representation (I realize that one can mean by it an AST representation as well).</p>
  
  <p>It is my understanding that, when writing a best-practice compiler for an <em>imperative language</em>, code optimization happens both on the AST (probably best using a Visitor Pattern), and on the IR produced from the AST. </p>
  
  <p>(a) Is that correct?</p>
  
  <p>(b) Which type of optimization steps are best handled on the AST before even producing an IR? (reference to an article/a list online welcome too as long as it deals with an imperative language) </p>
  
  <p>The compiler I'm working on is for Decaf (which some might know) which has a fairly deep CFG up to (single) class inheritance; I'll add features not part of it such as type coercion. It will be completely hand-coded (using no tools whatsoever). This is not homework; writing it for fun. </p>