void SideEffectAnalysis::getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS) { assert(ApplyEffects.ParamEffects.size() == 0 && "Not using a new ApplyEffects?"); ApplyEffects.ParamEffects.resize(FAS.getNumArguments()); // Is this a call to a semantics function? ArraySemanticsCall ASC(FAS.getInstruction()); if (ASC && ASC.hasSelf()) { if (getSemanticEffects(ApplyEffects, ASC)) return; } if (SILFunction *SingleCallee = FAS.getCalleeFunction()) { // Does the function have any @effects? if (getDefinedEffects(ApplyEffects, SingleCallee)) return; } auto Callees = BCA->getCalleeList(FAS); if (!Callees.allCalleesVisible() || // @callee_owned function calls implicitly release the context, which // may call deinits of boxed values. // TODO: be less conservative about what destructors might be called. FAS.getOrigCalleeType()->isCalleeConsumed()) { ApplyEffects.setWorstEffects(); return; } // We can see all the callees. So we just merge the effects from all of // them. for (auto *Callee : Callees) { const FunctionEffects &CalleeFE = getEffects(Callee); ApplyEffects.mergeFrom(CalleeFE); } }
void GenericFunctionEffectAnalysis<FunctionEffects>::analyzeCall( FunctionInfo *functionInfo, FullApplySite fullApply, FunctionOrder &bottomUpOrder, int recursionDepth) { FunctionEffects applyEffects; if (applyEffects.summarizeCall(fullApply)) { functionInfo->functionEffects.mergeFromApply(applyEffects, fullApply); return; } if (recursionDepth >= MaxRecursionDepth) { functionInfo->functionEffects.setWorstEffects(); return; } CalleeList callees = BCA->getCalleeList(fullApply); if (!callees.allCalleesVisible() || // @callee_owned function calls implicitly release the context, which // may call deinits of boxed values. // TODO: be less conservative about what destructors might be called. fullApply.getOrigCalleeType()->isCalleeConsumed()) { functionInfo->functionEffects.setWorstEffects(); return; } // Derive the effects of the apply from the known callees. // Defer merging callee effects until the callee is scheduled for (SILFunction *callee : callees) { FunctionInfo *calleeInfo = getFunctionInfo(callee); calleeInfo->addCaller(functionInfo, fullApply); if (!calleeInfo->isVisited()) { // Recursively visit the called function. analyzeFunction(calleeInfo, bottomUpOrder, recursionDepth + 1); bottomUpOrder.tryToSchedule(calleeInfo); } } }
void SideEffectAnalysis::getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS) { assert(ApplyEffects.ParamEffects.size() == 0 && "Not using a new ApplyEffects?"); ApplyEffects.ParamEffects.resize(FAS.getNumArguments()); // Is this a call to a semantics function? ArraySemanticsCall ASC(FAS.getInstruction()); if (ASC && ASC.hasSelf()) { if (getSemanticEffects(ApplyEffects, ASC)) return; } if (SILFunction *SingleCallee = FAS.getCalleeFunction()) { // Does the function have any @effects? if (getDefinedEffects(ApplyEffects, SingleCallee)) return; } auto Callees = BCA->getCalleeList(FAS); if (!Callees.allCalleesVisible()) { ApplyEffects.setWorstEffects(); return; } // We can see all the callees. So we just merge the effects from all of // them. for (auto *Callee : Callees) { const FunctionEffects &CalleeFE = getEffects(Callee); ApplyEffects.mergeFrom(CalleeFE); } }
void GenericFunctionEffectAnalysis<FunctionEffects>::getCalleeEffects( FunctionEffects &calleeEffects, FullApplySite fullApply) { if (calleeEffects.summarizeCall(fullApply)) return; auto callees = BCA->getCalleeList(fullApply); if (!callees.allCalleesVisible() || // @callee_owned function calls implicitly release the context, which // may call deinits of boxed values. // TODO: be less conservative about what destructors might be called. fullApply.getOrigCalleeType()->isCalleeConsumed()) { calleeEffects.setWorstEffects(); return; } // We can see all the callees, so merge the effects from all of them. for (auto *callee : callees) calleeEffects.mergeFrom(getEffects(callee)); }