本文整理汇总了C++中IRGenFunction::getActiveDominancePoint方法的典型用法代码示例。如果您正苦于以下问题:C++ IRGenFunction::getActiveDominancePoint方法的具体用法?C++ IRGenFunction::getActiveDominancePoint怎么用?C++ IRGenFunction::getActiveDominancePoint使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IRGenFunction
的用法示例。
在下文中一共展示了IRGenFunction::getActiveDominancePoint方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: emitDynamicAlloca
/// Emit a dynamic alloca call to allocate enough memory to hold an object of
/// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
/// false.
DynamicAlloca irgen::emitDynamicAlloca(IRGenFunction &IGF, SILType T,
bool isInEntryBlock) {
llvm::Value *stackRestorePoint = nullptr;
// Save the stack pointer if we are not in the entry block (we could be
// executed more than once).
if (!isInEntryBlock) {
auto *stackSaveFn = llvm::Intrinsic::getDeclaration(
&IGF.IGM.Module, llvm::Intrinsic::ID::stacksave);
stackRestorePoint = IGF.Builder.CreateCall(stackSaveFn, {}, "spsave");
}
// Emit the dynamic alloca.
llvm::Value *size = emitLoadOfSize(IGF, T);
auto *alloca = IGF.Builder.CreateAlloca(IGF.IGM.Int8Ty, size, "alloca");
alloca->setAlignment(16);
assert(!isInEntryBlock ||
IGF.getActiveDominancePoint().isUniversal() &&
"Must be in entry block if we insert dynamic alloca's without "
"stackrestores");
return {alloca, stackRestorePoint};
}
示例2: CanType
void LocalTypeDataCache::
addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments,
llvm::function_ref<AbstractSource()> createSource) {
// Add the source lazily.
Optional<unsigned> sourceIndex;
auto getSourceIndex = [&]() -> unsigned {
if (!sourceIndex) {
AbstractSources.emplace_back(createSource());
sourceIndex = AbstractSources.size() - 1;
}
return *sourceIndex;
};
for (auto &fulfillment : fulfillments) {
CanType type = CanType(fulfillment.first.first);
LocalTypeDataKind localDataKind;
// For now, ignore witness-table fulfillments when they're not for
// archetypes.
if (ProtocolDecl *protocol = fulfillment.first.second) {
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
auto conformsTo = archetype->getConformsTo();
auto it = std::find(conformsTo.begin(), conformsTo.end(), protocol);
if (it == conformsTo.end()) continue;
localDataKind = LocalTypeDataKind::forAbstractProtocolWitnessTable(*it);
} else {
continue;
}
} else {
// Ignore type metadata fulfillments for non-dependent types that
// we can produce very cheaply. We don't want to end up emitting
// the type metadata for Int by chasing through N layers of metadata
// just because that path happens to be in the cache.
if (!type->hasArchetype() &&
isTypeMetadataAccessTrivial(IGF.IGM, type)) {
continue;
}
localDataKind = LocalTypeDataKind::forTypeMetadata();
}
// Find the chain for the key.
auto key = getKey(type, localDataKind);
auto &chain = Map[key];
// Check whether there's already an entry that's at least as good as the
// fulfillment.
Optional<unsigned> fulfillmentCost;
auto getFulfillmentCost = [&]() -> unsigned {
if (!fulfillmentCost)
fulfillmentCost = fulfillment.second.Path.cost();
return *fulfillmentCost;
};
bool isConditional = IGF.isConditionalDominancePoint();
bool foundBetter = false;
for (CacheEntry *cur = chain.Root, *last = nullptr; cur;
last = cur, cur = cur->getNext()) {
// Ensure the entry is acceptable.
if (!IGF.isActiveDominancePointDominatedBy(cur->DefinitionPoint))
continue;
// Ensure that the entry isn't better than the fulfillment.
auto curCost = cur->cost();
if (curCost == 0 || curCost <= getFulfillmentCost()) {
foundBetter = true;
break;
}
// If the entry is defined at the current point, (1) we know there
// won't be a better entry and (2) we should remove it.
if (cur->DefinitionPoint == IGF.getActiveDominancePoint() &&
!isConditional) {
// Splice it out of the chain.
assert(!cur->isConditional());
chain.eraseEntry(last, cur);
break;
}
}
if (foundBetter) continue;
// Okay, make a new entry.
// Register with the conditional dominance scope if necessary.
if (isConditional) {
IGF.registerConditionalLocalTypeDataKey(key);
}
// Allocate the new entry.
auto newEntry = new AbstractCacheEntry(IGF.getActiveDominancePoint(),
isConditional,
getSourceIndex(),
std::move(fulfillment.second.Path));
// Add it to the front of the chain.
chain.push_front(newEntry);
}
}
示例3: while
MetadataResponse
LocalTypeDataCache::tryGet(IRGenFunction &IGF, LocalTypeDataKey key,
bool allowAbstract, DynamicMetadataRequest request) {
// Use the caching key.
key = key.getCachingKey();
auto it = Map.find(key);
if (it == Map.end()) return MetadataResponse();
auto &chain = it->second;
CacheEntry *best = nullptr;
Optional<OperationCost> bestCost;
CacheEntry *next = chain.Root;
while (next) {
CacheEntry *cur = next;
next = cur->getNext();
// Ignore abstract entries if so requested.
if (!allowAbstract && !isa<ConcreteCacheEntry>(cur))
continue;
// Ignore unacceptable entries.
if (!IGF.isActiveDominancePointDominatedBy(cur->DefinitionPoint))
continue;
// If there's a collision, compare by cost, ignoring higher-cost entries.
if (best) {
// Compute the cost of the best entry if we haven't done so already.
// If that's zero, go ahead and short-circuit out.
if (!bestCost) {
bestCost = best->costForRequest(key, request);
if (*bestCost == OperationCost::Free) break;
}
auto curCost = cur->costForRequest(key, request);
if (curCost >= *bestCost) continue;
// Replace the best cost and fall through.
bestCost = curCost;
}
best = cur;
}
// If we didn't find anything, we're done.
if (!best) return MetadataResponse();
// Okay, we've found the best entry available.
switch (best->getKind()) {
// For concrete caches, this is easy.
case CacheEntry::Kind::Concrete: {
auto entry = cast<ConcreteCacheEntry>(best);
if (entry->immediatelySatisfies(key, request))
return entry->Value;
assert(key.Kind.isAnyTypeMetadata());
// Emit a dynamic check that the type metadata matches the request.
// TODO: we could potentially end up calling this redundantly with a
// dynamic request. Fortunately, those are used only in very narrow
// circumstances.
auto response = emitCheckTypeMetadataState(IGF, request, entry->Value);
// Add a concrete entry for the checked result.
IGF.setScopedLocalTypeData(key, response);
return response;
}
// For abstract caches, we need to follow a path.
case CacheEntry::Kind::Abstract: {
auto entry = cast<AbstractCacheEntry>(best);
// Follow the path.
auto &source = AbstractSources[entry->SourceIndex];
auto response = entry->follow(IGF, source, request);
// Following the path automatically caches at every point along it,
// including the end.
assert(chain.Root->DefinitionPoint == IGF.getActiveDominancePoint());
assert(isa<ConcreteCacheEntry>(chain.Root));
return response;
}
}
llvm_unreachable("bad cache entry kind");
}