Skip to content

Commit

Permalink
Standard math functions in Modelica.Math are not evaluated instead of…
Browse files Browse the repository at this point in the history
… compiled and run in Ceval.rml

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@1975 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Peter Aronsson committed Nov 18, 2005
1 parent eedd717 commit 6d72b4b
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 37 deletions.
173 changes: 137 additions & 36 deletions Compiler/Ceval.rml
Expand Up @@ -91,7 +91,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
bool, (*impl*)
Msg)
=> Exp.Subscript list


relation is_known_external_func:( string, string option) => ()
end


Expand Down Expand Up @@ -319,49 +320,18 @@ end
=> (Values.REAL(resr),st'')



(* FIXME: disabled calling of functions during ceval for now. Some
* functions call other functions, which must be generated together in
* order that compilation works *)
(*
axiom ceval (env, e as Exp.CALL(funcpath,expl,_,builtin as false),impl as false,st as NONE,_) => fail
*)

(* Call functions in non-interactive mode. *)
(* Call functions *)
(* FIXME: functions are always generated. Put back the check
and write another rule for the false case that generates the function *)
rule ceval_list(env,expl,impl,st,msg) => vallst &
ceval_call_function (env,e,vallst,msg) => newval
-------------------------------------------------------
ceval (env, e as Exp.CALL(funcpath,expl,_,builtin as false),impl as false,st as NONE,_,msg) => (newval,st)

(* ceval (env, e as Exp.CALL(funcpath,expl,_,_),false,st as SOME(Interactive.SYMBOLTABLE(_,_,_,_,cflist)),_) => (newval,st)
*)


(* FIXME: Fix this in order to allow calling of constant-marked function
* calls. One should call the function as if we were in interactive
* mode, and put the result instead of the function call *)

(*
ceval (env, e as Exp.CALL(funcpath,expl,_,builtin),impl,st,_,msg)
=> (newval,st)

rule Print.print_buf "# Can't call builtin functions at compile time\n" &
Print.print_buf " expression: " & Exp.print_exp e & Print.print_buf "\n"
-------------------------------------------------------
ceval (env, e as Exp.CALL(_,_,_,builtin as true),impl as false,NONE,_) => fail
*)

rule Print.print_buf "# Can't call functions at compile time\n" &
Print.print_buf " expression: " & Exp.print_exp e & Print.print_buf "\n"
-------------------------------------------------------
ceval (env, e as Exp.CALL(_,_,_,_),impl as false,NONE,_,MSG) => fail

axiom ceval (env, e as Exp.CALL(_,_,_,_),impl as false,NONE,_,NO_MSG) => fail

rule (* Print.print_buf "implicit evaluation of function calls without symbol table, exp: " &
Exp.print_exp e & Print.print_buf "\n" *)
-------------------------------------------
ceval(env, e as Exp.CALL(_,_,_,_),impl as true,NONE,_,_) => fail

rule ceval_interactive_functions(env,e,st,msg) => (value,st)
-------------------------------------
Expand Down Expand Up @@ -720,7 +690,14 @@ relation ceval_call_function : (Env.Env,
Values.Value list, (* input parameter values*)
Msg) (* Should error messages be printed. *)
=> Values.Value (* resulting value *) =

(* External functions that are "known" should be evaluated without
* compilation, e.g. all math functions *)
rule ceval_known_external_funcs(env,funcpath,vallst,msg) => newval
-------------------------------------------------------
ceval_call_function (env, e as Exp.CALL(funcpath,expl,_,builtin),
vallst,msg) => newval


