Vendor import of llvm-project main llvmorg-14-init-10223-g401b76fdf2b3.
This commit is contained in:
parent
c0981da47d
commit
846a2208a8
@ -258,7 +258,8 @@ class Redeclarable {
|
||||
|
||||
redecl_iterator& operator++() {
|
||||
assert(Current && "Advancing while iterator has reached end");
|
||||
// Sanity check to avoid infinite loop on invalid redecl chain.
|
||||
// Make sure we don't infinitely loop on an invalid redecl chain. This
|
||||
// should never happen.
|
||||
if (Current->isFirstDecl()) {
|
||||
if (PassedFirst) {
|
||||
assert(0 && "Passed first decl twice, invalid redecl chain!");
|
||||
|
@ -5073,8 +5073,10 @@ class DeducedTemplateSpecializationType : public DeducedType,
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
|
||||
QualType Deduced, bool IsDependent) {
|
||||
Template.Profile(ID);
|
||||
ID.AddPointer(Deduced.getAsOpaquePtr());
|
||||
ID.AddBoolean(IsDependent);
|
||||
QualType CanonicalType =
|
||||
Deduced.isNull() ? Deduced : Deduced.getCanonicalType();
|
||||
ID.AddPointer(CanonicalType.getAsOpaquePtr());
|
||||
ID.AddBoolean(IsDependent || Template.isDependent());
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
|
@ -515,7 +515,7 @@ class CFGTerminator {
|
||||
/// of the most derived class while we're in the base class.
|
||||
VirtualBaseBranch,
|
||||
|
||||
/// Number of different kinds, for sanity checks. We subtract 1 so that
|
||||
/// Number of different kinds, for validity checks. We subtract 1 so that
|
||||
/// to keep receiving compiler warnings when we don't cover all enum values
|
||||
/// in a switch.
|
||||
NumKindsMinusOne = VirtualBaseBranch
|
||||
|
@ -2310,6 +2310,7 @@ def SwiftAttr : InheritableAttr {
|
||||
let Spellings = [GNU<"swift_attr">];
|
||||
let Args = [StringArgument<"Attribute">];
|
||||
let Documentation = [SwiftAttrDocs];
|
||||
let PragmaAttributeSupport = 1;
|
||||
}
|
||||
|
||||
def SwiftBridge : InheritableAttr {
|
||||
|
@ -250,7 +250,7 @@ class ABIArgInfo {
|
||||
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
|
||||
llvm::Type *unpaddedCoerceToType) {
|
||||
#ifndef NDEBUG
|
||||
// Sanity checks on unpaddedCoerceToType.
|
||||
// Check that unpaddedCoerceToType has roughly the right shape.
|
||||
|
||||
// Assert that we only have a struct type if there are multiple elements.
|
||||
auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
|
||||
|
@ -319,7 +319,7 @@ class LookupResult {
|
||||
}
|
||||
|
||||
LookupResultKind getResultKind() const {
|
||||
assert(sanity());
|
||||
assert(checkDebugAssumptions());
|
||||
return ResultKind;
|
||||
}
|
||||
|
||||
@ -706,10 +706,9 @@ class LookupResult {
|
||||
void addDeclsFromBasePaths(const CXXBasePaths &P);
|
||||
void configure();
|
||||
|
||||
// Sanity checks.
|
||||
bool sanity() const;
|
||||
bool checkDebugAssumptions() const;
|
||||
|
||||
bool sanityCheckUnresolved() const {
|
||||
bool checkUnresolved() const {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
|
||||
return true;
|
||||
|
@ -5676,6 +5676,9 @@ QualType ASTContext::getDeducedTemplateSpecializationType(
|
||||
|
||||
auto *DTST = new (*this, TypeAlignment)
|
||||
DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);
|
||||
llvm::FoldingSetNodeID TempID;
|
||||
DTST->Profile(TempID);
|
||||
assert(ID == TempID && "ID does not match");
|
||||
Types.push_back(DTST);
|
||||
DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos);
|
||||
return QualType(DTST, 0);
|
||||
|
@ -790,9 +790,8 @@ static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check that the property is the same type as the ivar, or a
|
||||
// reference to it, and that it is either an object pointer or trivially
|
||||
// copyable.
|
||||
// We expect that the property is the same type as the ivar, or a reference to
|
||||
// it, and that it is either an object pointer or trivially copyable.
|
||||
if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
|
||||
Prop->getType().getNonReferenceType()))
|
||||
return nullptr;
|
||||
|
@ -791,7 +791,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
|
||||
// Unary functions have no arg effects by definition.
|
||||
ArgEffects ScratchArgs(AF.getEmptyMap());
|
||||
|
||||
// Sanity check that this is *really* a unary function. This can
|
||||
// Verify that this is *really* a unary function. This can
|
||||
// happen if people do weird things.
|
||||
const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
|
||||
if (!FTP || FTP->getNumParams() != 1)
|
||||
|
@ -692,7 +692,7 @@ void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
|
||||
StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
|
||||
StringRef Group) {
|
||||
StringRef Best;
|
||||
unsigned BestDistance = Group.size() + 1; // Sanity threshold.
|
||||
unsigned BestDistance = Group.size() + 1; // Maximum threshold.
|
||||
for (const WarningOption &O : OptionTable) {
|
||||
// Don't suggest ignored warning flags.
|
||||
if (!O.Members && !O.SubGroups)
|
||||
|
@ -59,12 +59,10 @@ unsigned ContentCache::getSizeBytesMapped() const {
|
||||
/// Returns the kind of memory used to back the memory buffer for
|
||||
/// this content cache. This is used for performance analysis.
|
||||
llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const {
|
||||
assert(Buffer);
|
||||
|
||||
// Should be unreachable, but keep for sanity.
|
||||
if (!Buffer)
|
||||
if (Buffer == nullptr) {
|
||||
assert(0 && "Buffer should never be null");
|
||||
return llvm::MemoryBuffer::MemoryBuffer_Malloc;
|
||||
|
||||
}
|
||||
return Buffer->getBufferKind();
|
||||
}
|
||||
|
||||
@ -864,7 +862,6 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
|
||||
/// This function knows that the SourceLocation is in a loaded buffer, not a
|
||||
/// local one.
|
||||
FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const {
|
||||
// Sanity checking, otherwise a bug may lead to hanging in release build.
|
||||
if (SLocOffset < CurrentLoadedOffset) {
|
||||
assert(0 && "Invalid SLocOffset or bad function choice");
|
||||
return FileID();
|
||||
@ -909,7 +906,6 @@ FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const {
|
||||
++NumProbes;
|
||||
|
||||
if (E.getOffset() > SLocOffset) {
|
||||
// Sanity checking, otherwise a bug may lead to hanging in release build.
|
||||
if (GreaterIndex == MiddleIndex) {
|
||||
assert(0 && "binary search missed the entry");
|
||||
return FileID();
|
||||
@ -925,7 +921,6 @@ FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const {
|
||||
return Res;
|
||||
}
|
||||
|
||||
// Sanity checking, otherwise a bug may lead to hanging in release build.
|
||||
if (LessIndex == MiddleIndex) {
|
||||
assert(0 && "binary search missed the entry");
|
||||
return FileID();
|
||||
|
@ -4303,7 +4303,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const Driver &D = TC.getDriver();
|
||||
ArgStringList CmdArgs;
|
||||
|
||||
// Check number of inputs for sanity. We need at least one input.
|
||||
assert(Inputs.size() >= 1 && "Must have at least one input.");
|
||||
// CUDA/HIP compilation may have multiple inputs (source file + results of
|
||||
// device-side compilations). OpenMP device jobs also take the host IR as a
|
||||
|
@ -2579,7 +2579,7 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
|
||||
// doesn't have hidden dependencies
|
||||
// (http://llvm.org/docs/CodingStandards.html#include-style).
|
||||
//
|
||||
// FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix
|
||||
// FIXME: Do some validation, e.g. edit distance of the base name, to fix
|
||||
// cases where the first #include is unlikely to be the main header.
|
||||
tooling::IncludeCategoryManager Categories(Style.IncludeStyle, FileName);
|
||||
bool FirstIncludeBlock = true;
|
||||
|
@ -842,7 +842,7 @@ void PrintPreprocessedAction::ExecuteAction() {
|
||||
const char *next = (cur != end) ? cur + 1 : end;
|
||||
|
||||
// Limit ourselves to only scanning 256 characters into the source
|
||||
// file. This is mostly a sanity check in case the file has no
|
||||
// file. This is mostly a check in case the file has no
|
||||
// newlines whatsoever.
|
||||
if (end - cur > 256)
|
||||
end = cur + 256;
|
||||
|
@ -5532,8 +5532,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
|
||||
|
||||
// For an arithmetic operation, the implied arithmetic must be well-formed.
|
||||
if (Form == Arithmetic) {
|
||||
// gcc does not enforce these rules for GNU atomics, but we do so for
|
||||
// sanity.
|
||||
// GCC does not enforce these rules for GNU atomics, but we do, because if
|
||||
// we didn't it would be very confusing. FIXME: For whom? How so?
|
||||
auto IsAllowedValueType = [&](QualType ValType) {
|
||||
if (ValType->isIntegerType())
|
||||
return true;
|
||||
@ -5574,7 +5574,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
|
||||
if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) &&
|
||||
!AtomTy->isScalarType()) {
|
||||
// For GNU atomics, require a trivially-copyable type. This is not part of
|
||||
// the GNU atomics specification, but we enforce it for sanity.
|
||||
// the GNU atomics specification, but we enforce it, because if we didn't it
|
||||
// would be very confusing. FIXME: For whom? How so?
|
||||
Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_trivial_copy)
|
||||
<< Ptr->getType() << Ptr->getSourceRange();
|
||||
return ExprError();
|
||||
|
@ -12621,8 +12621,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
||||
}
|
||||
|
||||
/// ActOnInitializerError - Given that there was an error parsing an
|
||||
/// initializer for the given declaration, try to return to some form
|
||||
/// of sanity.
|
||||
/// initializer for the given declaration, try to at least re-establish
|
||||
/// invariants such as whether a variable's type is either dependent or
|
||||
/// complete.
|
||||
void Sema::ActOnInitializerError(Decl *D) {
|
||||
// Our main concern here is re-establishing invariants like "a
|
||||
// variable's type is either dependent or complete".
|
||||
@ -15997,8 +15998,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
|
||||
// It's okay to have a tag decl in the same scope as a typedef
|
||||
// which hides a tag decl in the same scope. Finding this
|
||||
// insanity with a redeclaration lookup can only actually happen
|
||||
// in C++.
|
||||
// with a redeclaration lookup can only actually happen in C++.
|
||||
//
|
||||
// This is also okay for elaborated-type-specifiers, which is
|
||||
// technically forbidden by the current standard but which is
|
||||
|
@ -9172,7 +9172,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
|
||||
}
|
||||
|
||||
// Don't check the implicit member of the anonymous union type.
|
||||
// This is technically non-conformant, but sanity demands it.
|
||||
// This is technically non-conformant but supported, and we have a
|
||||
// diagnostic for this elsewhere.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -12256,7 +12257,7 @@ NamedDecl *Sema::BuildUsingDeclaration(
|
||||
// Unlike most lookups, we don't always want to hide tag
|
||||
// declarations: tag names are visible through the using declaration
|
||||
// even if hidden by ordinary names, *except* in a dependent context
|
||||
// where it's important for the sanity of two-phase lookup.
|
||||
// where they may be used by two-phase lookup.
|
||||
if (!IsInstantiation)
|
||||
R.setHideTags(false);
|
||||
|
||||
|
@ -11185,7 +11185,6 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
isScopedEnumerationType(RHSType)) {
|
||||
return InvalidOperands(Loc, LHS, RHS);
|
||||
}
|
||||
// Sanity-check shift operands
|
||||
DiagnoseBadShiftValues(*this, LHS, RHS, Loc, Opc, LHSType);
|
||||
|
||||
// "The type of the result is that of the promoted left operand."
|
||||
|
@ -1507,8 +1507,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
||||
ElemTy = Context.getBaseElementType(Ty);
|
||||
}
|
||||
|
||||
// There doesn't seem to be an explicit rule against this but sanity demands
|
||||
// we only construct objects with object types.
|
||||
// Only construct objects with object types.
|
||||
// There doesn't seem to be an explicit rule for this but functions are
|
||||
// not objects, so they cannot take initializers.
|
||||
if (Ty->isFunctionType())
|
||||
return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type)
|
||||
<< Ty << FullRange);
|
||||
|
@ -324,14 +324,14 @@ void LookupResult::configure() {
|
||||
}
|
||||
}
|
||||
|
||||
bool LookupResult::sanity() const {
|
||||
bool LookupResult::checkDebugAssumptions() const {
|
||||
// This function is never called by NDEBUG builds.
|
||||
assert(ResultKind != NotFound || Decls.size() == 0);
|
||||
assert(ResultKind != Found || Decls.size() == 1);
|
||||
assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
|
||||
(Decls.size() == 1 &&
|
||||
isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
|
||||
assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
|
||||
assert(ResultKind != FoundUnresolvedValue || checkUnresolved());
|
||||
assert(ResultKind != Ambiguous || Decls.size() > 1 ||
|
||||
(Decls.size() == 1 && (Ambiguity == AmbiguousBaseSubobjects ||
|
||||
Ambiguity == AmbiguousBaseSubobjectTypes)));
|
||||
|
@ -1517,7 +1517,7 @@ void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
|
||||
}
|
||||
|
||||
void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
|
||||
//char *strncat(char *restrict s1, const char *restrict s2, size_t n);
|
||||
// char *strncat(char *restrict s1, const char *restrict s2, size_t n);
|
||||
evalStrcpyCommon(C, CE,
|
||||
/* ReturnEnd = */ false,
|
||||
/* IsBounded = */ true,
|
||||
@ -2069,8 +2069,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
||||
}
|
||||
|
||||
void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const {
|
||||
//char *strsep(char **stringp, const char *delim);
|
||||
// Sanity: does the search string parameter match the return type?
|
||||
// char *strsep(char **stringp, const char *delim);
|
||||
// Verify whether the search string parameter matches the return type.
|
||||
SourceArgExpr SearchStrPtr = {CE->getArg(0), 0};
|
||||
|
||||
QualType CharPtrTy = SearchStrPtr.Expression->getType()->getPointeeType();
|
||||
|
@ -160,7 +160,7 @@ static bool isInMIGCall(CheckerContext &C) {
|
||||
if (Optional<AnyCall> AC = AnyCall::forDecl(D)) {
|
||||
// Even though there's a Sema warning when the return type of an annotated
|
||||
// function is not a kern_return_t, this warning isn't an error, so we need
|
||||
// an extra sanity check here.
|
||||
// an extra check here.
|
||||
// FIXME: AnyCall doesn't support blocks yet, so they remain unchecked
|
||||
// for now.
|
||||
if (!AC->getReturnType(C.getASTContext())
|
||||
|
@ -155,7 +155,7 @@ class StdLibraryFunctionsChecker
|
||||
protected:
|
||||
ArgNo ArgN; // Argument to which we apply the constraint.
|
||||
|
||||
/// Do polymorphic sanity check on the constraint.
|
||||
/// Do polymorphic validation check on the constraint.
|
||||
virtual bool checkSpecificValidity(const FunctionDecl *FD) const {
|
||||
return true;
|
||||
}
|
||||
@ -527,8 +527,8 @@ class StdLibraryFunctionsChecker
|
||||
}
|
||||
|
||||
private:
|
||||
// Once we know the exact type of the function then do sanity check on all
|
||||
// the given constraints.
|
||||
// Once we know the exact type of the function then do validation check on
|
||||
// all the given constraints.
|
||||
bool validateByConstraints(const FunctionDecl *FD) const {
|
||||
for (const ConstraintSet &Case : CaseConstraints)
|
||||
for (const ValueConstraintPtr &Constraint : Case)
|
||||
|
@ -182,8 +182,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
|
||||
ProgramStateRef state = C.getState();
|
||||
|
||||
if (CE->getNumArgs() < MinArgCount) {
|
||||
// The frontend should issue a warning for this case, so this is a sanity
|
||||
// check.
|
||||
// The frontend should issue a warning for this case. Just return.
|
||||
return;
|
||||
} else if (CE->getNumArgs() == MaxArgCount) {
|
||||
const Expr *Arg = CE->getArg(CreateModeArgIndex);
|
||||
@ -366,7 +365,7 @@ void UnixAPIPortabilityChecker::BasicAllocationCheck(CheckerContext &C,
|
||||
const unsigned numArgs,
|
||||
const unsigned sizeArg,
|
||||
const char *fn) const {
|
||||
// Sanity check for the correct number of arguments
|
||||
// Check for the correct number of arguments.
|
||||
if (CE->getNumArgs() != numArgs)
|
||||
return;
|
||||
|
||||
|
@ -1670,9 +1670,10 @@ PathDiagnosticPieceRef TrackConstraintBRVisitor::VisitNode(
|
||||
if (isUnderconstrained(PrevN)) {
|
||||
IsSatisfied = true;
|
||||
|
||||
// As a sanity check, make sure that the negation of the constraint
|
||||
// was infeasible in the current state. If it is feasible, we somehow
|
||||
// missed the transition point.
|
||||
// At this point, the negation of the constraint should be infeasible. If it
|
||||
// is feasible, make sure that the negation of the constrainti was
|
||||
// infeasible in the current state. If it is feasible, we somehow missed
|
||||
// the transition point.
|
||||
assert(!isUnderconstrained(N));
|
||||
|
||||
// We found the transition point for the constraint. We now need to
|
||||
|
@ -326,8 +326,8 @@ ProgramStateRef ExprEngine::createTemporaryRegionIfNeeded(
|
||||
}
|
||||
Result = InitWithAdjustments;
|
||||
} else {
|
||||
// We need to create a region no matter what. For sanity, make sure we don't
|
||||
// try to stuff a Loc into a non-pointer temporary region.
|
||||
// We need to create a region no matter what. Make sure we don't try to
|
||||
// stuff a Loc into a non-pointer temporary region.
|
||||
assert(!InitValWithAdjustments.getAs<Loc>() ||
|
||||
Loc::isLocType(Result->getType()) ||
|
||||
Result->getType()->isMemberPointerType());
|
||||
|
@ -249,7 +249,7 @@ static bool regionMatchesCXXRecordType(SVal V, QualType Ty) {
|
||||
}
|
||||
|
||||
SVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) {
|
||||
// Sanity check to avoid doing the wrong thing in the face of
|
||||
// Early return to avoid doing the wrong thing in the face of
|
||||
// reinterpret_cast.
|
||||
if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType()))
|
||||
return UnknownVal();
|
||||
|
@ -126,7 +126,7 @@ void syntax::Tree::replaceChildRangeLowLevel(Node *Begin, Node *End,
|
||||
for (auto *N = New; N; N = N->NextSibling) {
|
||||
assert(N->Parent == nullptr);
|
||||
assert(N->getRole() != NodeRole::Detached && "Roles must be set");
|
||||
// FIXME: sanity-check the role.
|
||||
// FIXME: validate the role.
|
||||
}
|
||||
|
||||
auto Reachable = [](Node *From, Node *N) {
|
||||
|
@ -1,196 +0,0 @@
|
||||
//===-- clang-nvlink-wrapper/ClangNvlinkWrapper.cpp - wrapper over nvlink-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This tool works as a wrapper over nvlink program. It transparently passes
|
||||
/// every input option and objects to nvlink except archive files. It reads
|
||||
/// each input archive file to extract archived cubin files as temporary files.
|
||||
/// These temp (*.cubin) files are passed to nvlink, because nvlink does not
|
||||
/// support linking of archive files implicitly.
|
||||
///
|
||||
/// During linking of heterogeneous device archive libraries, the
|
||||
/// clang-offload-bundler creates a device specific archive of cubin files.
|
||||
/// Such an archive is then passed to this tool to extract cubin files before
|
||||
/// passing to nvlink.
|
||||
///
|
||||
/// Example:
|
||||
/// clang-nvlink-wrapper -o a.out-openmp-nvptx64 /tmp/libTest-nvptx-sm_50.a
|
||||
///
|
||||
/// 1. Extract (libTest-nvptx-sm_50.a) => /tmp/a.cubin /tmp/b.cubin
|
||||
/// 2. nvlink -o a.out-openmp-nvptx64 /tmp/a.cubin /tmp/b.cubin
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
|
||||
|
||||
// Mark all our options with this category, everything else (except for -help)
|
||||
// will be hidden.
|
||||
static cl::OptionCategory
|
||||
ClangNvlinkWrapperCategory("clang-nvlink-wrapper options");
|
||||
|
||||
static cl::opt<std::string> NvlinkUserPath("nvlink-path",
|
||||
cl::desc("Path of nvlink binary"),
|
||||
cl::cat(ClangNvlinkWrapperCategory));
|
||||
|
||||
// Do not parse nvlink options
|
||||
static cl::list<std::string>
|
||||
NVArgs(cl::Sink, cl::desc("<options to be passed to nvlink>..."));
|
||||
|
||||
static Error runNVLink(std::string NVLinkPath,
|
||||
SmallVectorImpl<std::string> &Args) {
|
||||
std::vector<StringRef> NVLArgs;
|
||||
NVLArgs.push_back(NVLinkPath);
|
||||
for (auto &Arg : Args) {
|
||||
NVLArgs.push_back(Arg);
|
||||
}
|
||||
|
||||
if (sys::ExecuteAndWait(NVLinkPath.c_str(), NVLArgs))
|
||||
return createStringError(inconvertibleErrorCode(), "'nvlink' failed");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
static Error extractArchiveFiles(StringRef Filename,
|
||||
SmallVectorImpl<std::string> &Args,
|
||||
SmallVectorImpl<std::string> &TmpFiles) {
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
|
||||
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(Filename, false, false);
|
||||
if (std::error_code EC = BufOrErr.getError())
|
||||
return createFileError(Filename, EC);
|
||||
|
||||
ArchiveBuffers.push_back(std::move(*BufOrErr));
|
||||
Expected<std::unique_ptr<llvm::object::Archive>> LibOrErr =
|
||||
object::Archive::create(ArchiveBuffers.back()->getMemBufferRef());
|
||||
if (!LibOrErr)
|
||||
return LibOrErr.takeError();
|
||||
|
||||
auto Archive = std::move(*LibOrErr);
|
||||
|
||||
Error Err = Error::success();
|
||||
auto ChildEnd = Archive->child_end();
|
||||
for (auto ChildIter = Archive->child_begin(Err); ChildIter != ChildEnd;
|
||||
++ChildIter) {
|
||||
if (Err)
|
||||
return Err;
|
||||
auto ChildNameOrErr = (*ChildIter).getName();
|
||||
if (!ChildNameOrErr)
|
||||
return ChildNameOrErr.takeError();
|
||||
|
||||
StringRef ChildName = sys::path::filename(ChildNameOrErr.get());
|
||||
|
||||
auto ChildBufferRefOrErr = (*ChildIter).getMemoryBufferRef();
|
||||
if (!ChildBufferRefOrErr)
|
||||
return ChildBufferRefOrErr.takeError();
|
||||
|
||||
auto ChildBuffer =
|
||||
MemoryBuffer::getMemBuffer(ChildBufferRefOrErr.get(), false);
|
||||
auto ChildNameSplit = ChildName.split('.');
|
||||
|
||||
SmallString<16> Path;
|
||||
int FileDesc;
|
||||
if (std::error_code EC = sys::fs::createTemporaryFile(
|
||||
(ChildNameSplit.first), (ChildNameSplit.second), FileDesc, Path))
|
||||
return createFileError(ChildName, EC);
|
||||
|
||||
std::string TmpFileName(Path.str());
|
||||
Args.push_back(TmpFileName);
|
||||
TmpFiles.push_back(TmpFileName);
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(Path.c_str(), EC, sys::fs::OF_None);
|
||||
if (EC)
|
||||
return createFileError(TmpFileName, errc::io_error);
|
||||
OS << ChildBuffer->getBuffer();
|
||||
OS.close();
|
||||
}
|
||||
return Err;
|
||||
}
|
||||
|
||||
static Error cleanupTmpFiles(SmallVectorImpl<std::string> &TmpFiles) {
|
||||
for (auto &TmpFile : TmpFiles) {
|
||||
if (std::error_code EC = sys::fs::remove(TmpFile))
|
||||
return createFileError(TmpFile, errc::no_such_file_or_directory);
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
static void PrintVersion(raw_ostream &OS) {
|
||||
OS << clang::getClangToolFullVersion("clang-nvlink-wrapper") << '\n';
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
sys::PrintStackTraceOnErrorSignal(argv[0]);
|
||||
cl::SetVersionPrinter(PrintVersion);
|
||||
cl::HideUnrelatedOptions(ClangNvlinkWrapperCategory);
|
||||
cl::ParseCommandLineOptions(
|
||||
argc, argv,
|
||||
"A wrapper tool over nvlink program. It transparently passes every \n"
|
||||
"input option and objects to nvlink except archive files and path of \n"
|
||||
"nvlink binary. It reads each input archive file to extract archived \n"
|
||||
"cubin files as temporary files.\n");
|
||||
|
||||
if (Help) {
|
||||
cl::PrintHelpMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto reportError = [argv](Error E) {
|
||||
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
|
||||
exit(1);
|
||||
};
|
||||
|
||||
std::string NvlinkPath;
|
||||
SmallVector<const char *, 0> Argv(argv, argv + argc);
|
||||
SmallVector<std::string, 0> ArgvSubst;
|
||||
SmallVector<std::string, 0> TmpFiles;
|
||||
BumpPtrAllocator Alloc;
|
||||
StringSaver Saver(Alloc);
|
||||
cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv);
|
||||
|
||||
for (const std::string &Arg : NVArgs) {
|
||||
if (sys::path::extension(Arg) == ".a") {
|
||||
if (Error Err = extractArchiveFiles(Arg, ArgvSubst, TmpFiles))
|
||||
reportError(std::move(Err));
|
||||
} else {
|
||||
ArgvSubst.push_back(Arg);
|
||||
}
|
||||
}
|
||||
|
||||
NvlinkPath = NvlinkUserPath;
|
||||
|
||||
// If user hasn't specified nvlink binary then search it in PATH
|
||||
if (NvlinkPath.empty()) {
|
||||
ErrorOr<std::string> NvlinkPathErr = sys::findProgramByName("nvlink");
|
||||
if (!NvlinkPathErr) {
|
||||
reportError(createStringError(NvlinkPathErr.getError(),
|
||||
"unable to find 'nvlink' in path"));
|
||||
}
|
||||
NvlinkPath = NvlinkPathErr.get();
|
||||
}
|
||||
|
||||
if (Error Err = runNVLink(NvlinkPath, ArgvSubst))
|
||||
reportError(std::move(Err));
|
||||
if (Error Err = cleanupTmpFiles(TmpFiles))
|
||||
reportError(std::move(Err));
|
||||
|
||||
return 0;
|
||||
}
|
@ -799,8 +799,14 @@ _Bool __aarch64_have_lse_atomics
|
||||
#define HWCAP_ATOMICS (1 << 8)
|
||||
#endif
|
||||
static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) {
|
||||
#if defined(__FreeBSD__)
|
||||
unsigned long hwcap;
|
||||
int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
|
||||
__aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0;
|
||||
#else
|
||||
unsigned long hwcap = getauxval(AT_HWCAP);
|
||||
__aarch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0;
|
||||
#endif
|
||||
}
|
||||
#endif // defined(__has_include)
|
||||
#endif // __has_include(<sys/auxv.h>)
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_heap_until.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
@ -26,7 +27,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
return _VSTD::is_heap_until(__first, __last, __comp) == __last;
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp) == __last;
|
||||
}
|
||||
|
||||
template<class _RandomAccessIterator>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -19,9 +20,9 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
template <class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
|
||||
__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
difference_type __len = __last - __first;
|
||||
@ -46,13 +47,19 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template<class _RandomAccessIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_RandomAccessIterator
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
|
||||
{
|
||||
return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
|
||||
return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define _LIBCPP___ALGORITHM_IS_SORTED_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_sorted_until.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
@ -26,7 +27,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
bool
|
||||
is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp) == __last;
|
||||
}
|
||||
|
||||
template<class _ForwardIterator>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -19,9 +20,9 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
if (__first != __last)
|
||||
{
|
||||
@ -36,10 +37,16 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __co
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template<class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
||||
_ForwardIterator
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/max_element.h>
|
||||
#include <initializer_list>
|
||||
|
||||
@ -49,7 +50,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_Tp
|
||||
max(initializer_list<_Tp> __t, _Compare __comp)
|
||||
{
|
||||
return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return *_VSTD::__max_element<_Comp_ref>(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -19,11 +20,9 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
|
||||
"std::max_element requires a ForwardIterator");
|
||||
@ -37,11 +36,17 @@ max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__max_element<_Comp_ref>(__first, __last, __comp);
|
||||
}
|
||||
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_ForwardIterator
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::max_element(__first, __last,
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/min_element.h>
|
||||
#include <initializer_list>
|
||||
|
||||
@ -49,7 +50,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_Tp
|
||||
min(initializer_list<_Tp> __t, _Compare __comp)
|
||||
{
|
||||
return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return *_VSTD::__min_element<_Comp_ref>(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <__config>
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
@ -19,11 +20,9 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
|
||||
"std::min_element requires a ForwardIterator");
|
||||
@ -37,10 +36,16 @@ min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
|
||||
return _VSTD::__min_element<_Comp_ref>(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD_EXT inline
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
||||
_ForwardIterator
|
||||
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last)
|
||||
{
|
||||
return _VSTD::min_element(__first, __last,
|
||||
|
@ -149,7 +149,7 @@ __cpp_lib_syncbuf 201803L <syncstream>
|
||||
__cpp_lib_three_way_comparison 201907L <compare>
|
||||
__cpp_lib_to_address 201711L <memory>
|
||||
__cpp_lib_to_array 201907L <array>
|
||||
__cpp_lib_to_chars 201611L <utility>
|
||||
__cpp_lib_to_chars 201611L <charconv>
|
||||
__cpp_lib_to_underlying 202102L <utility>
|
||||
__cpp_lib_transformation_trait_aliases 201304L <type_traits>
|
||||
__cpp_lib_transparent_operators 201510L <functional> <memory>
|
||||
|
@ -13,10 +13,21 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
|
||||
#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKDYLIB_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace jitlink {
|
||||
|
||||
class JITLinkDylib {};
|
||||
class JITLinkDylib {
|
||||
public:
|
||||
JITLinkDylib(std::string Name) : Name(std::move(Name)) {}
|
||||
|
||||
/// Get the name for this JITLinkDylib.
|
||||
const std::string &getName() const { return Name; }
|
||||
|
||||
private:
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
} // end namespace jitlink
|
||||
} // end namespace llvm
|
||||
|
@ -927,17 +927,11 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
|
||||
friend class MaterializationResponsibility;
|
||||
public:
|
||||
|
||||
using AsynchronousSymbolQuerySet =
|
||||
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
|
||||
|
||||
JITDylib(const JITDylib &) = delete;
|
||||
JITDylib &operator=(const JITDylib &) = delete;
|
||||
JITDylib(JITDylib &&) = delete;
|
||||
JITDylib &operator=(JITDylib &&) = delete;
|
||||
|
||||
/// Get the name for this JITDylib.
|
||||
const std::string &getName() const { return JITDylibName; }
|
||||
|
||||
/// Get a reference to the ExecutionSession for this JITDylib.
|
||||
ExecutionSession &getExecutionSession() const { return ES; }
|
||||
|
||||
@ -1070,6 +1064,9 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
|
||||
std::vector<JITDylibSP> getReverseDFSLinkOrder();
|
||||
|
||||
private:
|
||||
using AsynchronousSymbolQuerySet =
|
||||
std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
|
||||
|
||||
using AsynchronousSymbolQueryList =
|
||||
std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
|
||||
|
||||
@ -1200,7 +1197,6 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
|
||||
failSymbols(FailedSymbolsWorklist);
|
||||
|
||||
ExecutionSession &ES;
|
||||
std::string JITDylibName;
|
||||
std::mutex GeneratorsMutex;
|
||||
bool Open = true;
|
||||
SymbolTable Symbols;
|
||||
|
@ -1289,17 +1289,15 @@ DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
|
||||
static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE,
|
||||
bool IncludeLinkageName = true) {
|
||||
SmallVector<StringRef, 2> Result;
|
||||
if (const char *Str = DIE.getName(DINameKind::ShortName))
|
||||
if (const char *Str = DIE.getShortName())
|
||||
Result.emplace_back(Str);
|
||||
else if (DIE.getTag() == dwarf::DW_TAG_namespace)
|
||||
Result.emplace_back("(anonymous namespace)");
|
||||
|
||||
if (IncludeLinkageName) {
|
||||
if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
|
||||
if (Result.empty() || Result[0] != Str)
|
||||
if (const char *Str = DIE.getLinkageName())
|
||||
Result.emplace_back(Str);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -1364,7 +1364,7 @@ Error JITDylib::remove(const SymbolNameSet &Names) {
|
||||
|
||||
void JITDylib::dump(raw_ostream &OS) {
|
||||
ES.runSessionLocked([&, this]() {
|
||||
OS << "JITDylib \"" << JITDylibName << "\" (ES: "
|
||||
OS << "JITDylib \"" << getName() << "\" (ES: "
|
||||
<< format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
|
||||
<< "Link order: " << LinkOrder << "\n"
|
||||
<< "Symbol table:\n";
|
||||
@ -1450,7 +1450,7 @@ JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
|
||||
}
|
||||
|
||||
JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
|
||||
: ES(ES), JITDylibName(std::move(Name)) {
|
||||
: JITLinkDylib(std::move(Name)), ES(ES) {
|
||||
LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(const Triple &TT,
|
||||
MaxInstLength = (TT.getArch() == Triple::amdgcn) ? 20 : 16;
|
||||
SeparatorString = "\n";
|
||||
CommentString = ";";
|
||||
PrivateLabelPrefix = "";
|
||||
InlineAsmStart = ";#ASMSTART";
|
||||
InlineAsmEnd = ";#ASMEND";
|
||||
|
||||
|
@ -718,7 +718,7 @@ Thumb2SizeReduce::ReduceSpecial(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||
case ARM::t2CMPrr: {
|
||||
// Try to reduce to the lo-reg only version first. Why there are two
|
||||
// versions of the instruction is a mystery.
|
||||
// It would be nice to just have two entries in the master table that
|
||||
// It would be nice to just have two entries in the main table that
|
||||
// are prioritized, but the table assumes a unique entry for each
|
||||
// source insn opcode. So for now, we hack a local entry record to use.
|
||||
static const ReduceEntry NarrowEntry =
|
||||
|
@ -44004,7 +44004,11 @@ static SDValue combineSetCCMOVMSK(SDValue EFLAGS, X86::CondCode &CC,
|
||||
// signbits extend down to all the sub-elements as well.
|
||||
// Calling MOVMSK with the wider type, avoiding the bitcast, helps expose
|
||||
// potential SimplifyDemandedBits/Elts cases.
|
||||
if (Vec.getOpcode() == ISD::BITCAST) {
|
||||
// If we looked through a truncate that discard bits, we can't do this
|
||||
// transform.
|
||||
// FIXME: We could do this transform for truncates that discarded bits by
|
||||
// inserting an AND mask between the new MOVMSK and the CMP.
|
||||
if (Vec.getOpcode() == ISD::BITCAST && NumElts <= CmpBits) {
|
||||
SDValue BC = peekThroughBitcasts(Vec);
|
||||
MVT BCVT = BC.getSimpleValueType();
|
||||
unsigned BCNumElts = BCVT.getVectorNumElements();
|
||||
|
@ -692,7 +692,7 @@ void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
|
||||
|
||||
IRBuilder<> Builder(Inc);
|
||||
uint64_t Index = Inc->getIndex()->getZExtValue();
|
||||
Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(),
|
||||
Value *Addr = Builder.CreateConstInBoundsGEP2_32(Counters->getValueType(),
|
||||
Counters, 0, Index);
|
||||
|
||||
if (isRuntimeCounterRelocationEnabled()) {
|
||||
|
@ -58,17 +58,13 @@ std::unique_ptr<Module> llvm::CloneModule(
|
||||
// new module. Here we add them to the VMap and to the new Module. We
|
||||
// don't worry about attributes or initializers, they will come later.
|
||||
//
|
||||
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I) {
|
||||
GlobalVariable *GV = new GlobalVariable(*New,
|
||||
I->getValueType(),
|
||||
I->isConstant(), I->getLinkage(),
|
||||
(Constant*) nullptr, I->getName(),
|
||||
(GlobalVariable*) nullptr,
|
||||
I->getThreadLocalMode(),
|
||||
I->getType()->getAddressSpace());
|
||||
GV->copyAttributesFrom(&*I);
|
||||
VMap[&*I] = GV;
|
||||
for (const GlobalVariable &I : M.globals()) {
|
||||
GlobalVariable *NewGV = new GlobalVariable(
|
||||
*New, I.getValueType(), I.isConstant(), I.getLinkage(),
|
||||
(Constant *)nullptr, I.getName(), (GlobalVariable *)nullptr,
|
||||
I.getThreadLocalMode(), I.getType()->getAddressSpace());
|
||||
NewGV->copyAttributesFrom(&I);
|
||||
VMap[&I] = NewGV;
|
||||
}
|
||||
|
||||
// Loop over the functions in the module, making external functions as before
|
||||
@ -81,34 +77,33 @@ std::unique_ptr<Module> llvm::CloneModule(
|
||||
}
|
||||
|
||||
// Loop over the aliases in the module
|
||||
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||
I != E; ++I) {
|
||||
if (!ShouldCloneDefinition(&*I)) {
|
||||
for (const GlobalAlias &I : M.aliases()) {
|
||||
if (!ShouldCloneDefinition(&I)) {
|
||||
// An alias cannot act as an external reference, so we need to create
|
||||
// either a function or a global variable depending on the value type.
|
||||
// FIXME: Once pointee types are gone we can probably pick one or the
|
||||
// other.
|
||||
GlobalValue *GV;
|
||||
if (I->getValueType()->isFunctionTy())
|
||||
GV = Function::Create(cast<FunctionType>(I->getValueType()),
|
||||
GlobalValue::ExternalLinkage,
|
||||
I->getAddressSpace(), I->getName(), New.get());
|
||||
if (I.getValueType()->isFunctionTy())
|
||||
GV = Function::Create(cast<FunctionType>(I.getValueType()),
|
||||
GlobalValue::ExternalLinkage, I.getAddressSpace(),
|
||||
I.getName(), New.get());
|
||||
else
|
||||
GV = new GlobalVariable(
|
||||
*New, I->getValueType(), false, GlobalValue::ExternalLinkage,
|
||||
nullptr, I->getName(), nullptr,
|
||||
I->getThreadLocalMode(), I->getType()->getAddressSpace());
|
||||
VMap[&*I] = GV;
|
||||
GV = new GlobalVariable(*New, I.getValueType(), false,
|
||||
GlobalValue::ExternalLinkage, nullptr,
|
||||
I.getName(), nullptr, I.getThreadLocalMode(),
|
||||
I.getType()->getAddressSpace());
|
||||
VMap[&I] = GV;
|
||||
// We do not copy attributes (mainly because copying between different
|
||||
// kinds of globals is forbidden), but this is generally not required for
|
||||
// correctness.
|
||||
continue;
|
||||
}
|
||||
auto *GA = GlobalAlias::create(I->getValueType(),
|
||||
I->getType()->getPointerAddressSpace(),
|
||||
I->getLinkage(), I->getName(), New.get());
|
||||
GA->copyAttributesFrom(&*I);
|
||||
VMap[&*I] = GA;
|
||||
auto *GA = GlobalAlias::create(I.getValueType(),
|
||||
I.getType()->getPointerAddressSpace(),
|
||||
I.getLinkage(), I.getName(), New.get());
|
||||
GA->copyAttributesFrom(&I);
|
||||
VMap[&I] = GA;
|
||||
}
|
||||
|
||||
// Now that all of the things that global variable initializer can refer to
|
||||
@ -153,10 +148,9 @@ std::unique_ptr<Module> llvm::CloneModule(
|
||||
}
|
||||
|
||||
Function::arg_iterator DestI = F->arg_begin();
|
||||
for (Function::const_arg_iterator J = I.arg_begin(); J != I.arg_end();
|
||||
++J) {
|
||||
DestI->setName(J->getName());
|
||||
VMap[&*J] = &*DestI++;
|
||||
for (const Argument &J : I.args()) {
|
||||
DestI->setName(J.getName());
|
||||
VMap[&J] = &*DestI++;
|
||||
}
|
||||
|
||||
SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
|
||||
@ -170,21 +164,17 @@ std::unique_ptr<Module> llvm::CloneModule(
|
||||
}
|
||||
|
||||
// And aliases
|
||||
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||
I != E; ++I) {
|
||||
for (const GlobalAlias &I : M.aliases()) {
|
||||
// We already dealt with undefined aliases above.
|
||||
if (!ShouldCloneDefinition(&*I))
|
||||
if (!ShouldCloneDefinition(&I))
|
||||
continue;
|
||||
GlobalAlias *GA = cast<GlobalAlias>(VMap[&*I]);
|
||||
if (const Constant *C = I->getAliasee())
|
||||
GlobalAlias *GA = cast<GlobalAlias>(VMap[&I]);
|
||||
if (const Constant *C = I.getAliasee())
|
||||
GA->setAliasee(MapValue(C, VMap));
|
||||
}
|
||||
|
||||
// And named metadata....
|
||||
for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
|
||||
E = M.named_metadata_end();
|
||||
I != E; ++I) {
|
||||
const NamedMDNode &NMD = *I;
|
||||
for (const NamedMDNode &NMD : M.named_metadata()) {
|
||||
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
|
||||
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
|
||||
NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap));
|
||||
|
@ -285,9 +285,8 @@ bool Evaluator::getFormalParams(CallBase &CB, Function *F,
|
||||
}
|
||||
|
||||
auto ArgI = CB.arg_begin();
|
||||
for (auto ParI = FTy->param_begin(), ParE = FTy->param_end(); ParI != ParE;
|
||||
++ParI) {
|
||||
auto *ArgC = ConstantFoldLoadThroughBitcast(getVal(*ArgI), *ParI, DL);
|
||||
for (Type *PTy : FTy->params()) {
|
||||
auto *ArgC = ConstantFoldLoadThroughBitcast(getVal(*ArgI), PTy, DL);
|
||||
if (!ArgC) {
|
||||
LLVM_DEBUG(dbgs() << "Can not convert function argument.\n");
|
||||
return false;
|
||||
|
@ -293,9 +293,8 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
|
||||
// L is now a subloop of our outer loop.
|
||||
NewOuter->addChildLoop(L);
|
||||
|
||||
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
|
||||
I != E; ++I)
|
||||
NewOuter->addBlockEntry(*I);
|
||||
for (BasicBlock *BB : L->blocks())
|
||||
NewOuter->addBlockEntry(BB);
|
||||
|
||||
// Now reset the header in L, which had been moved by
|
||||
// SplitBlockPredecessors for the outer loop.
|
||||
@ -496,12 +495,12 @@ static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist,
|
||||
// predecessors that are not in the loop. This is not valid for natural
|
||||
// loops, but can occur if the blocks are unreachable. Since they are
|
||||
// unreachable we can just shamelessly delete those CFG edges!
|
||||
for (Loop::block_iterator BB = L->block_begin(), E = L->block_end();
|
||||
BB != E; ++BB) {
|
||||
if (*BB == L->getHeader()) continue;
|
||||
for (BasicBlock *BB : L->blocks()) {
|
||||
if (BB == L->getHeader())
|
||||
continue;
|
||||
|
||||
SmallPtrSet<BasicBlock*, 4> BadPreds;
|
||||
for (BasicBlock *P : predecessors(*BB))
|
||||
for (BasicBlock *P : predecessors(BB))
|
||||
if (!L->contains(P))
|
||||
BadPreds.insert(P);
|
||||
|
||||
|
@ -663,9 +663,8 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
|
||||
// about ordering because we already dropped the references.
|
||||
// NOTE: This iteration is safe because erasing the block does not remove
|
||||
// its entry from the loop's block list. We do that in the next section.
|
||||
for (Loop::block_iterator LpI = L->block_begin(), LpE = L->block_end();
|
||||
LpI != LpE; ++LpI)
|
||||
(*LpI)->eraseFromParent();
|
||||
for (BasicBlock *BB : L->blocks())
|
||||
BB->eraseFromParent();
|
||||
|
||||
// Finally, the blocks from loopinfo. This has to happen late because
|
||||
// otherwise our loop iterators won't work.
|
||||
@ -1501,10 +1500,9 @@ Loop *llvm::cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
|
||||
LPM->addLoop(New);
|
||||
|
||||
// Add all of the blocks in L to the new loop.
|
||||
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
|
||||
I != E; ++I)
|
||||
if (LI->getLoopFor(*I) == L)
|
||||
New.addBasicBlockToLoop(cast<BasicBlock>(VM[*I]), *LI);
|
||||
for (BasicBlock *BB : L->blocks())
|
||||
if (LI->getLoopFor(BB) == L)
|
||||
New.addBasicBlockToLoop(cast<BasicBlock>(VM[BB]), *LI);
|
||||
|
||||
// Add all of the subloops to the new loop.
|
||||
for (Loop *I : *L)
|
||||
|
@ -92,12 +92,12 @@ void MetaRename(Module &M,
|
||||
Renamer renamer(randSeed);
|
||||
|
||||
// Rename all aliases
|
||||
for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) {
|
||||
StringRef Name = AI->getName();
|
||||
for (GlobalAlias &GA : M.aliases()) {
|
||||
StringRef Name = GA.getName();
|
||||
if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
|
||||
continue;
|
||||
|
||||
AI->setName("alias");
|
||||
GA.setName("alias");
|
||||
}
|
||||
|
||||
// Rename all global variables
|
||||
|
@ -201,19 +201,7 @@ static int analyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr,
|
||||
// (issue a smaller load then merge the bits in) but this seems unlikely to be
|
||||
// valuable.
|
||||
if (StoreOffset > LoadOffset ||
|
||||
StoreOffset + StoreSize < LoadOffset + LoadSize)
|
||||
return -1;
|
||||
|
||||
// If the load and store are to the exact same address, they should have been
|
||||
// a must alias. AA must have gotten confused.
|
||||
// FIXME: Study to see if/when this happens. One case is forwarding a memset
|
||||
// to a load from the base of the memset.
|
||||
|
||||
// If the load and store don't overlap at all, the store doesn't provide
|
||||
// anything to the load. In this case, they really don't alias at all, AA
|
||||
// must have gotten confused. The if statement above ensure the condition
|
||||
// that StoreOffset <= LoadOffset.
|
||||
if (StoreOffset + int64_t(StoreSize) <= LoadOffset)
|
||||
StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
|
||||
return -1;
|
||||
|
||||
// Okay, we can do this transformation. Return the number of bytes into the
|
||||
|
Loading…
Reference in New Issue
Block a user