Skip to content

Commit

Permalink
Minor cleanup and commenting. (#940)
Browse files Browse the repository at this point in the history
- Added comments for record handling template functions.

  - Removed generation of unused record utility function
    `recordCopyFromVars` which was used to assign to 'record'
    in simulation contexts. Assigning to record in simulation
    context is now handled by splitting the assignment (recursively)
    to each element instead.
  • Loading branch information
mahge committed Jun 8, 2020
1 parent 5ae3010 commit 9edc53b
Showing 1 changed file with 73 additions and 34 deletions.
107 changes: 73 additions & 34 deletions OMCompiler/Compiler/Template/CodegenCFunctions.tpl
Expand Up @@ -424,10 +424,9 @@ template recordDeclaration(RecordDeclaration recDecl)
listLength(variables))%>

<%recordConstructorDef(r.name, r.name, r.variables)%>
<%recordCopyFromVarsDef(r.name, r.variables)%>
<%recordModelicaCallConstrctor(r.name, r.variables)%>

<%recordCopyDef(r.name, r.variables)%>
<%recordCopyToVarsDef(r.name, r.variables)%>
>>
case r as RECORD_DECL_ADD_CONSTRCTOR(__) then
<<
Expand All @@ -453,7 +452,27 @@ template recordDeclarationHeader(RecordDeclaration recDecl)
end recordDeclarationHeader;

template recordDeclarationExtraCtor(RecordDeclaration recDecl)
"Generates structs for a record declaration."
"Generates structs for a extra record declaration. An extra
record declration is a constrctor with some of its elements provided
from outside. Modelica puts a lot of freedom on record creation. You can
generaly provide none, some or all elements to create a record without
providing a single constructor. Which means a record with N elements
can have 2^N possible constructions.
e.g.,
record R
Real a=1,b=1,c=1;
end R;
R r1(a=2);
R r2(a=3,c=4);
....

These will be created by additional constructors:
R_1_construct(r1,2);
R_1_3_construct(r2,3,4);
...

Do not worry, these are created once for every use case and ONLY if they
are actually used by something."
::=
match recDecl
case r as RECORD_DECL_ADD_CONSTRCTOR(__) then
Expand All @@ -477,7 +496,11 @@ template recordDeclarationExtraCtor(RecordDeclaration recDecl)
end recordDeclarationExtraCtor;

template recordDeclarationFullHeader(RecordDeclaration recDecl)
"Generates structs for a record declaration."
"Generates structs for a record declaration. This will generate
a default record construtor function (no argumens) and a record copy function.
These generated functions are fully recursive. That means records in records
will be handled properly.
It will also generate (#define) array versions of these functions."
::=
match recDecl
case r as RECORD_DECL_FULL(__) then
Expand Down Expand Up @@ -517,13 +540,16 @@ template recordDeclarationFullHeader(RecordDeclaration recDecl)
void <%cpy_func_name%>(void* v_src, void* v_dst);
#define <%cpy_macro_name%>(src,dst) <%cpy_func_name%>(&src, &dst)

// This function should eventualy replace the default 'modelica' record constructor funcition
// that omc used to generate, i.e., replace functionBodyRecordConstructor template.
// <%rec_name%> <%modelica_ctor_name%>(threadData_t *threadData <%modelica_ctor_inputs%>);

/* This function is used to copy a records members to simvars. Since simvars
have no structure yet we can not directly copy records. Insted we pass the
corresponding simvars to this function and then copy each element one by one.*/
void <%copy_to_vars_name_p%>(void* v_src <%copy_to_vars_inputs%>);
#define <%copy_to_vars_name%>(src,...) <%copy_to_vars_name_p%>(&src, __VA_ARGS__)
// This function is not needed anymore. If you want to know how a record
// is 'assigned to' in simulation context see assignRhsExpToRecordCrefSimContext and
// splitRecordAssignmentToMemberAssignments (simCode). Basically the record is
// split up assignments generated for each memeber individualy.
// void <%copy_to_vars_name_p%>(void* v_src <%copy_to_vars_inputs%>);
// #define <%copy_to_vars_name%>(src,...) <%copy_to_vars_name_p%>(&src, __VA_ARGS__)

typedef base_array_t <%rec_name%>_array;
#define alloc_<%rec_name%>_array(dst,ndims,...) generic_array_create(NULL, dst, <%ctor_func_name%>, ndims, sizeof(<%rec_name%>), __VA_ARGS__)
Expand All @@ -537,7 +563,8 @@ template recordDeclarationFullHeader(RecordDeclaration recDecl)
end recordDeclarationFullHeader;

template recordCopyDef(String rec_name, list<Variable> variables)
"Generates structs for a record declaration."
"Generates code for copying one instance of a record to another
instance of the same record type."
::=
let &varCopies = buffer ""
let &auxFunction = buffer ""
Expand All @@ -553,8 +580,26 @@ template recordCopyDef(String rec_name, list<Variable> variables)
>>
end recordCopyDef;

template recordCopyFromVarsDef(String rec_name, list<Variable> variables)
"Generates structs for a record declaration."
template recordModelicaCallConstrctor(String rec_name, list<Variable> variables)
"Generates code for creating and initializing a record given values for
ALL its memebers. This is basically what we used to generate before. However
that one did not handle arrays and record record memebers properly. This
should replace that function. For now it is commented until I have time to
clean out uses of the other one and replace it with this.

Note that this is defferent from the constructors we have. This is the function
to be used when you do R(...). not for cases where you have

R r1; (uses default constructor, i e., recordDeclarationFullHeader and recordConstructorDef)
R r2(a=2); (uses extra constructor, i e., recordDeclarationExtraCtor and recordConstructorDef)
...

But for cases like these.
a := R() (should use this function)

The difference is this function creates and returns a NEW record instance. The others
accept an instance and initialize it (including any allocations needed by the MEMBERS).
"
::=
let &varCopies = buffer ""
let &auxFunction = buffer ""
Expand All @@ -565,6 +610,8 @@ template recordCopyFromVarsDef(String rec_name, list<Variable> variables)
(", " + varType(var) + " " + src_pref + contextCrefNoPrevExp(var.name, contextFunction, &auxFunction))
)
<<
// This function should eventualy replace the default 'modelica' record constructor funcition
// that omc used to generate, i.e., replace functionBodyRecordConstructor template.
/*
<%rec_name%> omc_<%rec_name%>(threadData_t *threadData <%inputs%>) {
<%rec_name%> dst;
Expand All @@ -576,29 +623,13 @@ template recordCopyFromVarsDef(String rec_name, list<Variable> variables)
}
*/
>>
end recordCopyFromVarsDef;

