本文整理汇总了C++中ApplySite类的典型用法代码示例。如果您正苦于以下问题:C++ ApplySite类的具体用法?C++ ApplySite怎么用?C++ ApplySite使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ApplySite类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getWitnessMethodSubstitutions
static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
ArrayRef<Substitution> Subs,
SmallVectorImpl<Substitution> &NewSubs) {
auto &Module = AI.getModule();
auto CalleeCanType = F->getLoweredFunctionType();
ProtocolDecl *proto = nullptr;
if (CalleeCanType->getRepresentation() ==
SILFunctionTypeRepresentation::WitnessMethod) {
proto = CalleeCanType->getDefaultWitnessMethodProtocol(
*Module.getSwiftModule());
}
ArrayRef<Substitution> origSubs = AI.getSubstitutions();
if (proto != nullptr) {
// If the callee is a default witness method thunk, preserve substitutions
// from the call site.
NewSubs.append(origSubs.begin(), origSubs.end());
return;
}
// If the callee is a concrete witness method thunk, apply substitutions
// from the conformance, and drop any substitutions derived from the Self
// type.
NewSubs.append(Subs.begin(), Subs.end());
if (auto generics = AI.getOrigCalleeType()->getGenericSignature()) {
for (auto genericParam : generics->getAllDependentTypes()) {
auto origSub = origSubs.front();
origSubs = origSubs.slice(1);
// If the callee is a concrete witness method thunk, we ignore
// generic parameters derived from 'self', the generic parameter at
// depth 0, index 0.
auto type = genericParam->getCanonicalType();
while (auto memberType = dyn_cast<DependentMemberType>(type)) {
type = memberType.getBase();
}
auto paramType = cast<GenericTypeParamType>(type);
if (paramType->getDepth() == 0) {
// There shouldn't be any other parameters at this depth.
assert(paramType->getIndex() == 0);
continue;
}
// Okay, remember this substitution.
NewSubs.push_back(origSub);
}
}
assert(origSubs.empty() && "subs not parallel to dependent types");
}
示例2: ApplySite
/// In the cases where we can statically determine the function that
/// we'll call to, replace an apply of a witness_method with an apply
/// of a function_ref, returning the new apply.
ApplySite
swift::tryDevirtualizeWitnessMethod(ApplySite AI, OptRemark::Emitter *ORE) {
if (!canDevirtualizeWitnessMethod(AI))
return ApplySite();
SILFunction *F;
SILWitnessTable *WT;
auto *WMI = cast<WitnessMethodInst>(AI.getCallee());
std::tie(F, WT) =
AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(),
WMI->getMember());
return devirtualizeWitnessMethod(AI, F, WMI->getConformance(), ORE);
}
示例3: FullApplySite
/// In the cases where we can statically determine the function that
/// we'll call to, replace an apply of a witness_method with an apply
/// of a function_ref, returning the new apply.
DevirtualizationResult swift::tryDevirtualizeWitnessMethod(ApplySite AI) {
if (!canDevirtualizeWitnessMethod(AI))
return std::make_pair(nullptr, FullApplySite());
SILFunction *F;
SILWitnessTable *WT;
auto *WMI = cast<WitnessMethodInst>(AI.getCallee());
std::tie(F, WT) =
AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(),
WMI->getMember());
auto Result = devirtualizeWitnessMethod(AI, F, WMI->getConformance());
return std::make_pair(Result.getInstruction(), Result);
}
示例4: findConcreteType
/// Find the concrete type of the existential argument. Wrapper
/// for findInitExistential in Local.h/cpp. In future, this code
/// can move to Local.h/cpp.
static bool findConcreteType(ApplySite AI, int ArgIdx, CanType &ConcreteType) {
bool isCopied = false;
auto Arg = AI.getArgument(ArgIdx);
/// Ignore any unconditional cast instructions. Is it Safe? Do we need to
/// also add UnconditionalCheckedCastAddrInst? TODO.
if (auto *Instance = dyn_cast<UnconditionalCheckedCastInst>(Arg)) {
Arg = Instance->getOperand();
}
/// Return init_existential if the Arg is global_addr.
if (auto *GAI = dyn_cast<GlobalAddrInst>(Arg)) {
SILValue InitExistential =
findInitExistentialFromGlobalAddrAndApply(GAI, AI, ArgIdx);
/// If the Arg is already init_existential, return the concrete type.
if (InitExistential &&
findConcreteTypeFromInitExistential(InitExistential, ConcreteType)) {
return true;
}
}
/// Handle AllocStack instruction separately.
if (auto *Instance = dyn_cast<AllocStackInst>(Arg)) {
if (SILValue Src =
getAddressOfStackInit(Instance, AI.getInstruction(), isCopied)) {
Arg = Src;
}
}
/// If the Arg is already init_existential after getAddressofStackInit
/// call, return the concrete type.
if (findConcreteTypeFromInitExistential(Arg, ConcreteType)) {
return true;
}
/// Call findInitExistential and determine the init_existential.
ArchetypeType *OpenedArchetype = nullptr;
SILValue OpenedArchetypeDef;
auto FAS = FullApplySite::isa(AI.getInstruction());
if (!FAS)
return false;
SILInstruction *InitExistential =
findInitExistential(FAS.getArgumentOperands()[ArgIdx], OpenedArchetype,
OpenedArchetypeDef, isCopied);
if (!InitExistential) {
LLVM_DEBUG(llvm::dbgs() << "ExistentialSpecializer Pass: Bail! Due to "
"findInitExistential\n";);
示例5: assert
ApplySite SILPerformanceInliner::specializeGeneric(
ApplySite Apply, llvm::SmallVectorImpl<ApplySite> &NewApplies) {
assert(NewApplies.empty() && "Expected out parameter for new applies!");
if (!Apply.hasSubstitutions())
return ApplySite();
auto *Callee = Apply.getCalleeFunction();
if (!Callee || Callee->isExternalDeclaration())
return ApplySite();
auto Filter = [](SILInstruction *I) -> bool {
return ApplySite::isa(I) != ApplySite();
};
CloneCollector Collector(Filter);
SILFunction *SpecializedFunction;
auto Specialized = trySpecializeApplyOfGeneric(Apply,
SpecializedFunction,
Collector);
if (!Specialized)
return ApplySite();
// Track the new applies from the specialization.
for (auto NewCallSite : Collector.getInstructionPairs())
NewApplies.push_back(ApplySite(NewCallSite.first));
auto FullApply = FullApplySite::isa(Apply.getInstruction());
if (!FullApply) {
assert(!FullApplySite::isa(Specialized.getInstruction()) &&
"Unexpected full apply generated!");
// Replace the old apply with the new and delete the old.
replaceDeadApply(Apply, Specialized.getInstruction());
return ApplySite(Specialized);
}
// Replace the old apply with the new and delete the old.
replaceDeadApply(Apply, Specialized.getInstruction());
return Specialized;
}
示例6: devirtualizeWitnessMethod
/// Generate a new apply of a function_ref to replace an apply of a
/// witness_method when we've determined the actual function we'll end
/// up calling.
static ApplySite
devirtualizeWitnessMethod(ApplySite AI, SILFunction *F,
ProtocolConformanceRef C, OptRemark::Emitter *ORE) {
// We know the witness thunk and the corresponding set of substitutions
// required to invoke the protocol method at this point.
auto &Module = AI.getModule();
// Collect all the required substitutions.
//
// The complete set of substitutions may be different, e.g. because the found
// witness thunk F may have been created by a specialization pass and have
// additional generic parameters.
auto SubMap = getWitnessMethodSubstitutions(Module, AI, F, C);
// Figure out the exact bound type of the function to be called by
// applying all substitutions.
auto CalleeCanType = F->getLoweredFunctionType();
auto SubstCalleeCanType = CalleeCanType->substGenericArgs(Module, SubMap);
// Collect arguments from the apply instruction.
auto Arguments = SmallVector<SILValue, 4>();
// Iterate over the non self arguments and add them to the
// new argument list, upcasting when required.
SILBuilderWithScope B(AI.getInstruction());
SILFunctionConventions substConv(SubstCalleeCanType, Module);
unsigned substArgIdx = AI.getCalleeArgIndexOfFirstAppliedArg();
for (auto arg : AI.getArguments()) {
auto paramType = substConv.getSILArgumentType(substArgIdx++);
if (arg->getType() != paramType)
arg = castValueToABICompatibleType(&B, AI.getLoc(), arg,
arg->getType(), paramType);
Arguments.push_back(arg);
}
assert(substArgIdx == substConv.getNumSILArguments());
// Replace old apply instruction by a new apply instruction that invokes
// the witness thunk.
SILBuilderWithScope Builder(AI.getInstruction());
SILLocation Loc = AI.getLoc();
FunctionRefInst *FRI = Builder.createFunctionRef(Loc, F);
ApplySite SAI = replaceApplySite(Builder, Loc, AI, FRI, SubMap, Arguments,
substConv);
if (ORE)
ORE->emit([&]() {
using namespace OptRemark;
return RemarkPassed("WitnessMethodDevirtualized", *AI.getInstruction())
<< "Devirtualized call to " << NV("Method", F);
});
NumWitnessDevirt++;
return SAI;
}
示例7: checkForViolationAtApply
/// Recursively check for conflicts with in-progress accesses at the given
/// apply.
///
/// Any captured variable accessed by a noescape closure is considered to be
/// accessed at the point that the closure is fully applied. This includes
/// variables captured by address by the noescape closure being applied or by
/// any other noescape closure that is itself passed as an argument to that
/// closure.
///
/// (1) Use AccessSummaryAnalysis to check each argument for statically
/// enforced accesses nested within the callee.
///
/// (2) If an applied argument is itself a function type, recursively check for
/// violations on the closure being passed as an argument.
///
/// (3) Walk up the chain of partial applies to recursively visit all arguments.
///
/// Note: This handles closures that are called immediately:
/// var i = 7
/// ({ (p: inout Int) in i = 8})(&i) // Overlapping access to 'i'
///
/// Note: This handles chains of partial applies:
/// pa1 = partial_apply f(c) : $(a, b, c)
/// pa2 = partial_apply pa1(b) : $(a, b)
/// apply pa2(a)
static void checkForViolationAtApply(ApplySite Apply, AccessState &State) {
// First, check access to variables immediately captured at this apply site.
checkCaptureAccess(Apply, State);
// Next, recursively check any noescape closures passed as arguments at this
// apply site.
TinyPtrVector<PartialApplyInst *> partialApplies;
for (SILValue Argument : Apply.getArguments()) {
auto FnType = getSILFunctionTypeForValue(Argument);
if (!FnType || !FnType->isNoEscape())
continue;
findClosuresForFunctionValue(Argument, partialApplies);
}
// Continue recursively walking up the chain of applies if necessary.
findClosuresForFunctionValue(Apply.getCallee(), partialApplies);
for (auto *PAI : partialApplies)
checkForViolationAtApply(ApplySite(PAI), State);
}
示例8: getWitnessMethodSubstitutions
static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
ProtocolConformanceRef CRef,
SmallVectorImpl<Substitution> &NewSubs) {
auto &Module = AI.getModule();
auto requirementSig = AI.getOrigCalleeType()->getGenericSignature();
auto witnessThunkSig = F->getLoweredFunctionType()->getGenericSignature();
SubstitutionList origSubs = AI.getSubstitutions();
bool isDefaultWitness =
F->getLoweredFunctionType()->getRepresentation()
== SILFunctionTypeRepresentation::WitnessMethod &&
F->getLoweredFunctionType()->getDefaultWitnessMethodProtocol(
*Module.getSwiftModule())
== CRef.getRequirement();
getWitnessMethodSubstitutions(Module, CRef, requirementSig, witnessThunkSig,
origSubs, isDefaultWitness, NewSubs);
}
示例9: canPassOrConvertAllArguments
/// Check if we can pass/convert all arguments of the original apply
/// as required by the found devirtualized method.
static bool
canPassOrConvertAllArguments(ApplySite AI,
CanSILFunctionType SubstCalleeCanType) {
for (unsigned ArgN = 0, ArgE = AI.getNumArguments(); ArgN != ArgE; ++ArgN) {
SILValue A = AI.getArgument(ArgN);
auto ParamType = SubstCalleeCanType->getSILArgumentType(
SubstCalleeCanType->getNumSILArguments() - AI.getNumArguments() + ArgN);
// Check if we can cast the provided argument into the required
// parameter type.
auto FromTy = A->getType();
auto ToTy = ParamType;
// If types are the same, no conversion will be required.
if (FromTy == ToTy)
continue;
// Otherwise, it should be possible to upcast the arguments.
if (!isLegalUpcast(FromTy, ToTy))
return false;
}
return true;
}
示例10: checkCaptureAccess
/// For each argument in the range of the callee arguments being applied at the
/// given apply site, use the summary analysis to determine whether the
/// arguments will be accessed in a way that conflicts with any currently in
/// progress accesses. If so, diagnose.
static void checkCaptureAccess(ApplySite Apply, AccessState &State) {
SILFunction *Callee = Apply.getCalleeFunction();
if (!Callee || Callee->empty())
return;
const AccessSummaryAnalysis::FunctionSummary &FS =
State.ASA->getOrCreateSummary(Callee);
for (unsigned ArgumentIndex : range(Apply.getNumArguments())) {
unsigned CalleeIndex =
Apply.getCalleeArgIndexOfFirstAppliedArg() + ArgumentIndex;
const AccessSummaryAnalysis::ArgumentSummary &AS =
FS.getAccessForArgument(CalleeIndex);
const auto &SubAccesses = AS.getSubAccesses();
// Is the capture accessed in the callee?
if (SubAccesses.empty())
continue;
SILValue Argument = Apply.getArgument(ArgumentIndex);
assert(Argument->getType().isAddress());
// A valid AccessedStorage should alway sbe found because Unsafe accesses
// are not tracked by AccessSummaryAnalysis.
const AccessedStorage &Storage = findValidAccessedStorage(Argument);
auto AccessIt = State.Accesses->find(Storage);
// Are there any accesses in progress at the time of the call?
if (AccessIt == State.Accesses->end())
continue;
const AccessInfo &Info = AccessIt->getSecond();
if (auto Conflict = findConflictingArgumentAccess(AS, Storage, Info))
State.ConflictingAccesses.push_back(*Conflict);
}
}
示例11: canDevirtualizeWitnessMethod
static bool canDevirtualizeWitnessMethod(ApplySite AI) {
SILFunction *F;
SILWitnessTable *WT;
auto *WMI = cast<WitnessMethodInst>(AI.getCallee());
std::tie(F, WT) =
AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(),
WMI->getMember());
if (!F)
return false;
if (AI.getFunction()->isSerialized()) {
// function_ref inside fragile function cannot reference a private or
// hidden symbol.
if (!F->hasValidLinkageForFragileRef())
return false;
}
return true;
}
示例12: getWitnessMethodSubstitutions
static SubstitutionMap
getWitnessMethodSubstitutions(SILModule &Module, ApplySite AI, SILFunction *F,
ProtocolConformanceRef CRef) {
auto witnessFnTy = F->getLoweredFunctionType();
assert(witnessFnTy->getRepresentation() ==
SILFunctionTypeRepresentation::WitnessMethod);
auto requirementSig = AI.getOrigCalleeType()->getGenericSignature();
auto witnessThunkSig = witnessFnTy->getGenericSignature();
SubstitutionMap origSubs = AI.getSubstitutionMap();
auto *mod = Module.getSwiftModule();
bool isDefaultWitness =
(witnessFnTy->getDefaultWitnessMethodProtocol()
== CRef.getRequirement());
auto *classWitness = witnessFnTy->getWitnessMethodClass(*mod);
return getWitnessMethodSubstitutions(
mod, CRef, requirementSig, witnessThunkSig,
origSubs, isDefaultWitness, classWitness);
}
示例13: FullApplySite
/// In the cases where we can statically determine the function that
/// we'll call to, replace an apply of a witness_method with an apply
/// of a function_ref, returning the new apply.
DevirtualizationResult swift::tryDevirtualizeWitnessMethod(ApplySite AI) {
SILFunction *F;
SILWitnessTable *WT;
auto *WMI = cast<WitnessMethodInst>(AI.getCallee());
std::tie(F, WT) =
AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(),
WMI->getMember());
if (!F)
return std::make_pair(nullptr, FullApplySite());
if (AI.getFunction()->isFragile()) {
// function_ref inside fragile function cannot reference a private or
// hidden symbol.
if (!F->hasValidLinkageForFragileRef())
return std::make_pair(nullptr, FullApplySite());
}
auto Result = devirtualizeWitnessMethod(AI, F, WMI->getConformance());
return std::make_pair(Result.getInstruction(), Result);
}
示例14: visitApplyAccesses
/// Helper for visitApplyAccesses that visits address-type call arguments,
/// including arguments to @noescape functions that are passed as closures to
/// the current call.
static void visitApplyAccesses(ApplySite apply,
llvm::function_ref<void(Operand *)> visitor) {
for (Operand &oper : apply.getArgumentOperands()) {
// Consider any address-type operand an access. Whether it is read or modify
// depends on the argument convention.
if (oper.get()->getType().isAddress()) {
visitor(&oper);
continue;
}
auto fnType = oper.get()->getType().getAs<SILFunctionType>();
if (!fnType || !fnType->isNoEscape())
continue;
// When @noescape function closures are passed as arguments, their
// arguments are considered accessed at the call site.
TinyPtrVector<PartialApplyInst *> partialApplies;
findClosuresForFunctionValue(oper.get(), partialApplies);
// Recursively visit @noescape function closure arguments.
for (auto *PAI : partialApplies)
visitApplyAccesses(PAI, visitor);
}
}
示例15: visitApplyAccesses
/// Helper for visitApplyAccesses that visits address-type call arguments,
/// including arguments to @noescape functions that are passed as closures to
/// the current call.
static void visitApplyAccesses(ApplySite apply,
llvm::function_ref<void(Operand *)> visitor) {
for (Operand &oper : apply.getArgumentOperands()) {
// Consider any address-type operand an access. Whether it is read or modify
// depends on the argument convention.
if (oper.get()->getType().isAddress()) {
visitor(&oper);
continue;
}
auto fnType = oper.get()->getType().getAs<SILFunctionType>();
if (!fnType || !fnType->isNoEscape())
continue;
// When @noescape function closures are passed as arguments, their
// arguments are considered accessed at the call site.
FindClosureResult result = findClosureForAppliedArg(oper.get());
if (!result.PAI)
continue;
// Recursively visit @noescape function closure arguments.
visitApplyAccesses(result.PAI, visitor);
}
}