Skip to content

Commit

Permalink
Merge pull request #50 from schweitzpgi/release_70
Browse files Browse the repository at this point in the history
merge latest from llvm mirror to Release 70
  • Loading branch information
sscalpone authored Dec 18, 2018
2 parents 4a9339f + cc5aa71 commit 24bd54d
Show file tree
Hide file tree
Showing 34 changed files with 580 additions and 281 deletions.
1 change: 0 additions & 1 deletion include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,6 @@ class DeclContextLookupResult {
value_type SingleElement;

public:
iterator() = default;
explicit iterator(pointer Pos, value_type Single = nullptr)
: IteratorBase(Pos), SingleElement(Single) {}

Expand Down
33 changes: 33 additions & 0 deletions include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,39 @@ def Target : InheritableAttr {
return parse(getFeaturesStr());
}

StringRef getArchitecture() const {
StringRef Features = getFeaturesStr();
if (Features == "default") return {};

SmallVector<StringRef, 1> AttrFeatures;
Features.split(AttrFeatures, ",");

for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
if (Feature.startswith("arch="))
return Feature.drop_front(sizeof("arch=") - 1);
}
return "";
}

// Gets the list of features as simple string-refs with no +/- or 'no-'.
// Only adds the items to 'Out' that are additions.
void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
StringRef Features = getFeaturesStr();
if (Features == "default") return;

SmallVector<StringRef, 1> AttrFeatures;
Features.split(AttrFeatures, ",");

for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();

if (!Feature.startswith("no-") && !Feature.startswith("arch=") &&
!Feature.startswith("fpmath=") && !Feature.startswith("tune="))
Out.push_back(Feature);
}
}

template<class Compare>
ParsedTargetAttr parse(Compare cmp) const {
ParsedTargetAttr Attrs = parse();
Expand Down
2 changes: 1 addition & 1 deletion include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3364,7 +3364,7 @@ def IFuncDocs : Documentation {
let Content = [{
``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function.

The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer.
The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should return a pointer.

The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline.

Expand Down
2 changes: 1 addition & 1 deletion include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def warn_option_invalid_ocl_version : Warning<
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;

def warn_stdlibcxx_not_found : Warning<
"include path for stdlibc++ headers not found; pass '-std=libc++' on the "
"include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the "
"command line to use the libc++ standard library instead">,
InGroup<DiagGroup<"stdlibcxx-not-found">>;
}
2 changes: 0 additions & 2 deletions include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -2857,8 +2857,6 @@ def err_cyclic_alias : Error<
"%select{alias|ifunc}0 definition is part of a cycle">;
def err_ifunc_resolver_return : Error<
"ifunc resolver function must return a pointer">;
def err_ifunc_resolver_params : Error<
"ifunc resolver function must have no parameters">;
def warn_attribute_wrong_decl_type_str : Warning<
"%0 attribute only applies to %1">, InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type_str : Error<
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9734,6 +9734,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return true;

if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// Multiversioned functions always have to be emitted, because they are used
// by the resolver.
if (FD->isMultiVersion())
return true;
// Forward declarations aren't required.
if (!FD->doesThisDeclarationHaveABody())
return FD->doesDeclarationForceExternallyVisibleDefinition();
Expand Down
24 changes: 22 additions & 2 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// If we're paying attention to global visibility, apply
// -finline-visibility-hidden if this is an inline method.
if (useInlineVisibilityHidden(D))
LV.mergeVisibility(HiddenVisibility, true);
LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
}
}

Expand Down Expand Up @@ -915,7 +915,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D,
// Note that we do this before merging information about
// the class visibility.
if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D))
LV.mergeVisibility(HiddenVisibility, true);
LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
}

// If this class member has an explicit visibility attribute, the only
Expand Down Expand Up @@ -1262,7 +1262,27 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
!isTemplateInstantiation(FD->getTemplateSpecializationKind()))
return LinkageInfo::none();

// If a function is hidden by -fvisibility-inlines-hidden option and
// is not explicitly attributed as a hidden function,
// we should not make static local variables in the function hidden.
LV = getLVForDecl(FD, computation);
if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
!LV.isVisibilityExplicit()) {
assert(cast<VarDecl>(D)->isStaticLocal());
// If this was an implicitly hidden inline method, check again for
// explicit visibility on the parent class, and use that for static locals
// if present.
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
LV = getLVForDecl(MD->getParent(), computation);
if (!LV.isVisibilityExplicit()) {
Visibility globalVisibility =
computation.isValueVisibility()
? Context.getLangOpts().getValueVisibilityMode()
: Context.getLangOpts().getTypeVisibilityMode();
return LinkageInfo(VisibleNoLinkage, globalVisibility,
/*visibilityExplicit=*/false);
}
}
}
if (!isExternallyVisible(LV.getLinkage()))
return LinkageInfo::none();
Expand Down
80 changes: 21 additions & 59 deletions lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2359,91 +2359,53 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
CGM.getSanStats().create(IRB, SSK);
}

llvm::Value *CodeGenFunction::FormResolverCondition(
const TargetMultiVersionResolverOption &RO) {
llvm::Value *TrueCondition = nullptr;
if (!RO.ParsedAttribute.Architecture.empty())
TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture);