template recordCopyToVarsDef(String rec_name, list<Variable> variables)
"Generates structs for a record declaration."
::=
let &varCopies = buffer ""
let &auxFunction = buffer ""
let dst_pref = ' *in'
let src_pref = 'src->'
let _ = (variables |> var => recordMemberCopy(var, src_pref, dst_pref, &varCopies, &auxFunction) ;separator="\n")
let inputs = (variables |> var as VARIABLE(__) =>
(", " + varType(var) + " " + dst_pref + contextCrefNoPrevExp(var.name, contextFunction, &auxFunction))
)

<<
void <%rec_name%>_copy_to_vars_p(void* v_src <%inputs%>) {
<%rec_name%>* src = (<%rec_name%>*)(v_src);
<%varCopies%>
}
>>
end recordCopyToVarsDef;
end recordModelicaCallConstrctor;

template recordMemberCopy(Variable var, String src_pref, String dst_pref, Text &varCopies, Text &auxFunction)
"Generates code for copying memembers of a record during a record copy operation.
This function is needed because we need to have a 'localized' operation. Localized as
in references in these copy operations need to be resolved to other mememers of the
record. So we use prefixes (e.g. src->) to generate crefs in these operations."
::=
match var
case var as VARIABLE(__) then
Expand All @@ -622,7 +653,12 @@ case var as VARIABLE(__) then
end recordMemberCopy;

template recordConstructorDef(String ctor_name, String rec_name, list<Variable> variables)
"Generates structs for a record declaration."
"Generates code for constructing a record. This means allocating memory for all
memebers of the record and then initializing them with their default values. Sometimes
we can have modelica derived records (e.g. record A = B(c=exp)), this will be a new
record type whcih needs an exp to be passed to to be initialized correctly. This is
also handled by these function. Check markDerivedRecordOutsideBindings and makeTypeRecordVar
in the OF and NF respectively."
::=
let &varDecls = buffer ""
let &auxFunction = buffer ""
Expand Down Expand Up @@ -752,6 +788,9 @@ template arrayVarAllocInit(ComponentRef var_cref, Type var_type, list<DAE.Dimens
>>

case NONE() then
// If an array variable has unknown dimensions but does not have a default value (declaration binding)
// then the variable is flexible. That means it can actually change its dimensions whenever it is
// assigned to. Ya it is allowed :/
if Expression.hasUnknownDims(var_dims) then
<<
generic_array_create_flexible(&<%var_name%>, <%listLength(var_dims)%>); // <%var_name%> has unknown size and no default value. It is flexible.<%\n%>
Expand Down

0 comments on commit 9edc53b

Please sign in to comment.