(* Call functions in non-interactive mode. *)
(* FIXME: functions are always generated. Put back the check
and write another rule for the false case that generates the function *)
Expand All @@ -744,6 +721,130 @@ relation ceval_call_function : (Env.Env,

end


(** relation: ceval_known_external_funcs
**
** Evaluates external functions that are known, e.g. all math functions.
**)
relation ceval_known_external_funcs: (Env.Env,
Absyn.Path,
Values.Value list,
Msg) => Values.Value =

rule Lookup.lookup_class(env,funcpath,false) => (cdef,env') &
let SCode.CLASS(fid,_,_,SCode.R_EXT_FUNCTION,SCode.PARTS(_,_,_,_,_,extdecl)) = cdef &
let SOME(Absyn.EXTERNALDECL(id,lan,out,args,_)) = extdecl &
is_known_external_func(fid,id) &
ceval_known_external_funcs2(fid,id,vals,msg) => res
-----------------------------
ceval_known_external_funcs(env,funcpath,vals,msg) => res
end

(** relation is_known_external_func
**
** Succeds if external function name is "known", i.e. no compilation
** required.
**)

relation is_known_external_func:( SCode.Ident, Absyn.Ident option) => () =

axiom is_known_external_func("acos",SOME("acos"))
axiom is_known_external_func("asin",SOME("asin"))
axiom is_known_external_func("atan",SOME("atan"))
axiom is_known_external_func("atan2",SOME("atan2"))
axiom is_known_external_func("cos",SOME("cos"))
axiom is_known_external_func("cosh",SOME("cosh"))
axiom is_known_external_func("exp",SOME("exp"))
axiom is_known_external_func("log",SOME("log"))
axiom is_known_external_func("log10",SOME("log10"))
axiom is_known_external_func("sin",SOME("sin"))
axiom is_known_external_func("sinh",SOME("sinh"))
axiom is_known_external_func("tan",SOME("tan"))
axiom is_known_external_func("tanh",SOME("tanh"))
end


(** relation: ceval_known_external_funcs2
** author: PA
**
** Helper relation to ceval_known_external_funcs, does the evaluation.
**)

relation ceval_known_external_funcs2: (SCode.Ident,
Absyn.Ident option,
Values.Value list,
Msg) => Values.Value =

rule System.acos rv => rv'
--------------------------
ceval_known_external_funcs2("acos",SOME("acos"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.asin rv => rv'
--------------------------
ceval_known_external_funcs2("asin",SOME("asin"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.atan(rv) => rv'
--------------------------
ceval_known_external_funcs2("atan",SOME("atan"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.atan2(rv1,rv2) => rv'
--------------------------
ceval_known_external_funcs2("atan2",SOME("atan2"),[Values.REAL(rv1),
Values.REAL(rv2)
],_)
=> Values.REAL(rv')

rule real_cos(rv) => rv'
--------------------------
ceval_known_external_funcs2("cos",SOME("cos"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.cosh(rv) => rv'
--------------------------
ceval_known_external_funcs2("cosh",SOME("cosh"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule real_exp(rv) => rv'
--------------------------
ceval_known_external_funcs2("exp",SOME("exp"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.log(rv) => rv'
--------------------------
ceval_known_external_funcs2("log",SOME("log"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.log10(rv) => rv'
--------------------------
ceval_known_external_funcs2("log10",SOME("log10"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule real_sin(rv) => rv'
--------------------------
ceval_known_external_funcs2("sin",SOME("sin"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.sinh(rv) => rv'
--------------------------
ceval_known_external_funcs2("sinh",SOME("sinh"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule real_sin rv => sv &
real_cos rv => cv &
real_div(sv,cv) => rv'
--------------------------
ceval_known_external_funcs2("tan",SOME("tan"),[Values.REAL(rv)],_)
=> Values.REAL(rv')

rule System.tanh(rv) => rv'
--------------------------
ceval_known_external_funcs2("tanh",SOME("tanh"),[Values.REAL(rv)],_)
=> Values.REAL(rv')
end

(** relation: ceval_function
**
** For constant evaluation of functions returning a single value. For now only
Expand Down
21 changes: 20 additions & 1 deletion Compiler/SimCodegen.rml
Expand Up @@ -2030,7 +2030,7 @@ relation generate_init_data2:(DAELow.DAELow,
array_list(nyarr3) => ny_lst &
array_list(nparr3) => np_lst &
Util.list_flatten([nx_lst,nxd_lst,ny_lst,np_lst]) => whole_lst &
Util.string_delimit_list(whole_lst,"\n") => res
Util.string_delimit_list_no_empty(whole_lst,"\n") => res
-----------------------------
generate_init_data2(DAELow.DAELOW(vars,knvars,_,_,initeqn,alg,_),nx,ny,np) => res

Expand Down Expand Up @@ -2339,6 +2339,15 @@ relation generate_zero_crossing2: (DAELow.ZeroCrossing list, int,
--------------------------------------------------
generate_zero_crossing2((zc as DAELow.ZERO_CROSSING(_,eql,_))::xs,
index,dae,dlow,ass1,ass2,blocks,helpVarInfo) => (res1,res2)

rule dump_zero_crossing_str zc => zc_str &
Util.string_append_list(["Internal Error generating zero crossing :",
zc_str,"\n"]) => res &
Print.print_error_buf res
------------------------
generate_zero_crossing2((zc as DAELow.ZERO_CROSSING(_,eql,_))::xs,
index,dae,dlow,ass1,ass2,blocks,helpVarInfo)
=> fail
end


Expand All @@ -2357,6 +2366,12 @@ relation dump_zero_crossing_str: (DAELow.ZeroCrossing) => string =
----------------------------------------
dump_zero_crossing_str (DAELow.ZERO_CROSSING(Exp.CALL(Absyn.IDENT("sample"),[start,interval],_,_),_,_)) => zc_str

rule print_exp_cpp_str(e) => e_str &
Util.string_append_list(["/*Unknown zero crossing: ",e_str," */"])
=> zc_str
-------------------
dump_zero_crossing_str (DAELow.ZERO_CROSSING(e,_,_)) => zc_str

end

relation isZeroCrossingAffectingHelpVar: ((int * Exp.Exp * int), (int * DAELow.DAELow)) => bool =
Expand All @@ -2381,6 +2396,10 @@ relation build_help_var_assignments: ( (int * Exp.Exp * int) list ) => string =
string_append(res1,res2) => res
--------------------------------------------------
build_help_var_assignments((helpVarIndex, e,_)::rest) => res

rule Print.print_error_buf "Internal Error, build_help_var_assignments failed\n"
--------------------------------------------------
build_help_var_assignments(_) => fail
end

relation print_zero_crossing_op_str: (Exp.Operator) => string =
Expand Down
9 changes: 9 additions & 0 deletions Compiler/Static.rml
Expand Up @@ -3315,6 +3315,15 @@ relation generate_compiled_function: (Env.Env, Absyn.ComponentRef, Exp.Exp, Type
-----------------------------------------------
generate_compiled_function(env,fn,e,prop,SOME(st as Interactive.SYMBOLTABLE(p,_,_,_,cflist))) => SOME(st)

(* Don not compile if is "known" external function, e.g. math lib.*)
rule Absyn.cref_to_path(fn) => path &
Lookup.lookup_class(env,path,false) => (cdef,env') &
let SCode.CLASS(fid,_,_,SCode.R_EXT_FUNCTION,SCode.PARTS(_,_,_,_,_,extdecl)) = cdef &
let SOME(Absyn.EXTERNALDECL(id,lan,out,args,_)) = extdecl &
Ceval.is_known_external_func(fid,id)
----------------------------------
generate_compiled_function(env,fn,e,prop,st) => st

rule Debug.fprintln("sei", "generate_compiled_function: start2") &
Absyn.cref_to_path(fn) => path &
is_function_in_cflist (cflist, path) => false &
Expand Down
41 changes: 41 additions & 0 deletions Compiler/System.rml
Expand Up @@ -301,6 +301,47 @@ relation acos: real => real

relation atan: real => real

(** relation: atan2
**
** Arctan2 is not defined in rml.
**)

relation atan2: (real,real) => real

(** relation: cosh
**
** Cosh is not defined in rml.
**)

relation cosh: real => real

(** relation: log
**
** log is not defined in rml.
**)

relation log: real => real

(** relation: log10
**
** log10 is not defined in rml.
**)

relation log10: real => real

(** relation: sinh
**
** sinh is not defined in rml.
**)

relation sinh: real => real

(** relation: tanh
**
** tanh is not defined in rml.
**)

relation tanh: real => real

(** relation get_classnames_for_simulation
** this returns a list of classnames that are in the
Expand Down
43 changes: 43 additions & 0 deletions Compiler/runtime/systemimpl.c
Expand Up @@ -967,6 +967,49 @@ RML_BEGIN_LABEL(System__atan)
}
RML_END_LABEL

RML_BEGIN_LABEL(System__atan2)
{
rmlA0 = rml_prim_mkreal(atan2(rml_prim_get_real(rmlA0),
rml_prim_get_real(rmlA1)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__cosh)
{
rmlA0 = rml_prim_mkreal(cosh(rml_prim_get_real(rmlA0)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__log)
{
rmlA0 = rml_prim_mkreal(log(rml_prim_get_real(rmlA0)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__log10)
{
rmlA0 = rml_prim_mkreal(log10(rml_prim_get_real(rmlA0)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__sinh)
{
rmlA0 = rml_prim_mkreal(sinh(rml_prim_get_real(rmlA0)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__tanh)
{
rmlA0 = rml_prim_mkreal(tanh(rml_prim_get_real(rmlA0)));
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

float next_realelt(float *arr)
{
static int curpos;
Expand Down

0 comments on commit 6d72b4b

Please sign in to comment.