if (!RO.ParsedAttribute.Features.empty()) {
SmallVector<StringRef, 8> FeatureList;
llvm::for_each(RO.ParsedAttribute.Features,
[&FeatureList](const std::string &Feature) {
FeatureList.push_back(StringRef{Feature}.substr(1));
});
llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList);
TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp)
: FeatureCmp;
}
return TrueCondition;
}

void CodeGenFunction::EmitTargetMultiVersionResolver(
llvm::Function *Resolver,
ArrayRef<TargetMultiVersionResolverOption> Options) {
assert((getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86 ||
getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86_64) &&
"Only implemented for x86 targets");

// Main function's basic block.
llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);
Builder.SetInsertPoint(CurBlock);
EmitX86CpuInit();
llvm::Value *
CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) {
llvm::Value *Condition = nullptr;

llvm::Function *DefaultFunc = nullptr;
for (const TargetMultiVersionResolverOption &RO : Options) {
Builder.SetInsertPoint(CurBlock);
llvm::Value *TrueCondition = FormResolverCondition(RO);
if (!RO.Conditions.Architecture.empty())
Condition = EmitX86CpuIs(RO.Conditions.Architecture);

if (!TrueCondition) {
DefaultFunc = RO.Function;
} else {
llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver);
llvm::IRBuilder<> RetBuilder(RetBlock);
RetBuilder.CreateRet(RO.Function);
CurBlock = createBasicBlock("ro_else", Resolver);
Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
}
if (!RO.Conditions.Features.empty()) {
llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
Condition =
Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond;
}

assert(DefaultFunc && "No default version?");
// Emit return from the 'else-ist' block.
Builder.SetInsertPoint(CurBlock);
Builder.CreateRet(DefaultFunc);
return Condition;
}

void CodeGenFunction::EmitCPUDispatchMultiVersionResolver(
llvm::Function *Resolver,
ArrayRef<CPUDispatchMultiVersionResolverOption> Options) {
void CodeGenFunction::EmitMultiVersionResolver(
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
assert((getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86 ||
getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86_64) &&
"Only implemented for x86 targets");

// Main function's basic block.
llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
Builder.SetInsertPoint(CurBlock);
EmitX86CpuInit();

for (const CPUDispatchMultiVersionResolverOption &RO : Options) {
for (const MultiVersionResolverOption &RO : Options) {
Builder.SetInsertPoint(CurBlock);
llvm::Value *Condition = FormResolverCondition(RO);

// "generic" case should catch-all.
if (RO.FeatureMask == 0) {
// The 'default' or 'generic' case.
if (!Condition) {
assert(&RO == Options.end() - 1 &&
"Default or Generic case must be last");
Builder.CreateRet(RO.Function);
return;
}

llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
llvm::IRBuilder<> RetBuilder(RetBlock);
RetBuilder.CreateRet(RO.Function);
CurBlock = createBasicBlock("resolver_else", Resolver);
llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask);
Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
Builder.CreateCondBr(Condition, RetBlock, CurBlock);
}

// If no generic/default, emit an unreachable.
Builder.SetInsertPoint(CurBlock);
llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
TrapCall->setDoesNotReturn();
Expand Down
41 changes: 18 additions & 23 deletions lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4247,30 +4247,26 @@ class CodeGenFunction : public CodeGenTypeCache {

void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);

struct TargetMultiVersionResolverOption {
struct MultiVersionResolverOption {
llvm::Function *Function;
TargetAttr::ParsedTargetAttr ParsedAttribute;
unsigned Priority;
TargetMultiVersionResolverOption(
const TargetInfo &TargInfo, llvm::Function *F,
const clang::TargetAttr::ParsedTargetAttr &PT)
: Function(F), ParsedAttribute(PT), Priority(0u) {
for (StringRef Feat : PT.Features)
Priority = std::max(Priority,
TargInfo.multiVersionSortPriority(Feat.substr(1)));

if (!PT.Architecture.empty())
Priority = std::max(Priority,
TargInfo.multiVersionSortPriority(PT.Architecture));
}
struct Conds {
StringRef Architecture;
llvm::SmallVector<StringRef, 8> Features;

bool operator>(const TargetMultiVersionResolverOption &Other) const {
return Priority > Other.Priority;
}
Conds(StringRef Arch, ArrayRef<StringRef> Feats)
: Architecture(Arch), Features(Feats.begin(), Feats.end()) {}
} Conditions;

MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
ArrayRef<StringRef> Feats)
: Function(F), Conditions(Arch, Feats) {}
};
void EmitTargetMultiVersionResolver(
llvm::Function *Resolver,
ArrayRef<TargetMultiVersionResolverOption> Options);

// Emits the body of a multiversion function's resolver. Assumes that the
// options are already sorted in the proper order, with the 'default' option
// last (if it exists).
void EmitMultiVersionResolver(llvm::Function *Resolver,
ArrayRef<MultiVersionResolverOption> Options);

struct CPUDispatchMultiVersionResolverOption {
llvm::Function *Function;
Expand Down Expand Up @@ -4306,8 +4302,7 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
llvm::Value *EmitX86CpuSupports(uint32_t Mask);
llvm::Value *EmitX86CpuInit();
llvm::Value *
FormResolverCondition(const TargetMultiVersionResolverOption &RO);
llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO);
};

inline DominatingLLVMValue::saved_type
Expand Down
Loading

0 comments on commit 24bd54d

Please sign in to comment.