Skip to content

Commit

Permalink
[NF] Various improvements.
Browse files Browse the repository at this point in the history
- Fixed ceval of ^ by actually using ^ and not /.
- Fixed type when converting array parameters in function to DAE.
- Added new model simplification phase, which currently only removes
  some empty array crefs in function calls.

Belonging to [master]:
  - OpenModelica/OMCompiler#2433
  • Loading branch information
perost authored and OpenModelica-Hudson committed May 14, 2018
1 parent 52e894f commit fb58909
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 8 deletions.
4 changes: 2 additions & 2 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -544,7 +544,7 @@ function evalBinaryPow
algorithm
exp := match (exp1, exp2)
case (Expression.REAL(), Expression.REAL())
then Expression.REAL(exp1.value / exp2.value);
then Expression.REAL(exp1.value ^ exp2.value);

case (Expression.ARRAY(), Expression.ARRAY())
guard listLength(exp1.elements) == listLength(exp2.elements)
Expand All @@ -553,7 +553,7 @@ algorithm

else
algorithm
exp := Expression.BINARY(exp1, Operator.makeMul(Type.UNKNOWN()), exp2);
exp := Expression.BINARY(exp1, Operator.makePow(Type.UNKNOWN()), exp2);
printFailedEvalError(getInstanceName(), exp, sourceInfo());
then
fail();
Expand Down
4 changes: 2 additions & 2 deletions Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -133,7 +133,7 @@ protected
Direction dir;
algorithm
dcref := ComponentRef.toDAE(cref);
dty := Type.toDAE(ty);
dty := Type.toDAE(if isFunctionParam then Type.arrayElementType(ty) else ty);
source := ElementSource.createElementSource(info);

var := match attr
Expand All @@ -155,7 +155,7 @@ algorithm
Prefixes.visibilityToDAE(vis),
dty,
binding,
if isFunctionParam then {} else ComponentReference.crefDims(dcref),
ComponentReference.crefDims(dcref),
Prefixes.connectorTypeToDAE(attr.connectorType),
source,
vattr,
Expand Down
10 changes: 10 additions & 0 deletions Compiler/NFFrontEnd/NFDimension.mo
Expand Up @@ -221,6 +221,16 @@ public
end match;
end isKnown;

function isZero
input Dimension dim;
output Boolean isZero;
algorithm
isZero := match dim
case INTEGER() then dim.size == 0;
else false;
end match;
end isZero;

function subscriptType
"Returns the expected type of a subscript for the given dimension."
input Dimension dim;
Expand Down
14 changes: 12 additions & 2 deletions Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -199,14 +199,24 @@ public

function isCref
input Expression exp;
output Boolean isTrue;
output Boolean isCref;
algorithm
isTrue := match exp
isCref := match exp
case CREF() then true;
else false;
end match;
end isCref;

function isCall
input Expression exp;
output Boolean isCall;
algorithm
isCall := match exp
case CALL() then true;
else false;
end match;
end isCall;

function isTrue
input Expression exp;
output Boolean isTrue;
Expand Down
8 changes: 6 additions & 2 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -94,6 +94,7 @@ import NFFunction.Function;
import FlatModel = NFFlatModel;
import BindingOrigin = NFBindingOrigin;
import ElementSource;
import SimplifyModel = NFSimplifyModel;

type EquationScope = enumeration(NORMAL, INITIAL, WHEN);

Expand Down Expand Up @@ -139,15 +140,18 @@ algorithm
// Type the class.
Typing.typeClass(inst_cls, name);

// Flatten and convert the class into a DAE.
// Flatten and simplify the model.
(flat_model, funcs) := Flatten.flatten(inst_cls, name);
(flat_model, funcs) := SimplifyModel.simplify(flat_model, funcs);

// Collect package constants that couldn't be substituted with their values
// (e.g. because they where used with non-constants subscripts), and add them
// (e.g. because they where used with non-constant subscripts), and add them
// to the model.
flat_model := Package.collectConstants(flat_model, funcs);

// Scalarize array components in the flat model.
flat_model := Scalarize.scalarize(flat_model, name);
// Convert the flat model to a DAE.
(dae, daeFuncs) := ConvertDAE.convert(flat_model, funcs, name, InstNode.info(inst_cls));

// Do unit checking
Expand Down
213 changes: 213 additions & 0 deletions Compiler/NFFrontEnd/NFSimplifyModel.mo
@@ -0,0 +1,213 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from OSMC, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

encapsulated package NFSimplifyModel

import FlatModel = NFFlatModel;
import Equation = NFEquation;
import Statement = NFStatement;
import Expression = NFExpression;
import Type = NFType;
import ComponentRef = NFComponentRef;
import NFFlatten.FunctionTree;
import NFClass.Class;
import NFInstNode.InstNode;
import NFFunction.Function;
import Sections = NFSections;

protected
import MetaModelica.Dangerous.*;
import ExecStat.execStat;

