bool FunctionAccessedStorage::summarizeFunction(SILFunction *F) { assert(accessResult.isEmpty() && "expected uninitialized results."); if (F->isDefinition()) return false; // If the function definition is unavailable, set unidentifiedAccess to a // conservative value, since analyzeInstruction will never be called. // // If FunctionSideEffects can be summarized, use that information. FunctionSideEffects functionSideEffects; if (!functionSideEffects.summarizeFunction(F)) { setWorstEffects(); // May as well consider this a successful summary since there are no // instructions to visit anyway. return true; } bool mayRead = functionSideEffects.getGlobalEffects().mayRead(); bool mayWrite = functionSideEffects.getGlobalEffects().mayWrite(); for (auto ¶mEffects : functionSideEffects.getParameterEffects()) { mayRead |= paramEffects.mayRead(); mayWrite |= paramEffects.mayWrite(); } if (mayWrite) accessResult.setUnidentifiedAccess(SILAccessKind::Modify); else if (mayRead) accessResult.setUnidentifiedAccess(SILAccessKind::Read); // If function side effects is "readnone" then this result will have an empty // storageAccessSet and unidentifiedAccess == None. return true; }
static bool isSafeReadOnlyApply(SideEffectAnalysis *SEA, ApplyInst *AI) { FunctionSideEffects E; SEA->getCalleeEffects(E, AI); if (E.getGlobalEffects().mayRead()) { // If we have Global effects, // we don't know which memory is read in the callee. // Therefore we bail for safety return false; } auto MB = E.getMemBehavior(RetainObserveKind::ObserveRetains); return (MB <= SILInstruction::MemoryBehavior::MayRead); }
bool swift::isPureCall(FullApplySite AI, SideEffectAnalysis *SEA) { // If a call has only constant arguments and the call is pure, i.e. has // no side effects, then we should always inline it. // This includes arguments which are objects initialized with constant values. FunctionSideEffects ApplyEffects; SEA->getCalleeEffects(ApplyEffects, AI); auto GE = ApplyEffects.getGlobalEffects(); if (GE.mayRead() || GE.mayWrite() || GE.mayRetain() || GE.mayRelease()) return false; // Check if all parameters are constant. auto Args = AI.getArgumentOperands().slice(AI.getNumIndirectSILResults()); for (Operand &Arg : Args) { if (!isConstantArg(&Arg)) { return false; } } return true; }