本文整理汇总了C++中ArrayRef::size方法的典型用法代码示例。如果您正苦于以下问题:C++ ArrayRef::size方法的具体用法?C++ ArrayRef::size怎么用?C++ ArrayRef::size使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ArrayRef
的用法示例。
在下文中一共展示了ArrayRef::size方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
//
// runTargetDesc - Output the target register and register file descriptions.
//
void
RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
CodeGenRegBank &RegBank){
EmitSourceFileHeader("Target Register and Register Classes Information", OS);
OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";
OS << "#undef GET_REGINFO_TARGET_DESC\n";
OS << "namespace llvm {\n\n";
// Get access to MCRegisterClass data.
OS << "extern const MCRegisterClass " << Target.getName()
<< "MCRegisterClasses[];\n";
// Start out by emitting each of the register classes.
ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
// Collect all registers belonging to any allocatable class.
std::set<Record*> AllocatableRegs;
// Collect allocatable registers.
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
ArrayRef<Record*> Order = RC.getOrder();
if (RC.Allocatable)
AllocatableRegs.insert(Order.begin(), Order.end());
}
// Build a shared array of value types.
SequenceToOffsetTable<std::vector<MVT::SimpleValueType> > VTSeqs;
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc)
VTSeqs.add(RegisterClasses[rc]->VTs);
VTSeqs.layout();
OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
OS << "};\n";
// Now that all of the structs have been emitted, emit the instances.
if (!RegisterClasses.empty()) {
std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
OS << "\nstatic const TargetRegisterClass *const "
<< "NullRegClasses[] = { NULL };\n\n";
unsigned NumSubRegIndices = RegBank.getSubRegIndices().size();
if (NumSubRegIndices) {
// Compute the super-register classes for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
for (DenseMap<Record*,Record*>::const_iterator
i = RC.SubRegClasses.begin(),
e = RC.SubRegClasses.end(); i != e; ++i) {
// Find the register class number of i->second for SuperRegClassMap.
const CodeGenRegisterClass *RC2 = RegBank.getRegClass(i->second);
assert(RC2 && "Invalid register class in SubRegClasses");
SuperRegClassMap[RC2->EnumValue].insert(rc);
}
}
// Emit the super-register classes for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
// Give the register class a legal C name if it's anonymous.
std::string Name = RC.getName();
OS << "// " << Name
<< " Super-register Classes...\n"
<< "static const TargetRegisterClass *const "
<< Name << "SuperRegClasses[] = {\n ";
bool Empty = true;
std::map<unsigned, std::set<unsigned> >::iterator I =
SuperRegClassMap.find(rc);
if (I != SuperRegClassMap.end()) {
for (std::set<unsigned>::iterator II = I->second.begin(),
EE = I->second.end(); II != EE; ++II) {
const CodeGenRegisterClass &RC2 = *RegisterClasses[*II];
if (!Empty)
OS << ", ";
OS << "&" << RC2.getQualifiedName() << "RegClass";
Empty = false;
}
}
OS << (!Empty ? ", " : "") << "NULL";
OS << "\n};\n\n";
}
}
// Emit the sub-classes array for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
// Give the register class a legal C name if it's anonymous.
//.........这里部分代码省略.........
示例2: printCOFFUnwindInfo
void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
const coff_file_header *Header;
if (error(Obj->getHeader(Header))) return;
if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
errs() << "Unsupported image machine type "
"(currently only AMD64 is supported).\n";
return;
}
const coff_section *Pdata = 0;
error_code ec;
for (section_iterator SI = Obj->begin_sections(),
SE = Obj->end_sections();
SI != SE; SI.increment(ec)) {
if (error(ec)) return;
StringRef Name;
if (error(SI->getName(Name))) continue;
if (Name != ".pdata") continue;
Pdata = Obj->getCOFFSection(SI);
std::vector<RelocationRef> Rels;
for (relocation_iterator RI = SI->begin_relocations(),
RE = SI->end_relocations();
RI != RE; RI.increment(ec)) {
if (error(ec)) break;
Rels.push_back(*RI);
}
// Sort relocations by address.
std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
ArrayRef<uint8_t> Contents;
if (error(Obj->getSectionContents(Pdata, Contents))) continue;
if (Contents.empty()) continue;
ArrayRef<RuntimeFunction> RFs(
reinterpret_cast<const RuntimeFunction *>(Contents.data()),
Contents.size() / sizeof(RuntimeFunction));
for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
const uint64_t SectionOffset = std::distance(RFs.begin(), I)
* sizeof(RuntimeFunction);
outs() << "Function Table:\n";
outs() << " Start Address: ";
printCOFFSymbolAddress(outs(), Rels, SectionOffset +
/*offsetof(RuntimeFunction, StartAddress)*/ 0,
I->StartAddress);
outs() << "\n";
outs() << " End Address: ";
printCOFFSymbolAddress(outs(), Rels, SectionOffset +
/*offsetof(RuntimeFunction, EndAddress)*/ 4,
I->EndAddress);
outs() << "\n";
outs() << " Unwind Info Address: ";
printCOFFSymbolAddress(outs(), Rels, SectionOffset +
/*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
I->UnwindInfoOffset);
outs() << "\n";
ArrayRef<uint8_t> XContents;
uint64_t UnwindInfoOffset = 0;
if (error(getSectionContents(Obj, Rels, SectionOffset +
/*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
XContents, UnwindInfoOffset))) continue;
if (XContents.empty()) continue;
UnwindInfoOffset += I->UnwindInfoOffset;
if (UnwindInfoOffset > XContents.size()) continue;
const Win64EH::UnwindInfo *UI =
reinterpret_cast<const Win64EH::UnwindInfo *>
(XContents.data() + UnwindInfoOffset);
// The casts to int are required in order to output the value as number.
// Without the casts the value would be interpreted as char data (which
// results in garbage output).
outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
outs() << " Flags: " << static_cast<int>(UI->getFlags());
if (UI->getFlags()) {
if (UI->getFlags() & UNW_ExceptionHandler)
outs() << " UNW_ExceptionHandler";
if (UI->getFlags() & UNW_TerminateHandler)
outs() << " UNW_TerminateHandler";
if (UI->getFlags() & UNW_ChainInfo)
outs() << " UNW_ChainInfo";
}
outs() << "\n";
outs() << " Size of prolog: "
<< static_cast<int>(UI->PrologSize) << "\n";
outs() << " Number of Codes: "
<< static_cast<int>(UI->NumCodes) << "\n";
// Maybe this should move to output of UOP_SetFPReg?
if (UI->getFrameRegister()) {
//.........这里部分代码省略.........
示例3: addLiveRegs
/// Force liveness of registers.
void RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) {
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
if (LiveRegs.insert(Regs[i]))
increaseRegPressure(Regs[i]);
}
}
示例4: IllegalArgumentException
ArrayRef<Ref<DataBlock> >
DataBlock::getDataBlocks(ArrayRef<unsigned char> rawCodewords,
Version *version,
ErrorCorrectionLevel &ecLevel) {
// Figure out the number and size of data blocks used by this version and
// error correction level
Version::ECBlocks &ecBlocks = version->getECBlocksForLevel(ecLevel);
// First count the total number of data blocks
int totalBlocks = 0;
vector<Version::ECB*> ecBlockArray = ecBlocks.getECBlocks();
for (size_t i = 0; i < ecBlockArray.size(); i++) {
totalBlocks += ecBlockArray[i]->getCount();
}
// Now establish DataBlocks of the appropriate size and number of data codewords
ArrayRef<Ref<DataBlock> > result(totalBlocks);
int numResultBlocks = 0;
for (size_t j = 0; j < ecBlockArray.size(); j++) {
Version::ECB *ecBlock = ecBlockArray[j];
for (int i = 0; i < ecBlock->getCount(); i++) {
int numDataCodewords = ecBlock->getDataCodewords();
int numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords;
ArrayRef<unsigned char> buffer(numBlockCodewords);
Ref<DataBlock> blockRef(new DataBlock(numDataCodewords, buffer));
result[numResultBlocks++] = blockRef;
}
}
// All blocks have the same amount of data, except that the last n
// (where n may be 0) have 1 more byte. Figure out where these start.
int shorterBlocksTotalCodewords = result[0]->codewords_.size();
int longerBlocksStartAt = result->size() - 1;
while (longerBlocksStartAt >= 0) {
int numCodewords = result[longerBlocksStartAt]->codewords_.size();
if (numCodewords == shorterBlocksTotalCodewords) {
break;
}
if (numCodewords != shorterBlocksTotalCodewords + 1) {
throw IllegalArgumentException("Data block sizes differ by more than 1");
}
longerBlocksStartAt--;
}
longerBlocksStartAt++;
int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewords();
// The last elements of result may be 1 element longer;
// first fill out as many elements as all of them have
int rawCodewordsOffset = 0;
for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
for (int j = 0; j < numResultBlocks; j++) {
result[j]->codewords_[i] = rawCodewords[rawCodewordsOffset++];
}
}
// Fill out the last data block in the longer ones
for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {
result[j]->codewords_[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
}
// Now add in error correction blocks
int max = result[0]->codewords_.size();
for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
for (int j = 0; j < numResultBlocks; j++) {
int iOffset = j < longerBlocksStartAt ? i : i + 1;
result[j]->codewords_[iOffset] = rawCodewords[rawCodewordsOffset++];
}
}
if ((size_t) rawCodewordsOffset != rawCodewords.size()) {
throw IllegalArgumentException("rawCodewordsOffset != rawCodewords.length");
}
return result;
}
示例5: if
SolutionDiff::SolutionDiff(ArrayRef<Solution> solutions) {
if (solutions.size() <= 1)
return;
// Populate the type bindings with the first solution.
llvm::DenseMap<TypeVariableType *, SmallVector<Type, 2>> typeBindings;
for (auto binding : solutions[0].typeBindings) {
typeBindings[binding.first].push_back(binding.second);
}
// Populate the overload choices with the first solution.
llvm::DenseMap<ConstraintLocator *, SmallVector<OverloadChoice, 2>>
overloadChoices;
for (auto choice : solutions[0].overloadChoices) {
overloadChoices[choice.first].push_back(choice.second.choice);
}
// Find the type variables and overload locators common to all of the
// solutions.
for (auto &solution : solutions.slice(1)) {
// For each type variable bound in all of the previous solutions, check
// whether we have a binding for this type variable in this solution.
SmallVector<TypeVariableType *, 4> removeTypeBindings;
for (auto &binding : typeBindings) {
auto known = solution.typeBindings.find(binding.first);
if (known == solution.typeBindings.end()) {
removeTypeBindings.push_back(binding.first);
continue;
}
// Add this solution's binding to the results.
binding.second.push_back(known->second);
}
// Remove those type variables for which this solution did not have a
// binding.
for (auto typeVar : removeTypeBindings) {
typeBindings.erase(typeVar);
}
removeTypeBindings.clear();
// For each overload locator for which we have an overload choice in
// all of the previous solutions. Check whether we have an overload choice
// in this solution.
SmallVector<ConstraintLocator *, 4> removeOverloadChoices;
for (auto &overloadChoice : overloadChoices) {
auto known = solution.overloadChoices.find(overloadChoice.first);
if (known == solution.overloadChoices.end()) {
removeOverloadChoices.push_back(overloadChoice.first);
continue;
}
// Add this solution's overload choice to the results.
overloadChoice.second.push_back(known->second.choice);
}
// Remove those overload locators for which this solution did not have
// an overload choice.
for (auto overloadChoice : removeOverloadChoices) {
overloadChoices.erase(overloadChoice);
}
}
// Look through the type variables that have bindings in all of the
// solutions, and add those that have differences to the diff.
for (auto &binding : typeBindings) {
Type singleType;
for (auto type : binding.second) {
if (!singleType)
singleType = type;
else if (!singleType->isEqual(type)) {
// We have a difference. Add this binding to the diff.
this->typeBindings.push_back(
SolutionDiff::TypeBindingDiff{
binding.first,
std::move(binding.second)
});
break;
}
}
}
// Look through the overload locators that have overload choices in all of
// the solutions, and add those that have differences to the diff.
for (auto &overloadChoice : overloadChoices) {
OverloadChoice singleChoice = overloadChoice.second[0];
for (auto choice : overloadChoice.second) {
if (!sameOverloadChoice(singleChoice, choice)) {
// We have a difference. Add this set of overload choices to the diff.
this->overloads.push_back(
SolutionDiff::OverloadDiff{
overloadChoice.first,
overloadChoice.second
});
}
}
}
}
示例6: printPretty
void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
switch (getKind()) {
case APValue::Uninitialized:
Out << "<uninitialized>";
return;
case APValue::Int:
if (Ty->isBooleanType())
Out << (getInt().getBoolValue() ? "true" : "false");
else
Out << getInt();
return;
case APValue::Float:
Out << GetApproxValue(getFloat());
return;
case APValue::Vector: {
Out << '{';
QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
getVectorElt(0).printPretty(Out, Ctx, ElemTy);
for (unsigned i = 1; i != getVectorLength(); ++i) {
Out << ", ";
getVectorElt(i).printPretty(Out, Ctx, ElemTy);
}
Out << '}';
return;
}
case APValue::ComplexInt:
Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
return;
case APValue::ComplexFloat:
Out << GetApproxValue(getComplexFloatReal()) << "+"
<< GetApproxValue(getComplexFloatImag()) << "i";
return;
case APValue::LValue: {
LValueBase Base = getLValueBase();
if (!Base) {
Out << "0";
return;
}
bool IsReference = Ty->isReferenceType();
QualType InnerTy
= IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
if (!hasLValuePath()) {
// No lvalue path: just print the offset.
CharUnits O = getLValueOffset();
CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
if (!O.isZero()) {
if (IsReference)
Out << "*(";
if (O % S) {
Out << "(char*)";
S = CharUnits::One();
}
Out << '&';
} else if (!IsReference)
Out << '&';
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
else
Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
if (!O.isZero()) {
Out << " + " << (O / S);
if (IsReference)
Out << ')';
}
return;
}
// We have an lvalue path. Print it out nicely.
if (!IsReference)
Out << '&';
else if (isLValueOnePastTheEnd())
Out << "*(&";
QualType ElemTy;
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
Out << *VD;
ElemTy = VD->getType();
} else {
const Expr *E = Base.get<const Expr*>();
E->printPretty(Out, 0, Ctx.getPrintingPolicy());
ElemTy = E->getType();
}
ArrayRef<LValuePathEntry> Path = getLValuePath();
const CXXRecordDecl *CastToBase = 0;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (ElemTy->getAs<RecordType>()) {
// The lvalue refers to a class type, so the next path entry is a base
// or member.
const Decl *BaseOrMember =
BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
CastToBase = RD;
ElemTy = Ctx.getRecordType(RD);
} else {
const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
Out << ".";
//.........这里部分代码省略.........
示例7: analyze
/// This function goes through the arguments of F and sees if we have anything
/// to optimize in which case it returns true. If we have nothing to optimize,
/// it returns false.
bool FunctionAnalyzer::analyze() {
// For now ignore functions with indirect results.
if (F->getLoweredFunctionType()->hasIndirectResult())
return false;
ArrayRef<SILArgument *> Args = F->begin()->getBBArgs();
// A map from consumed SILArguments to the release associated with an
// argument.
ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(RCIA, F);
ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap(
RCIA, F, ConsumedArgToEpilogueReleaseMatcher::ExitKind::Throw);
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgumentDescriptor A(Allocator, Args[i]);
bool HaveOptimizedArg = false;
bool isABIRequired = isArgumentABIRequired(Args[i]);
auto OnlyRelease = getNonTrivialNonDebugReleaseUse(Args[i]);
// If this argument is not ABI required and has not uses except for debug
// instructions, remove it.
if (!isABIRequired && OnlyRelease && OnlyRelease.getValue().isNull()) {
A.IsDead = true;
HaveOptimizedArg = true;
++NumDeadArgsEliminated;
}
// See if we can find a ref count equivalent strong_release or release_value
// at the end of this function if our argument is an @owned parameter.
if (A.hasConvention(ParameterConvention::Direct_Owned)) {
if (auto *Release = ArgToReturnReleaseMap.releaseForArgument(A.Arg)) {
SILInstruction *ReleaseInThrow = nullptr;
// If the function has a throw block we must also find a matching
// release in the throw block.
if (!ArgToThrowReleaseMap.hasBlock() ||
(ReleaseInThrow = ArgToThrowReleaseMap.releaseForArgument(A.Arg))) {
// TODO: accept a second release in the throw block to let the
// argument be dead.
if (OnlyRelease && OnlyRelease.getValue().getPtrOrNull() == Release) {
A.IsDead = true;
}
A.CalleeRelease = Release;
A.CalleeReleaseInThrowBlock = ReleaseInThrow;
HaveOptimizedArg = true;
++NumOwnedConvertedToGuaranteed;
}
}
}
if (A.shouldExplode()) {
HaveOptimizedArg = true;
++NumSROAArguments;
}
if (HaveOptimizedArg) {
ShouldOptimize = true;
// Store that we have modified the self argument. We need to change the
// calling convention later.
if (Args[i]->isSelf())
HaveModifiedSelfArgument = true;
}
// Add the argument to our list.
ArgDescList.push_back(std::move(A));
}
return ShouldOptimize;
}
示例8: emitExistentialErasure
ManagedValue SILGenFunction::emitExistentialErasure(
SILLocation loc,
CanType concreteFormalType,
const TypeLowering &concreteTL,
const TypeLowering &existentialTL,
ArrayRef<ProtocolConformanceRef> conformances,
SGFContext C,
llvm::function_ref<ManagedValue (SGFContext)> F,
bool allowEmbeddedNSError) {
// Mark the needed conformances as used.
for (auto conformance : conformances)
SGM.useConformance(conformance);
// If we're erasing to the 'Error' type, we might be able to get an NSError
// representation more efficiently.
auto &ctx = getASTContext();
if (ctx.LangOpts.EnableObjCInterop && conformances.size() == 1 &&
conformances[0].getRequirement() == ctx.getErrorDecl() &&
ctx.getNSErrorDecl()) {
auto nsErrorDecl = ctx.getNSErrorDecl();
// If the concrete type is NSError or a subclass thereof, just erase it
// directly.
auto nsErrorType = nsErrorDecl->getDeclaredType()->getCanonicalType();
if (nsErrorType->isExactSuperclassOf(concreteFormalType, nullptr)) {
ManagedValue nsError = F(SGFContext());
if (nsErrorType != concreteFormalType) {
nsError = ManagedValue(B.createUpcast(loc, nsError.getValue(),
getLoweredType(nsErrorType)),
nsError.getCleanup());
}
return emitBridgedToNativeError(loc, nsError);
}
// If the concrete type is known to conform to _BridgedStoredNSError,
// call the _nsError witness getter to extract the NSError directly,
// then just erase the NSError.
if (auto storedNSErrorConformance =
SGM.getConformanceToBridgedStoredNSError(loc, concreteFormalType)) {
auto nsErrorVar = SGM.getNSErrorRequirement(loc);
if (!nsErrorVar) return emitUndef(loc, existentialTL.getLoweredType());
ArrayRef<Substitution> nsErrorVarSubstitutions;
// Devirtualize. Maybe this should be done implicitly by
// emitPropertyLValue?
if (storedNSErrorConformance->isConcrete()) {
if (auto witnessVar = storedNSErrorConformance->getConcrete()
->getWitness(nsErrorVar, nullptr)) {
nsErrorVar = cast<VarDecl>(witnessVar.getDecl());
nsErrorVarSubstitutions = witnessVar.getSubstitutions();
}
}
auto nativeError = F(SGFContext());
WritebackScope writebackScope(*this);
auto nsError =
emitRValueForPropertyLoad(loc, nativeError, concreteFormalType,
/*super*/ false, nsErrorVar,
nsErrorVarSubstitutions,
AccessSemantics::Ordinary, nsErrorType,
SGFContext())
.getAsSingleValue(*this, loc);
return emitBridgedToNativeError(loc, nsError);
}
// Otherwise, if it's an archetype, try calling the _getEmbeddedNSError()
// witness to try to dig out the embedded NSError. But don't do this
// when we're being called recursively.
if (isa<ArchetypeType>(concreteFormalType) && allowEmbeddedNSError) {
auto contBB = createBasicBlock();
auto isNotPresentBB = createBasicBlock();
auto isPresentBB = createBasicBlock();
// Call swift_stdlib_getErrorEmbeddedNSError to attempt to extract an
// NSError from the value.
auto getEmbeddedNSErrorFn = SGM.getGetErrorEmbeddedNSError(loc);
if (!getEmbeddedNSErrorFn)
return emitUndef(loc, existentialTL.getLoweredType());
Substitution getEmbeddedNSErrorSubstitutions[1] = {
Substitution(concreteFormalType, conformances)
};
ManagedValue concreteValue = F(SGFContext());
ManagedValue potentialNSError =
emitApplyOfLibraryIntrinsic(loc,
getEmbeddedNSErrorFn,
getEmbeddedNSErrorSubstitutions,
{ concreteValue.copy(*this, loc) },
SGFContext())
.getAsSingleValue(*this, loc);
// We're going to consume 'concreteValue' in exactly one branch,
// so kill its cleanup now and recreate it on both branches.
(void) concreteValue.forward(*this);
// Check whether we got an NSError back.
//.........这里部分代码省略.........
示例9: B
/// AggregateAvailableValues - Given a bunch of primitive subelement values,
/// build out the right aggregate type (LoadTy) by emitting tuple and struct
/// instructions as necessary.
static SILValue
AggregateAvailableValues(SILInstruction *Inst, SILType LoadTy,
SILValue Address,
ArrayRef<std::pair<SILValue, unsigned>> AvailableValues,
unsigned FirstElt) {
assert(LoadTy.isObject());
SILModule &M = Inst->getModule();
// Check to see if the requested value is fully available, as an aggregate.
// This is a super-common case for single-element structs, but is also a
// general answer for arbitrary structs and tuples as well.
if (FirstElt < AvailableValues.size()) { // #Elements may be zero.
SILValue FirstVal = AvailableValues[FirstElt].first;
if (FirstVal && AvailableValues[FirstElt].second == 0 &&
FirstVal->getType() == LoadTy) {
// If the first element of this value is available, check any extra ones
// before declaring success.
bool AllMatch = true;
for (unsigned i = 0, e = getNumSubElements(LoadTy, M); i != e; ++i)
if (AvailableValues[FirstElt+i].first != FirstVal ||
AvailableValues[FirstElt+i].second != i) {
AllMatch = false;
break;
}
if (AllMatch)
return FirstVal;
}
}
SILBuilderWithScope B(Inst);
if (TupleType *TT = LoadTy.getAs<TupleType>()) {
SmallVector<SILValue, 4> ResultElts;
for (unsigned EltNo : indices(TT->getElements())) {
SILType EltTy = LoadTy.getTupleElementType(EltNo);
unsigned NumSubElt = getNumSubElements(EltTy, M);
// If we are missing any of the available values in this struct element,
// compute an address to load from.
SILValue EltAddr;
if (anyMissing(FirstElt, NumSubElt, AvailableValues))
EltAddr = B.createTupleElementAddr(Inst->getLoc(), Address, EltNo,
EltTy.getAddressType());
ResultElts.push_back(AggregateAvailableValues(Inst, EltTy, EltAddr,
AvailableValues, FirstElt));
FirstElt += NumSubElt;
}
return B.createTuple(Inst->getLoc(), LoadTy, ResultElts);
}
// Extract struct elements from fully referenceable structs.
if (auto *SD = getFullyReferenceableStruct(LoadTy)) {
SmallVector<SILValue, 4> ResultElts;
for (auto *FD : SD->getStoredProperties()) {
SILType EltTy = LoadTy.getFieldType(FD, M);
unsigned NumSubElt = getNumSubElements(EltTy, M);
// If we are missing any of the available values in this struct element,
// compute an address to load from.
SILValue EltAddr;
if (anyMissing(FirstElt, NumSubElt, AvailableValues))
EltAddr = B.createStructElementAddr(Inst->getLoc(), Address, FD,
EltTy.getAddressType());
ResultElts.push_back(AggregateAvailableValues(Inst, EltTy, EltAddr,
AvailableValues, FirstElt));
FirstElt += NumSubElt;
}
return B.createStruct(Inst->getLoc(), LoadTy, ResultElts);
}
// Otherwise, we have a simple primitive. If the value is available, use it,
// otherwise emit a load of the value.
auto Val = AvailableValues[FirstElt];
if (!Val.first)
return B.createLoad(Inst->getLoc(), Address);
SILValue EltVal = ExtractSubElement(Val.first, Val.second, B, Inst->getLoc());
// It must be the same type as LoadTy if available.
assert(EltVal->getType() == LoadTy &&
"Subelement types mismatch");
return EltVal;
}
示例10: CanEvaluateShuffled
/// Return true if we can evaluate the specified expression tree if the vector
/// elements were shuffled in a different order.
static bool CanEvaluateShuffled(Value *V, ArrayRef<int> Mask,
unsigned Depth = 5) {
// We can always reorder the elements of a constant.
if (isa<Constant>(V))
return true;
// We won't reorder vector arguments. No IPO here.
Instruction *I = dyn_cast<Instruction>(V);
if (!I) return false;
// Two users may expect different orders of the elements. Don't try it.
if (!I->hasOneUse())
return false;
if (Depth == 0) return false;
switch (I->getOpcode()) {
case Instruction::Add:
case Instruction::FAdd:
case Instruction::Sub:
case Instruction::FSub:
case Instruction::Mul:
case Instruction::FMul:
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::FDiv:
case Instruction::URem:
case Instruction::SRem:
case Instruction::FRem:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::ICmp:
case Instruction::FCmp:
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::FPTrunc:
case Instruction::FPExt:
case Instruction::GetElementPtr: {
for (Value *Operand : I->operands()) {
if (!CanEvaluateShuffled(Operand, Mask, Depth-1))
return false;
}
return true;
}
case Instruction::InsertElement: {
ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(2));
if (!CI) return false;
int ElementNumber = CI->getLimitedValue();
// Verify that 'CI' does not occur twice in Mask. A single 'insertelement'
// can't put an element into multiple indices.
bool SeenOnce = false;
for (int i = 0, e = Mask.size(); i != e; ++i) {
if (Mask[i] == ElementNumber) {
if (SeenOnce)
return false;
SeenOnce = true;
}
}
return CanEvaluateShuffled(I->getOperand(0), Mask, Depth-1);
}
}
return false;
}
示例11: findReachingDefs
bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB,
SlotIndex Use, unsigned PhysReg,
ArrayRef<SlotIndex> Undefs) {
unsigned UseMBBNum = UseMBB.getNumber();
// Block numbers where LR should be live-in.
SmallVector<unsigned, 16> WorkList(1, UseMBBNum);
// Remember if we have seen more than one value.
bool UniqueVNI = true;
VNInfo *TheVNI = nullptr;
bool FoundUndef = false;
// Using Seen as a visited set, perform a BFS for all reaching defs.
for (unsigned i = 0; i != WorkList.size(); ++i) {
MachineBasicBlock *MBB = MF->getBlockNumbered(WorkList[i]);
#ifndef NDEBUG
if (Undefs.size() > 0 && MBB->pred_empty()) {
MBB->getParent()->verify();
errs() << "Use of " << PrintReg(PhysReg)
<< " does not have a corresponding definition on every path:\n";
const MachineInstr *MI = Indexes->getInstructionFromIndex(Use);
if (MI != nullptr)
errs() << Use << " " << *MI;
llvm_unreachable("Use not jointly dominated by defs.");
}
if (TargetRegisterInfo::isPhysicalRegister(PhysReg) &&
!MBB->isLiveIn(PhysReg)) {
MBB->getParent()->verify();
const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
errs() << "The register " << PrintReg(PhysReg, TRI)
<< " needs to be live in to BB#" << MBB->getNumber()
<< ", but is missing from the live-in list.\n";
llvm_unreachable("Invalid global physical register");
}
#endif
FoundUndef |= MBB->pred_empty();
for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
PE = MBB->pred_end(); PI != PE; ++PI) {
MachineBasicBlock *Pred = *PI;
// Is this a known live-out block?
if (Seen.test(Pred->getNumber())) {
if (VNInfo *VNI = Map[Pred].first) {
if (TheVNI && TheVNI != VNI)
UniqueVNI = false;
TheVNI = VNI;
}
continue;
}
SlotIndex Start, End;
std::tie(Start, End) = Indexes->getMBBRange(Pred);
// First time we see Pred. Try to determine the live-out value, but set
// it as null if Pred is live-through with an unknown value.
auto EP = LR.extendInBlock(Undefs, Start, End);
VNInfo *VNI = EP.first;
FoundUndef |= EP.second;
setLiveOutValue(Pred, VNI);
if (VNI) {
if (TheVNI && TheVNI != VNI)
UniqueVNI = false;
TheVNI = VNI;
}
if (VNI || EP.second)
continue;
// No, we need a live-in value for Pred as well
if (Pred != &UseMBB)
WorkList.push_back(Pred->getNumber());
else
// Loopback to UseMBB, so value is really live through.
Use = SlotIndex();
}
}
LiveIn.clear();
FoundUndef |= (TheVNI == nullptr);
if (Undefs.size() > 0 && FoundUndef)
UniqueVNI = false;
// Both updateSSA() and LiveRangeUpdater benefit from ordered blocks, but
// neither require it. Skip the sorting overhead for small updates.
if (WorkList.size() > 4)
array_pod_sort(WorkList.begin(), WorkList.end());
// If a unique reaching def was found, blit in the live ranges immediately.
if (UniqueVNI) {
assert(TheVNI != nullptr);
LiveRangeUpdater Updater(&LR);
for (unsigned BN : WorkList) {
SlotIndex Start, End;
std::tie(Start, End) = Indexes->getMBBRange(BN);
// Trim the live range in UseMBB.
if (BN == UseMBBNum && Use.isValid())
//.........这里部分代码省略.........
示例12: checkPreCall
void NonNullParamChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
const Decl *FD = Call.getDecl();
if (!FD)
return;
// Merge all non-null attributes
unsigned NumArgs = Call.getNumArgs();
llvm::SmallBitVector AttrNonNull(NumArgs);
for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) {
if (!NonNull->args_size()) {
AttrNonNull.set(0, NumArgs);
break;
}
for (unsigned Val : NonNull->args()) {
if (Val >= NumArgs)
continue;
AttrNonNull.set(Val);
}
}
ProgramStateRef state = C.getState();
CallEvent::param_type_iterator TyI = Call.param_type_begin(),
TyE = Call.param_type_end();
for (unsigned idx = 0; idx < NumArgs; ++idx) {
// Check if the parameter is a reference. We want to report when reference
// to a null pointer is passed as a paramter.
bool haveRefTypeParam = false;
if (TyI != TyE) {
haveRefTypeParam = (*TyI)->isReferenceType();
TyI++;
}
bool haveAttrNonNull = AttrNonNull[idx];
if (!haveAttrNonNull) {
// Check if the parameter is also marked 'nonnull'.
ArrayRef<ParmVarDecl*> parms = Call.parameters();
if (idx < parms.size())
haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>();
}
if (!haveRefTypeParam && !haveAttrNonNull)
continue;
// If the value is unknown or undefined, we can't perform this check.
const Expr *ArgE = Call.getArgExpr(idx);
SVal V = Call.getArgSVal(idx);
Optional<DefinedSVal> DV = V.getAs<DefinedSVal>();
if (!DV)
continue;
// Process the case when the argument is not a location.
assert(!haveRefTypeParam || DV->getAs<Loc>());
if (haveAttrNonNull && !DV->getAs<Loc>()) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
if (!ArgE)
continue;
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
if (Optional<nonloc::CompoundVal> CSV =
DV->getAs<nonloc::CompoundVal>()) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
V = *CSV_I;
DV = V.getAs<DefinedSVal>();
assert(++CSV_I == CSV->end());
// FIXME: Handle (some_union){ some_other_union_val }, which turns into
// a LazyCompoundVal inside a CompoundVal.
if (!V.getAs<Loc>())
continue;
// Retrieve the corresponding expression.
if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE))
if (const InitListExpr *IE =
dyn_cast<InitListExpr>(CE->getInitializer()))
ArgE = dyn_cast<Expr>(*(IE->begin()));
} else {
// FIXME: Handle LazyCompoundVals?
continue;
}
}
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (stateNull) {
if (!stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
if (ExplodedNode *errorNode = C.generateErrorNode(stateNull)) {
//.........这里部分代码省略.........
示例13: getIntrinsicInstrCost
unsigned BasicTTI::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<Type *> Tys) const {
unsigned ISD = 0;
switch (IID) {
default: {
// Assume that we need to scalarize this intrinsic.
unsigned ScalarizationCost = 0;
unsigned ScalarCalls = 1;
if (RetTy->isVectorTy()) {
ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
}
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
if (Tys[i]->isVectorTy()) {
ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
}
}
return ScalarCalls + ScalarizationCost;
}
// Look for intrinsics that can be lowered directly or turned into a scalar
// intrinsic call.
case Intrinsic::sqrt: ISD = ISD::FSQRT; break;
case Intrinsic::sin: ISD = ISD::FSIN; break;
case Intrinsic::cos: ISD = ISD::FCOS; break;
case Intrinsic::exp: ISD = ISD::FEXP; break;
case Intrinsic::exp2: ISD = ISD::FEXP2; break;
case Intrinsic::log: ISD = ISD::FLOG; break;
case Intrinsic::log10: ISD = ISD::FLOG10; break;
case Intrinsic::log2: ISD = ISD::FLOG2; break;
case Intrinsic::fabs: ISD = ISD::FABS; break;
case Intrinsic::floor: ISD = ISD::FFLOOR; break;
case Intrinsic::ceil: ISD = ISD::FCEIL; break;
case Intrinsic::trunc: ISD = ISD::FTRUNC; break;
case Intrinsic::rint: ISD = ISD::FRINT; break;
case Intrinsic::pow: ISD = ISD::FPOW; break;
case Intrinsic::fma: ISD = ISD::FMA; break;
case Intrinsic::fmuladd: ISD = ISD::FMA; break; // FIXME: mul + add?
}
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy);
if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
// The operation is legal. Assume it costs 1.
// If the type is split to multiple registers, assume that thre is some
// overhead to this.
// TODO: Once we have extract/insert subvector cost we need to use them.
if (LT.first > 1)
return LT.first * 2;
return LT.first * 1;
}
if (!TLI->isOperationExpand(ISD, LT.second)) {
// If the operation is custom lowered then assume
// thare the code is twice as expensive.
return LT.first * 2;
}
// Else, assume that we need to scalarize this intrinsic. For math builtins
// this will emit a costly libcall, adding call overhead and spills. Make it
// very expensive.
if (RetTy->isVectorTy()) {
unsigned Num = RetTy->getVectorNumElements();
unsigned Cost = TopTTI->getIntrinsicInstrCost(IID, RetTy->getScalarType(),
Tys);
return 10 * Cost * Num;
}
// This is going to be turned into a library call, make it expensive.
return 10;
}
示例14: NoteJumpIntoScopes
/// Produce note diagnostics for a jump into a protected scope.
void JumpScopeChecker::NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes) {
assert(!ToScopes.empty());
for (unsigned I = 0, E = ToScopes.size(); I != E; ++I)
if (Scopes[ToScopes[I]].InDiag)
S.Diag(Scopes[ToScopes[I]].Loc, Scopes[ToScopes[I]].InDiag);
}
示例15: check
void elf::ObjectFile<ELFT>::initializeSections(
DenseSet<CachedHashStringRef> &ComdatGroups) {
const ELFFile<ELFT> &Obj = this->getObj();
ArrayRef<Elf_Shdr> ObjSections =
check(this->getObj().sections(), toString(this));
uint64_t Size = ObjSections.size();
this->Sections.resize(Size);
this->SectionStringTable =
check(Obj.getSectionStringTable(ObjSections), toString(this));
for (size_t I = 0, E = ObjSections.size(); I < E; I++) {
if (this->Sections[I] == &InputSection::Discarded)
continue;
const Elf_Shdr &Sec = ObjSections[I];
// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
// This is compatible with GNU.
if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) {
this->Sections[I] = &InputSection::Discarded;
continue;
}
switch (Sec.sh_type) {
case SHT_GROUP: {
// De-duplicate section groups by their signatures.
StringRef Signature = getShtGroupSignature(ObjSections, Sec);
bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
this->Sections[I] = &InputSection::Discarded;
// If it is a new section group, we want to keep group members.
// Group leader sections, which contain indices of group members, are
// discarded because they are useless beyond this point. The only
// exception is the -r option because in order to produce re-linkable
// object files, we want to pass through basically everything.
if (IsNew) {
if (Config->Relocatable)
this->Sections[I] = createInputSection(Sec);
continue;
}
// Otherwise, discard group members.
for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
if (SecIndex >= Size)
fatal(toString(this) +
": invalid section index in group: " + Twine(SecIndex));
this->Sections[SecIndex] = &InputSection::Discarded;
}
break;
}
case SHT_SYMTAB:
this->initSymtab(ObjSections, &Sec);
break;
case SHT_SYMTAB_SHNDX:
this->SymtabSHNDX =
check(Obj.getSHNDXTable(Sec, ObjSections), toString(this));
break;
case SHT_STRTAB:
case SHT_NULL:
break;
default:
this->Sections[I] = createInputSection(Sec);
}
// .ARM.exidx sections have a reverse dependency on the InputSection they
// have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
if (Sec.sh_flags & SHF_LINK_ORDER) {
if (Sec.sh_link >= this->Sections.size())
fatal(toString(this) + ": invalid sh_link index: " +
Twine(Sec.sh_link));
this->Sections[Sec.sh_link]->DependentSections.push_back(
this->Sections[I]);
}
}
}