Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/pure-cfg/src/compiler/IL/dom-tree-fn.sml
ViewVC logotype

View of /branches/pure-cfg/src/compiler/IL/dom-tree-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 740 - (download) (annotate)
Mon Apr 4 02:07:42 2011 UTC (8 years, 4 months ago) by jhr
File size: 3602 byte(s)
  Working on value-numbering optimization
(* dom-tree-fn.sml
 *
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *)

signature DOMINANCE_TREE =
  sig

    structure IL : SSA

  (* compute the dominance-tree information for a CFG *)
    val computeTree : IL.cfg -> unit

  (* get the dominance-tree children associated with a given node *)
    val children : IL.node -> IL.node list

  (* cleanup the node properties used to store information about the tree *)
    val clear : IL.cfg -> unit

  end

functor DomTreeFn (IL : SSA) : DOMINANCE_TREE = struct

    structure IL = IL
    structure Nd = IL.Node

  (* a property for COND nodes that maps them to their associated JOIN node
   * (if one exists).
   *)
    val {
	  peekFn = getJoin : IL.node -> IL.node option,
	  setFn = setJoin, clrFn = clrJoin, ...
	} = Nd.newProp (fn _ => raise Fail "join property")

  (* an element on the stack of open COND nodes. *)
    datatype open_if
      = THEN_BR of {cond : IL.node, elseBr : IL.node}
      | ELSE_BR of {cond : IL.node}

  (* compute the dominance-tree information for a CFG.  Most of the immediate
   * dominator info is already present in the tree, since JOIN nodes are the
   * only ones with multiple predecessors, but we also need tree edges from
   * COND nodes to their matching JOIN (it it exists).  We use properties
   * to implemented these edges
   *)
    fun computeTree cfg = let
	  fun walk (ifStk : open_if list, nd) = (case Nd.kind nd
		 of IL.NULL => raise Fail "unexpected NULL node"
		  | IL.ENTRY{succ} => walk (ifStk, !succ)
		  | IL.JOIN{succ, ...} => (case ifStk
		       of [] => raise Fail "unmatched JOIN"
			| THEN_BR{cond, elseBr}::r => (
			    setJoin(cond, nd);
			    walk (ELSE_BR{cond=cond}::r, elseBr))
			| ELSE_BR{cond}::r => (
			    setJoin(cond, nd);  (* may be redundant *)
			    walk (r, !succ))
		      (* end case *))
		  | IL.COND{trueBranch, falseBranch, ...} =>
		      walk (THEN_BR{cond=nd, elseBr = !falseBranch}::ifStk, !trueBranch)
		  | IL.COM{succ, ...} => walk (ifStk, !succ)
		  | IL.ASSIGN{succ, ...} => walk (ifStk, !succ)
		  | IL.NEW{succ, ...} => walk (ifStk, !succ)
		  | IL.EXIT _ => resume ifStk
		(* end case *))
	  and resume [] = ()
	    | resume (THEN_BR{cond, elseBr}::r) = walk (ELSE_BR{cond=cond}::r, elseBr)
	    | resume (ELSE_BR{cond}::r) = (case getJoin cond
		 of NONE => resume r
		  | SOME nd' => walk(r, nd')
		(* end case *))
	  in
	    walk ([], IL.CFG.entry cfg)
	  end

  (* get the dominance-tree children associated with a given node *)
    fun children nd = let
	(* check to see if a successor node is immediately dominated by nd. *)
	  fun maybeSucc (ref nd') = (case Nd.kind nd'
		 of IL.JOIN{preds, ...} => (case !preds
		       of [_] => [nd'] (* JOIN with single predecessor *)
			| _ => []
		      (* end case *))
		  | IL.COM{succ, ...} => maybeSucc succ (* skip comments *)
		  | _ => [nd']
		(* end case *))
	  in
	    case Nd.kind nd
	     of IL.NULL => raise Fail "unexpected NULL node"
	      | IL.ENTRY{succ} => maybeSucc succ
	      | IL.JOIN{succ, ...} => maybeSucc succ
	      | IL.COND{trueBranch, falseBranch, ...} => (case getJoin nd
		   of SOME nd' => [!trueBranch, !falseBranch, nd']
		    | NONE => [!trueBranch, !falseBranch]
		  (* end case *))
	      | IL.COM{succ, ...} => maybeSucc succ
	      | IL.ASSIGN{succ, ...} => maybeSucc succ
	      | IL.NEW{succ, ...} => maybeSucc succ
	      | IL.EXIT _ => []
	    (* end case *)
	  end

  (* cleanup the node properties used to store information about the tree *)
    fun clear cfg = IL.CFG.apply clrJoin cfg

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0