Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust inout to be implemented with a single argument #16180

Merged
merged 63 commits into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
88a2c19
Adjust inout to be implemented with a single argument
mppf Jul 31, 2020
4300acf
Accept behavior change for deinit in fn body
mppf Jul 31, 2020
3340f44
Start at fixing #16185
mppf Jul 31, 2020
522400d
Attempt to fix issue 16185
mppf Aug 3, 2020
6dbe7f5
Add a test of A.domain and copying behavior
mppf Aug 5, 2020
a53bd96
Change .good for inout being one argument
mppf Aug 6, 2020
604fcb7
Remove chpl__unalias and most chpl__unref. Replace with chpl__initCopy.
mppf Aug 6, 2020
76afaec
Fix syncsingle primer
mppf Aug 7, 2020
6cec8b8
Fix bugs
mppf Aug 7, 2020
c49afde
Fix bug in isTemporaryFromNoCopyReturn
mppf Aug 7, 2020
6cd205d
Improve infinite loop avoidance
mppf Aug 7, 2020
217af6f
Resolve problem with parallel/taskPar/sungeun/private
mppf Aug 20, 2020
e26dbc9
Fix problems with resolving initCopy(ir) when not needed
mppf Aug 20, 2020
4956fc6
Don't use value type for 'in' arg in chpl__coerceMove
mppf Aug 20, 2020
247305b
Just use --memLeaks instead of old workarounds for these tests
mppf Aug 21, 2020
294ee90
Fix problems with returning slices
mppf Aug 20, 2020
9b0e795
Fix canCoerceToCopyType to ignore references
mppf Aug 21, 2020
f5e1b50
Attempt to resolve issue #16275
mppf Aug 21, 2020
4d991fd
Fix rebase issue
mppf Aug 21, 2020
83b6910
Remove trailing spaces
mppf Aug 21, 2020
a24e8bb
Fix more rebase errors
mppf Aug 21, 2020
c7de3f7
Address the domain parts of issue #16275
mppf Aug 21, 2020
d64ef2b
Print formal argument AST ids when in developer mode in explainer
mppf Aug 24, 2020
9229f5d
Use value types in checkResolveFormalsWhereClauses
mppf Aug 24, 2020
96ae1b7
Improve --print-module-resolution output
mppf Aug 24, 2020
67987c0
Workaround for order of resolution issue with hello --no-local
mppf Aug 24, 2020
e854637
Adjust alias output
mppf Aug 26, 2020
805446f
Fix const checking for inout arguments
mppf Aug 26, 2020
3d7f339
Accept difference in warning output for 2 scan tests
mppf Aug 26, 2020
c2d3aa4
Adjust for minor differences in lifetime checker tests
mppf Aug 26, 2020
69f72f6
Adjust override-intents.good for just 1 inout argument
mppf Aug 26, 2020
5423b41
Fix problem with creating array of owned from forall expr
mppf Aug 26, 2020
fc803e4
Update tmacd-promotion
mppf Aug 26, 2020
1c96ffa
Add test for 16301 and adjust test of const checking domain task intent
mppf Aug 26, 2020
0fab450
Make int/uint <<= and >>= operators use integral shift amount
mppf Aug 26, 2020
293d6d9
Have _check_tuple_var_decl accept arguments with const ref intent
mppf Aug 31, 2020
25d0b02
Revert "Use value types in checkResolveFormalsWhereClauses"
mppf Aug 31, 2020
35ac623
Add comments about TODOs related to ref types
mppf Aug 31, 2020
897c58f
Work around issue with `const` sync arguments
mppf Aug 31, 2020
0252bf3
Un-future / Un-no-test tests as #16290 is resolved
mppf Aug 31, 2020
51f8072
Move check for coercion to copy type later in canCoerce
mppf Aug 31, 2020
7b841aa
Compute copy tuple including un-viewing arrays
mppf Aug 31, 2020
e5e536c
Adjust tuple autoCopy
mppf Aug 31, 2020
12404f2
Add isAliasingArrayType/isAliasingArrayImplType
mppf Sep 2, 2020
63cdca2
Change ownsArrInstance in rank change/reindex to param
mppf Sep 2, 2020
beaa34b
Add new alias test of reindex/rank change value arrays
mppf Sep 2, 2020
cc0cf4f
Remove old dead code in postFold
mppf Sep 2, 2020
ef93a43
Set aliasing array flag for benefit of no-alias analysis
mppf Sep 2, 2020
d609c87
Storing reindex domain into var is still a reindex domain
mppf Sep 2, 2020
7a36405
Domain of view array is still view
mppf Sep 2, 2020
f0476e7
Adjust print-module-resolution test for more detailed output
mppf Sep 2, 2020
49ba12c
Use instantiation point from iterator when resolving auto-copy
mppf Sep 2, 2020
c8e4062
Do not initCopy tuple elements containing references
mppf Sep 3, 2020
dd9f0c5
Revert "Accept difference in warning output for 2 scan tests"
mppf Sep 3, 2020
16e1433
Fix bugs in uts tests
mppf Sep 3, 2020
08c52ee
Workaround issue #16233 / #15973
mppf Sep 3, 2020
67fb6e4
Un-future some tests and adjust .bad files
mppf Sep 3, 2020
198dfd6
Add test for issue #16185
mppf Sep 3, 2020
20f06e7
Add test from issue #16195
mppf Sep 3, 2020
619d27b
Add variant of issue #16007 using in intent
mppf Sep 3, 2020
32d4bfd
Remove outdated comments
mppf Sep 3, 2020
0d30c64
Respond to review feedback
mppf Sep 8, 2020
1b403db
Add test of domains and if-exprs
mppf Sep 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/AST/primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,8 @@ initPrimitive() {
prim_def(PRIM_TO_NILABLE_CLASS, "to nilable class", returnInfoToNilable, false, false);
prim_def(PRIM_TO_NON_NILABLE_CLASS, "to non nilable class", returnInfoToNonNilable, false, false);

prim_def(PRIM_SET_ALIASING_ARRAY_ON_TYPE, "set aliasing array on type", returnInfoVoid, false, false);

prim_def(PRIM_NEEDS_AUTO_DESTROY, "needs auto destroy", returnInfoBool, false, false);

// if the argument is a value, mark it with "no auto destroy"
Expand Down
11 changes: 9 additions & 2 deletions compiler/AST/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2137,10 +2137,17 @@ const char* toString(ArgSymbol* arg) {
case INTENT_TYPE: intent = "type "; break;
}

const char* retval = "";
if (arg->getValType() == dtAny || arg->getValType() == dtUnknown)
return astr(intent, arg->name);
retval = astr(intent, arg->name);
else
return astr(intent, arg->name, ": ", toString(arg->getValType()));
retval = astr(intent, arg->name, ": ", toString(arg->getValType()));

if (developer == true) {
retval = astr(retval, " [", istr(arg->id), "]");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for adding this


return retval;
}

const char* toString(VarSymbol* var) {
Expand Down
18 changes: 18 additions & 0 deletions compiler/AST/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,24 @@ bool isDistImplType(Type* type)
return isDerivedType(type, FLAG_BASE_DIST);
}

bool isAliasingArrayImplType(Type* t) {
return t->symbol->hasFlag(FLAG_ALIASING_ARRAY);
}

bool isAliasingArrayType(Type* t) {
if (t->symbol->hasFlag(FLAG_ARRAY)) {
AggregateType* at = toAggregateType(t);
INT_ASSERT(at);

Symbol* instanceField = at->getField("_instance", false);
if (instanceField) {
return isAliasingArrayImplType(instanceField->type);
}
}

return false;
}

static bool isDerivedType(Type* type, Flag flag)
{
AggregateType* at = NULL;
Expand Down
7 changes: 1 addition & 6 deletions compiler/include/flags_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ symbolFlag( FLAG_FIRST_CLASS_FUNCTION_INVOCATION, npr, "first class function inv
symbolFlag( FLAG_FN_RETARG, npr, "fn returns via _retArg", ncm )
symbolFlag( FLAG_FOLLOWER_INDEX, npr, "follower index", "a variable representing a follower loop index" )
symbolFlag( FLAG_FORMAL_TEMP, npr, "formal temp", "a formal temp requiring write-back for an out or inout argument" )
symbolFlag( FLAG_FORMAL_TEMP_INOUT, npr, "formal temp inout", "a formal temp to back an inout argument" )
symbolFlag( FLAG_FORMAL_TEMP_OUT, npr, "formal temp out", "a formal temp to back an out argument" )
symbolFlag( FLAG_FORWARDING_FN , npr, "forwarding function" , ncm )
symbolFlag( FLAG_FUNCTION_CLASS , npr, "function class" , "first-class function class representation" )
Expand All @@ -167,10 +166,6 @@ symbolFlag( FLAG_GLOBAL_VAR_BUILTIN, ypr, "global var builtin", "is accessible t
symbolFlag( FLAG_HAS_POSTINIT , ypr, "has postinit" , "type that has a postinit method" )
symbolFlag( FLAG_HAS_RUNTIME_TYPE , ypr, "has runtime type" , "type that has an associated runtime type" )

// marks a hidden formal that appears after an inout argument.
// the hidden formal covers the "out" part of the "inout".
symbolFlag( FLAG_HIDDEN_FORMAL_INOUT , npr, "hidden formal for inout" , "a separate formal to implement the copy-back part of an inout argument" )

symbolFlag( FLAG_IGNORE_RUNTIME_TYPE , ypr, "ignore runtime type" , "use the static type only in the return value" )
symbolFlag( FLAG_IGNORE_IN_GLOBAL_ANALYSIS , ypr, "ignore in global analysis" , "ignore this function in global use-before-def analysis" )
symbolFlag( FLAG_RVV, npr, "RVV", "variable is the return value variable" )
Expand Down Expand Up @@ -275,6 +270,7 @@ symbolFlag( FLAG_NO_CAPTURE_FOR_TASKING , npr, "no capture for tasking", "does n
symbolFlag( FLAG_NO_CODEGEN , ypr, "no codegen" , "do not generate e.g. C code defining this symbol" )
symbolFlag( FLAG_NO_COPY , ypr, "no copy" , "do not apply chpl__initCopy to initialization of a variable" )
symbolFlag( FLAG_NO_COPY_RETURN, ypr, "no copy return", ncm)
symbolFlag( FLAG_NO_COPY_RETURNS_OWNED, ypr, "no copy returns owned", ncm)
symbolFlag( FLAG_NO_DEFAULT_FUNCTIONS , ypr, "no default functions" , ncm )
symbolFlag( FLAG_NO_DOC, ypr, "no doc", "do not generate chpldoc documentation for this symbol" )
symbolFlag( FLAG_NO_IMPLICIT_COPY , ypr, "no implicit copy" , "function does not require autoCopy/autoDestroy" )
Expand Down Expand Up @@ -450,7 +446,6 @@ symbolFlag( FLAG_TYPE_CUSTOM_ASSIGN , npr, "type uses custom =" , "type has user

symbolFlag( FLAG_TYPE_FORMAL_FOR_OUT , npr, "type formal for out" , "stores the runtime type for an untyped out argument" )
symbolFlag( FLAG_TYPE_VARIABLE , npr, "type variable" , "contains a type instead of a value" )
symbolFlag( FLAG_UNALIAS_FN, ypr, "unalias fn" , "function to copy array slices when assigning to a user variable")
symbolFlag( FLAG_UNCHECKED_THROWS, ypr, "unchecked throws" , "function throws but handling the errors is not required even in strict mode")
symbolFlag( FLAG_UNREF_FN, ypr, "unref fn" , "function to remove reference fields from tuples or copy array slices when returning")
symbolFlag( FLAG_UNSAFE, ypr, "unsafe" , "unsafe (disable lifetime and nilability checking)")
Expand Down
2 changes: 2 additions & 0 deletions compiler/include/primitive_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@
PRIMITIVE_R(PRIM_TO_NILABLE_CLASS)
PRIMITIVE_R(PRIM_TO_NON_NILABLE_CLASS)

PRIMITIVE_R(PRIM_SET_ALIASING_ARRAY_ON_TYPE)

PRIMITIVE_G(PRIM_INVARIANT_START)
PRIMITIVE_G(PRIM_NO_ALIAS_SET)
PRIMITIVE_G(PRIM_COPIES_NO_ALIAS_SET)
Expand Down
18 changes: 16 additions & 2 deletions compiler/include/resolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,14 @@ FnSymbol* getAutoCopyForType(Type* type); // requires hasAutoCopyForType()==tr
void getAutoCopyTypeKeys(Vec<Type*>& keys);
FnSymbol* getAutoCopy(Type* t); // returns NULL if there are none
FnSymbol* getAutoDestroy(Type* t); // "
FnSymbol* getUnalias(Type* t);

FnSymbol* getInitCopyDuringResolution(Type* t);

// Some types should change to another type when assigned into a variable.
// This function returns that type.
// Examples: array view -> array; sync int -> int; iterator -> array
Type* getCopyTypeDuringResolution(Type* t);

FnSymbol* getCoerceMoveFromCoerceCopy(FnSymbol* coerceCopyFn);
const char* getErroneousCopyError(FnSymbol* fn);
void markCopyErroneous(FnSymbol* fn, const char* err);
Expand Down Expand Up @@ -312,7 +319,14 @@ Type* getInstantiationType(Type* actualType, Symbol* actualSym,
Type* formalType, Symbol* formalSym,
Expr* ctx,
bool allowCoercion=true,
bool implicitBang=false);
bool implicitBang=false,
bool inOrOtherValue=false);

// in/out/inout but excluding formals to chpl__coerceMove etc
bool inOrOutFormalNeedingCopyType(ArgSymbol* formal);

bool isCallExprTemporary(Symbol* fromSym);
bool isTemporaryFromNoCopyReturn(Symbol* fromSym);

void resolveIfExprType(CondStmt* stmt);

Expand Down
3 changes: 3 additions & 0 deletions compiler/include/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ bool isRecordWrappedType(const Type* t);
bool isDomImplType(Type* t);
bool isArrayImplType(Type* t);
bool isDistImplType(Type* t);
bool isAliasingArrayImplType(Type* t);
bool isAliasingArrayType(Type* t);

bool isManagedPtrType(const Type* t);
Type* getManagedPtrBorrowType(const Type* t);
AggregateType* getManagedPtrManagerType(Type* t);
Expand Down
11 changes: 1 addition & 10 deletions compiler/optimizations/noAliasSets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,7 @@ void addNoAliasSetForFormal(ArgSymbol* arg,

static
bool isNonAliasingArrayImplType(Type* t) {
// Array views are marked with this flag because they
// can alias other arrays.
if (t->symbol->hasFlag(FLAG_ALIASING_ARRAY))
return false;

// Non-array view array classes
if (isArrayImplType(t))
return true;

return false;
return isArrayImplType(t) && !isAliasingArrayImplType(t);
}

static
Expand Down
50 changes: 1 addition & 49 deletions compiler/passes/normalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ static void makeExportWrapper(FnSymbol* fn);

static void fixupArrayFormals(FnSymbol* fn);

static void fixupInoutFormals(FnSymbol* fn);

static bool includesParameterizedPrimitive(FnSymbol* fn);
static void replaceFunctionWithInstantiationsOfPrimitive(FnSymbol* fn);
static void fixupQueryFormals(FnSymbol* fn);
Expand Down Expand Up @@ -171,8 +169,6 @@ void normalize() {
updateInitMethod(fn);
}
}

fixupInoutFormals(fn);
}

normalizeBase(theProgram, true);
Expand Down Expand Up @@ -3014,8 +3010,7 @@ static void updateVariableAutoDestroy(DefExpr* defExpr) {
var->hasFlag(FLAG_PARAM) == false && // Note 1.
var->hasFlag(FLAG_REF_VAR) == false &&

fn->_this != var && // Note 2.
fn->hasFlag(FLAG_INIT_COPY_FN) == false) { // Note 3.
fn->_this != var) { // Note 2.

// Note that if the DefExpr is at module scope, the auto-destroy
// for it will end up in the module deinit function.
Expand All @@ -3031,19 +3026,6 @@ static void updateVariableAutoDestroy(DefExpr* defExpr) {
// Note 2: "this" should be passed by reference. Then, no constructor call
// is made, and therefore no autodestroy call is needed.

// Note 3: If a record arg to an init copy function is passed by value,
// infinite recursion would ensue. This is an unreachable case (assuming that
// magic conversions from R -> ref R are removed and all existing
// implementations of chpl__initCopy are rewritten using "ref" or "const ref"
// intent on the record argument).


// Note 4: These two cases should be regularized. Either the copy constructor
// should *always* be called (and the corresponding destructor always called),
// or we should ensure that the destructor is called only if a constructor is
// called on the same variable. The latter case is an optimization, so the
// simplest implementation calls the copy-constructor in both cases.

/************************************* | **************************************
* *
* *
Expand Down Expand Up @@ -3555,36 +3537,6 @@ static void fixupArrayElementExpr(FnSymbol* fn,
}
}

/************************************* | **************************************
* *
* Add a second formal for each inout formal so that later parts of *
* compilation can handle the `in` and `out` parts separately. *
* *
************************************** | *************************************/
static void fixupInoutFormals(FnSymbol* fn) {
for_formals(formal, fn) {
if (formal->intent == INTENT_INOUT) {
if (fn->hasFlag(FLAG_EXTERN)) {
formal->originalIntent = INTENT_REF;
formal->intent = INTENT_REF;
} else if (formal->variableExpr != NULL) {
USR_FATAL_CONT(formal, "inout varargs not currently supported");
formal->originalIntent = INTENT_REF;
formal->intent = INTENT_REF;
} else {
// Add a hidden out formal after the inout one.
ArgSymbol* outFormal = formal->copy();
outFormal->name = astr(outFormal->name, "_out");
outFormal->originalIntent = INTENT_OUT;
outFormal->intent = INTENT_OUT;
outFormal->addFlag(FLAG_HIDDEN_FORMAL_INOUT);
outFormal->defaultExpr = new BlockStmt(new SymExpr(formal));
DefExpr* def = new DefExpr(outFormal);
formal->defPoint->insertAfter(def);
}
}
}
}

/************************************* | **************************************
* *
Expand Down
3 changes: 2 additions & 1 deletion compiler/passes/splitInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,8 @@ static bool canCopyElideVar(Symbol* rhs) {
static bool canCopyElideCall(CallExpr* call, Symbol* lhs, Symbol* rhs) {
return canCopyElideVar(rhs) &&
rhs->getValType() == lhs->getValType() &&
rhs->defPoint->parentSymbol == call->parentSymbol;
rhs->defPoint->parentSymbol == call->parentSymbol &&
!(isCallExprTemporary(rhs) && isTemporaryFromNoCopyReturn(rhs));
}

// returns true if there was an unconditional return
Expand Down
16 changes: 6 additions & 10 deletions compiler/resolution/AutoDestroyScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,14 @@ void AutoDestroyScope::addFormalTemps() {
if (fn->hasFlag(FLAG_EXTERN))
return;

bool anyOutInout = false;
bool anyOut = false;
for_formals(formal, fn) {
if (formal->intent == INTENT_OUT ||
formal->originalIntent == INTENT_OUT ||
formal->intent == INTENT_INOUT ||
formal->originalIntent == INTENT_INOUT) {
anyOutInout = true;
formal->originalIntent == INTENT_OUT) {
anyOut = true;
}
}
if (anyOutInout) {
if (anyOut) {
// Go through the function epilogue looking for
// write-backs to args from FORMAL_TEMP variables
LabelSymbol* epilogue = fn->getEpilogueLabel();
Expand All @@ -118,8 +116,7 @@ void AutoDestroyScope::addFormalTemps() {
next = cur->next;
if (VarSymbol* var = findFormalTempAssignBack(cur)) {
CallExpr* call = toCallExpr(cur);
INT_ASSERT(var->hasFlag(FLAG_FORMAL_TEMP_INOUT) ||
var->hasFlag(FLAG_FORMAL_TEMP_OUT));
INT_ASSERT(var->hasFlag(FLAG_FORMAL_TEMP_OUT));
INT_ASSERT(call);
mFormalTempActions.push_back(call);
call->remove(); // will be added back in just before destroying
Expand Down Expand Up @@ -437,8 +434,7 @@ void AutoDestroyScope::variablesDestroy(Expr* refStmt,
if (var != NULL && var != excludeVar && ignored.count(var) == 0) {
if (startingScope->isVariableInitialized(var)) {
bool outIntentFormalReturn = forErrorReturn == false &&
(var->hasFlag(FLAG_FORMAL_TEMP_OUT) ||
var->hasFlag(FLAG_FORMAL_TEMP_INOUT));
var->hasFlag(FLAG_FORMAL_TEMP_OUT);
// No deinit for out formal returns - deinited at call site
if (outIntentFormalReturn == false)
deinitialize(insertBeforeStmt, NULL, var);
Expand Down
Loading