16398, “e-kayrakli”, “Behavior difference between generic and concrete ‘in’ intents with domain literal actuals”, “2020-09-15T23:29:16Z”
Consider the following code:
proc foo(in d) {
writeln(d);
}
proc bar(in d: domain(1, int, false)) {
writeln(d);
}
var myDom: domain(1);
foo(myDom);
bar(myDom);
foo({1..10});
bar({1..10});
Should we copy
Currently we copy myDom
while calling foo
and `bar:
call_tmp_chpl31 = chpl__buildDomainRuntimeType(&defaultDist_chpl);
_runtime_type_tmp__chpl2 = (&call_tmp_chpl31)->dist;
chpl__convertRuntimeTypeToValue(&_runtime_type_tmp__chpl2, UINT8(false), &ret_tmp_chpl);
myDom_chpl = ret_tmp_chpl;
_formal_tmp_in_r_chpl = chpl__initCopy(&myDom_chpl, UINT8(false));
foo_chpl(&_formal_tmp_in_r_chpl); // we pass the copy here
_formal_type_tmp_chpl = chpl__buildDomainRuntimeType(&defaultDist_chpl);
chpl__coerceCopy(&_formal_type_tmp_chpl, &myDom_chpl, UINT8(false), &ret_tmp_chpl2);
_formal_tmp_in_r_chpl2 = ret_tmp_chpl2;
bar_chpl(&_formal_tmp_in_r_chpl2); // we pass the copy here
However the behavior is different while passing a domain literal:
chpl_build_bounded_range(INT64(1), INT64(10), &ret_tmp_chpl3);
call_tmp_chpl32 = ret_tmp_chpl3;
chpl__buildDomainExpr(call_tmp_chpl32, UINT8(false), &ret_tmp_chpl4);
call_tmp_chpl33 = ret_tmp_chpl4;
foo_chpl(&call_tmp_chpl33); // we pass the domain in this scope
chpl_build_bounded_range(INT64(1), INT64(10), &ret_tmp_chpl5);
call_tmp_chpl34 = ret_tmp_chpl5;
chpl__buildDomainExpr(call_tmp_chpl34, UINT8(false), &ret_tmp_chpl6);
call_tmp_chpl35 = ret_tmp_chpl6;
_formal_type_tmp_chpl2 = chpl__buildDomainRuntimeType(&defaultDist_chpl);
chpl__coerceMove(&_formal_type_tmp_chpl2, &call_tmp_chpl35, UINT8(false), &ret_tmp_chpl7);
_formal_tmp_in_r_chpl3 = ret_tmp_chpl7;
bar_chpl(&_formal_tmp_in_r_chpl3); // we pass the copy here
We may be doing some copy elision, because it is a literal in the calling scope,
so there is no need to create its copy. However, the behavior changes if the
argument is generic vs not.
I am not entirely sure whether this causes a problem on master, but it’ll after
https://github.com/chapel-lang/chapel/pull/16397. Because a domain literal
is constant by definition, and an in
argument isn’t. So if we are supposed to
elide the copy for the domain literal (1) we have to do that for the generic
case, too, (2) adjust the formal’s definedConst
field in the function body.