public
function simplify
input output FlatModel flatModel;
input output FunctionTree functions;
algorithm
flatModel.equations := simplifyEquations(flatModel.equations);
flatModel.initialEquations := simplifyEquations(flatModel.initialEquations);

//functions := FunctionTree.map(functions, simplifyFunction);

execStat(getInstanceName());
end simplify;

function simplifyEquations
input list<Equation> eql;
output list<Equation> outEql = {};
algorithm
for eq in eql loop
outEql := simplifyEquation(eq, outEql);
end for;

outEql := listReverseInPlace(outEql);
end simplifyEquations;

function simplifyEquation
input Equation eq;
input output list<Equation> equations;
algorithm
equations := match eq
case Equation.EQUALITY()
algorithm
eq.lhs := removeEmptyTupleElements(eq.lhs);
eq.rhs := removeEmptyFunctionArguments(eq.rhs);
then
eq :: equations;

case Equation.ARRAY_EQUALITY()
algorithm
eq.rhs := removeEmptyFunctionArguments(eq.rhs);
then
eq :: equations;

case Equation.NORETCALL()
algorithm
eq.exp := removeEmptyFunctionArguments(eq.exp);
then
eq :: equations;

else eq :: equations;
end match;
end simplifyEquation;

function simplifyStatements
input list<Statement> stmts;
output list<Statement> outStmts = {};
algorithm
for s in stmts loop
outStmts := simplifyStatement(s, outStmts);
end for;

outStmts := listReverseInPlace(outStmts);
end simplifyStatements;

function simplifyStatement
input Statement stmt;
input output list<Statement> statements;
algorithm
statements := match stmt
case Statement.ASSIGNMENT()
algorithm
stmt.lhs := removeEmptyTupleElements(stmt.lhs);
stmt.rhs := removeEmptyFunctionArguments(stmt.rhs);
then
stmt :: statements;

case Statement.NORETCALL()
algorithm
stmt.exp := removeEmptyFunctionArguments(stmt.exp);
then
stmt :: statements;

else stmt :: statements;
end match;
end simplifyStatement;

function removeEmptyTupleElements
"Replaces tuple elements that has one or more zero dimension with _."
input output Expression exp;
algorithm
() := match exp
local
list<Type> tyl;

case Expression.TUPLE(ty = Type.TUPLE(types = tyl))
algorithm
exp.elements := list(
if Type.isEmptyArray(t) then Expression.CREF(t, ComponentRef.WILD()) else e
threaded for e in exp.elements, t in tyl);
then
();

else ();
end match;
end removeEmptyTupleElements;

function removeEmptyFunctionArguments
input Expression exp;
input Boolean isArg = false;
output Expression outExp;
protected
Boolean is_arg;
algorithm
if isArg then
() := match exp
case Expression.CREF() guard Type.isEmptyArray(exp.ty)
algorithm
//outExp := Expression.ARRAY(exp.ty, {});
outExp := Expression.fillType(exp.ty, Expression.INTEGER(0));
return;
then
();

else ();
end match;
end if;

is_arg := isArg or Expression.isCall(exp);
outExp := Expression.mapShallow(exp, function removeEmptyFunctionArguments(isArg = is_arg));
end removeEmptyFunctionArguments;

function simplifyFunction
input Absyn.Path name;
input output Function func;
protected
Class cls;
list<Statement> fn_body;
Sections sections;
algorithm
cls := InstNode.getClass(func.node);

() := match cls
case Class.INSTANCED_CLASS(sections = sections)
algorithm
() := match sections
case Sections.SECTIONS(algorithms = {fn_body})
algorithm
fn_body := simplifyStatements(fn_body);
sections.algorithms := {fn_body};
cls.sections := sections;
InstNode.updateClass(cls, func.node);
then
();

else ();
end match;
then
();

else ();
end match;
end simplifyFunction;

annotation(__OpenModelica_Interface="frontend");
end NFSimplifyModel;
10 changes: 10 additions & 0 deletions Compiler/NFFrontEnd/NFType.mo
Expand Up @@ -283,6 +283,16 @@ public
end match;
end isSquareMatrix;

function isEmptyArray
input Type ty;
output Boolean isEmpty;
algorithm
isEmpty := match ty
case ARRAY() then List.exist(ty.dimensions, Dimension.isZero);
else false;
end match;
end isEmptyArray;

function isEnumeration
input Type ty;
output Boolean isEnum;
Expand Down
1 change: 1 addition & 0 deletions Compiler/boot/LoadCompilerSources.mos
Expand Up @@ -327,6 +327,7 @@ if true then /* Suppress output */
"../NFFrontEnd/NFRestriction.mo",
"../NFFrontEnd/NFScalarize.mo",
"../NFFrontEnd/NFSimplifyExp.mo",
"../NFFrontEnd/NFSimplifyModel.mo",
"../NFFrontEnd/NFSections.mo",
"../NFFrontEnd/NFStatement.mo",
"../NFFrontEnd/NFSubscript.mo",
Expand Down

0 comments on commit fb58909

Please sign in to comment.