Home My Page Projects Code Snippets Project Openings diderot

# SCM Repository

[diderot] View of /branches/lamont/src/compiler/simplify/reduction_lift.sml
 [diderot] / branches / lamont / src / compiler / simplify / reduction_lift.sml

# View of /branches/lamont/src/compiler/simplify/reduction_lift.sml

Sun Mar 3 14:51:31 2013 UTC (6 years, 7 months ago) by lamonts
File size: 3524 byte(s)
`Added Reductions into its own block and allow strands to use the strand pool correctly when allocating new strands`
```(* reduction_lift.sml
*
* COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)
*
* Lift reduction operations into its own block.
*
* NOTE: this process can be streamlined as follows:
*	1) Find the reduction expressions
*	2) Move the reduction and prior statements needed for the reduction into the global reduction block.
*)

structure ReductionLift : sig

val transform : Error.err_stream * Simple.program -> Simple.program

end = struct

structure S = Simple

local
val cnt = ref 0
fun genName prefix = let
val n = !cnt
in
cnt := n+1;
String.concat[prefix, "_", Int.toString n]
end
in
fun newGlobalR (r,ty) = Var.new (Atom.atom (genName(String.concat["r_",r])), AST.GlobalVar,ty)
end

fun reductionToString(r) = (case r
of S.R_Max => "max"
| S.R_Min => "min"
| S.R_Exists => "exists"
| S.R_All => "all"
| S.R_Product => "product"
| S.R_Mean => "mean"
| S.R_Variance => "variance"
| S.R_Sum => "sum")

fun transform (errStrm,prog as S.Program{globals,globalInit as S.Block(globalInitStms), init, strands,globalBlock,inputs,...}) = let

val globalReduc = ref []

fun reduceStrand(S.Strand{name, params, state,stateInit,methods}) =
S.Strand{
name = name,
params = params,
state = state, stateInit = stateInit,
methods = List.map reduceMethod methods
}

and reduceMethod (S.Method(name, body)) =
S.Method(name, reduceBlock body)

and reduceBlock (S.Block stms) = S.Block(List.rev (reduceStmts(stms,[])))

and reduceStmts ((stm::stms),stms') = (case stm
of S.S_Foreach(v,e,b) => reduceStmts(stms,S.S_Foreach(v, e, reduceBlock b)::stms')
| S.S_IfThenElse(v,b1,b2) => reduceStmts(stms,S.S_IfThenElse(v,reduceBlock b1, reduceBlock b2)::stms')
| S.S_Assign (lhs,rhs) => (case reduceAssign (lhs,rhs)
of NONE => reduceStmts(stms,stms')
| SOME rhs' => reduceStmts(stms,S.S_Assign(lhs,rhs')::stms')
(* end case *))
| _ => reduceStmts(stms,stm::stms'))
| reduceStmts ([],stms') = stms'

and reduceAssign(lhs,rhs) = (case rhs
of S.E_Reduction(r,sv,reduceStms,x'',ty) => let
fun initReduction(r) = (case r
of S.R_All => S.E_Lit(Literal.Bool(true))
| S.R_Exists => S.E_Lit(Literal.Bool(false))
| S.R_Min => S.E_Lit(Literal.Float(FloatLit.posInf))
| S.R_Max => S.E_Lit(Literal.Float(FloatLit.negInf))
| S.R_Product => S.E_Lit(Literal.Float(FloatLit.fromInt 1))
| S.R_Sum => S.E_Lit(Literal.Float (FloatLit.fromInt 0))
| S.R_Mean => S.E_Lit(Literal.Float (FloatLit.fromInt 0))
| S.R_Variance => S.E_Lit(Literal.Float (FloatLit.fromInt 0))
(* end case *))

val stm = S.S_Assign(lhs,S.E_Reduction(r,sv,reduceStms,x'',ty))
in
globalReduc := (reduceStms @ [stm])@(!globalReduc);
NONE
end
| _ => SOME(rhs))

val prog' =
S.Program{
strands = strands,
globals = globals,
globalInit = globalInit,
globalBlock = reduceBlock(globalBlock),
globalReduce = S.Block(!globalReduc),
init = init,
inputs = inputs
}
(* val _ = SimplePP.output (Log.logFile(), prog)*)	(* DEBUG *)
in
prog'
end

end
```