123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2010 Jérôme Vouillon
* Laboratoire PPS - CNRS Université Paris Diderot
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)open!Stdliblettimes=Debug.find"times"openCode(****)letadd_var=Var.ISet.addletadd_defvarsdefsxy=add_varvarsx;letidx=Var.idxxindefs.(idx)<-Var.Set.addydefs.(idx)letadd_depdepsxy=letidx=Var.idxyindeps.(idx)<-Var.Set.addxdeps.(idx)letrecarg_depsvarsdepsdefsparamsargs=matchparams,argswith|x::params,y::args->add_depdepsxy;add_defvarsdefsxy;arg_depsvarsdepsdefsparamsargs|_->()letcont_depsblocksvarsdepsdefs(pc,args)=letblock=Addr.Map.findpcblocksinarg_depsvarsdepsdefsblock.paramsargsletexpr_depsblocksvarsdepsdefsxe=matchewith|Constant_|Apply_|Prim_->()|Closure(_,cont)->cont_depsblocksvarsdepsdefscont|Block(_,a,_)->Array.itera~f:(funy->add_depdepsxy)|Field(y,_)->add_depdepsxyletprogram_deps{blocks;_}=letnv=Var.count()inletvars=Var.ISet.empty()inletdeps=Array.makenvVar.Set.emptyinletdefs=Array.makenvVar.Set.emptyinAddr.Map.iter(fun_pcblock->List.iterblock.body~f:(funi->matchiwith|Let(x,e)->add_varvarsx;expr_depsblocksvarsdepsdefsxe|Set_field_|Array_set_|Offset_ref_->());Option.iterblock.handler~f:(fun(_,cont)->cont_depsblocksvarsdepsdefscont);matchblock.branchwith|Return_|Raise_|Stop->()|Branchcont->cont_depsblocksvarsdepsdefscont|Cond(_,cont1,cont2)->cont_depsblocksvarsdepsdefscont1;cont_depsblocksvarsdepsdefscont2|Switch(_,a1,a2)->Array.itera1~f:(funcont->cont_depsblocksvarsdepsdefscont);Array.itera2~f:(funcont->cont_depsblocksvarsdepsdefscont)|Pushtrap(cont,_,_,_)->cont_depsblocksvarsdepsdefscont|Poptrap(cont,_)->cont_depsblocksvarsdepsdefscont)blocks;vars,deps,defsletrecrepr'reprsxacc=letidx=Var.idxxinmatchreprs.(idx)with|None->x,acc|Somey->repr'reprsy(x::acc)letreprreprsx=letlast,l=repr'reprsx[]inList.iterl~f:(funv->reprs.(Var.idxv)<-Somelast);lastletreplacedepsreprsxy=letyidx=Var.idxyinletxidx=Var.idxxindeps.(yidx)<-Var.Set.uniondeps.(yidx)deps.(xidx);reprs.(xidx)<-Somey;trueletpropagate1depsdefsreprsstx=letprev=Var.Tbl.getstxinifprevthenprevelseletidx=Var.idxxinlets=Var.Set.fold(funxs->Var.Set.add(reprreprsx)s)defs.(idx)Var.Set.emptyindefs.(idx)<-s;matchVar.Set.cardinalswith|1->replacedepsreprsx(Var.Set.chooses)|2->(matchVar.Set.elementsswith|[y;z]whenVar.comparexy=0->replacedepsreprsxz|[z;y]whenVar.comparexy=0->replacedepsreprsxz|_->false)|_->falsemoduleG=Dgraph.Make_Imperative(Var)(Var.ISet)(Var.Tbl)moduleDomain1=structtypet=boolletequal=Bool.equalletbot=falseendmoduleSolver1=G.Solver(Domain1)letsolver1varsdepsdefs=letnv=Var.count()inletreprs=Array.makenvNoneinletg={G.domain=vars;G.iter_children=(funfx->Var.Set.iterfdeps.(Var.idxx))}inignore(Solver1.f()g(propagate1depsdefsreprs));Array.mapireprs~f:(funidxy->matchywith|Somey->lety=reprreprsyinifVar.idxy=idxthenNoneelseSomey|None->None)letfp=lett=Timer.make()inlett'=Timer.make()inletvars,deps,defs=program_depspiniftimes()thenFormat.eprintf" phi-simpl. 1: %a@."Timer.printt';lett'=Timer.make()inletsubst=solver1varsdepsdefsiniftimes()thenFormat.eprintf" phi-simpl. 2: %a@."Timer.printt';letp=Subst.program(Subst.from_arraysubst)piniftimes()thenFormat.eprintf" phi-simpl.: %a@."Timer.printt;p