LRDE Tiger Compiler  1.34a $Id: 7fef12e1f5fa43449d667a0eec1d837c40fc1202 $
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
canon::Canon Class Reference

Object function to canonicalize tree::Tree code. More...

#include <canon.hh>

Public Member Functions

 Canon (bool trace_p=false)
 Build a canonizer.
tree::rStm operator() (const tree::rStm &tree)
 Canonicalizing Eseq and Calls.

Private Member Functions

tree::rTree canon (tree::rTree tree)
 The actual worker.
bool commutes_with_all_eseq (const tree::rTree &a, tree::tree_list_type::iterator start, tree::tree_list_type::iterator end)
 Are there any ESEQ in [begin, end) such that a does not commute with its SEQ part? Iff there are, return FALSE.
tree::rStm assemble_stm (const tree::rStm &s1, const tree::rStm &s2)
 Assemble statements s1 and s2 together.
tree::rExp assemble_eseq (tree::rStm s, tree::rExp e)
 Assemble statement s and expression e together.
tree::rSeq operator() (const tree::rSeq &seq)
 Canonicalize seq, in particular, bubble up the sub SEQ, and get rid of nops..
tree::rExp operator() (const tree::rEseq &eseq)
 Canonicalize eseq.
bool valid_call (const tree::rTree &tree, const tree::rTree &call)
 Is call a (LIR-)valid son of tree?
tree::rTree canon_default (const tree::rTree &tree)
 Canonicalize tree: lift the ESEQ children higher.

Private Attributes

bool trace_p_
 Report debugging information.

Detailed Description

Object function to canonicalize tree::Tree code.

Constructor & Destructor Documentation

canon::Canon::Canon ( bool  trace_p = false)

Build a canonizer.

Member Function Documentation

tree::rExp canon::Canon::assemble_eseq ( tree::rStm  s,
tree::rExp  e 
)
private

Assemble statement s and expression e together.

References assemble_stm(), and tree::Eseq::stm_get().

Referenced by canon_default(), and operator()().

tree::rStm canon::Canon::assemble_stm ( const tree::rStm &  s1,
const tree::rStm &  s2 
)
private

Assemble statements s1 and s2 together.

References tree::Tree::children_get().

Referenced by assemble_eseq(), and canon_default().

tree::rTree canon::Canon::canon ( tree::rTree  tree)
private
tree::rTree canon::Canon::canon_default ( const tree::rTree &  tree)
private

Canonicalize tree: lift the ESEQ children higher.

Canonicalize \a tree: lift the ESEQ children higher.

tree is not an ESEQ nor a SEQ. Pay attention to the case of CALL too.

The logic here is different from that of Appel. He suggest that when we find an eseq, we should move its statement backwards, and pay attention to the conflicts with expressions that don't commute with this statement, in which case you need to store the value of this expression in a temporary, and move this move.

This is probably very natural in a recursive implementation, but we are based on lists, and this is awkward.

The implementation below has a different viewpoint: for instance with "call(name f, e1, eseq(s1, e2))", we don't wait to study "eseq(s1, e2)" to realize that "e1" has to move: when we study "e1" we look whether it commutes with any eseq-statement (here "s1") that follow it, and if not, we immediately move it. As a consequence, when we reach an eseq-statement (again, "s1"), there is nothing magical to do: just move it.

References assemble_eseq(), assemble_stm(), precondition, and valid_call().

Referenced by canon().

bool canon::Canon::commutes_with_all_eseq ( const tree::rTree &  a,
tree::tree_list_type::iterator  start,
tree::tree_list_type::iterator  end 
)
private

Are there any ESEQ in [begin, end) such that a does not commute with its SEQ part? Iff there are, return FALSE.

References tree::Eseq::stm_get().

tree::rStm canon::Canon::operator() ( const tree::rStm &  tree)

Canonicalizing Eseq and Calls.

References canon(), misc::decendl(), misc::decindent(), misc::iendl(), misc::incendl(), and trace_p_.

Referenced by canon().

tree::rSeq canon::Canon::operator() ( const tree::rSeq &  seq)
private

Canonicalize seq, in particular, bubble up the sub SEQ, and get rid of nops..

References misc::decendl(), misc::incendl(), tree::Seq::push_back(), and trace_p_.

tree::rExp canon::Canon::operator() ( const tree::rEseq &  eseq)
private

Canonicalize eseq.

References assemble_eseq().

bool canon::Canon::valid_call ( const tree::rTree &  tree,
const tree::rTree &  call 
)
private

Is call a (LIR-)valid son of tree?

Valid CALLs are:

SXP(CALL ...)

MOVE(TEMP, CALL ...)

Referenced by canon_default().

Member Data Documentation

bool canon::Canon::trace_p_
private

Report debugging information.

Referenced by canon(), and operator()().


The documentation for this class was generated from the following files: