123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778(* 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!StdlibopenCode(****)letpure_exprpure_funse=matchewith|Block_|Field_|Closure_|Constant_->true|Special(Alias_prim_)->true|Apply{f;exact;_}->exact&&Var.Set.memfpure_funs|Prim(p,_l)->(matchpwith|Externf->Primitive.is_puref|_->true)letpure_instrpure_funsi=matchiwith|Let(_,e)->pure_exprpure_funse|Event_|Assign_->true|Set_field_|Offset_ref_|Array_set_->false(****)letrectraverseblockspcvisitedfuns=tryAddr.Map.findpcvisited,visited,funswithNot_found->letvisited=Addr.Map.addpcfalsevisitedinletpure,visited,funs=fold_childrenblockspc(funpc(pure,visited,funs)->letpure',visited,funs=traverseblockspcvisitedfunsinpure&&pure',visited,funs)(true,visited,funs)inletpure,visited,funs=blockblockspcpurevisitedfunsinpure,Addr.Map.addpcpurevisited,funsandblockblockspcpurevisitedfuns=letb=Addr.Map.findpcblocksinletpure=matchb.branchwith|Raise_->false|_->pureinList.fold_leftb.body~init:(pure,visited,funs)~f:(fun(pure,visited,funs)i->letvisited,funs=matchiwith|Let(x,Closure(_,(pc,_)))->letpure,visited,funs=traverseblockspcvisitedfunsinvisited,ifpurethenVar.Set.addxfunselsefuns|_->visited,funsinpure&&pure_instrfunsi,visited,funs)letfp=let_,_,funs=traversep.blocksp.startAddr.Map.emptyVar.Set.emptyinfuns