Skip to content

Member lookup macro expansion performance #66257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions include/swift/AST/NameLookupRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "swift/AST/FileUnit.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/TypeOrExtensionDecl.h"
#include "swift/Basic/Statistic.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/TinyPtrVector.h"
Expand All @@ -37,6 +38,7 @@ class GenericContext;
class GenericParamList;
class LookupResult;
enum class NLKind;
class PotentialMacroExpansions;
class SourceLoc;
class TypeAliasDecl;
class TypeDecl;
Expand Down Expand Up @@ -889,6 +891,27 @@ class HasDynamicCallableAttributeRequest
bool isCached() const { return true; }
};

/// Determine the potential macro expansions for a given type or extension
/// context.
class PotentialMacroExpansionsInContextRequest
: public SimpleRequest<
PotentialMacroExpansionsInContextRequest,
PotentialMacroExpansions(TypeOrExtensionDecl),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
PotentialMacroExpansions evaluate(
Evaluator &evaluator, TypeOrExtensionDecl container) const;

public:
bool isCached() const { return true; }
};

#define SWIFT_TYPEID_ZONE NameLookup
#define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/NameLookupTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,5 @@ SWIFT_REQUEST(NameLookup, HasDynamicMemberLookupAttributeRequest,
bool(NominalTypeDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, HasDynamicCallableAttributeRequest,
bool(NominalTypeDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, PotentialMacroExpansionsInContextRequest,
PotentialMacroExpansions(TypeOrExtension), Cached, NoLocationInfo)
186 changes: 186 additions & 0 deletions include/swift/AST/PotentialMacroExpansions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
//===--- PotentialMacroExpansions.h -----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines a structure (\c PotentialMacroExpansions) to track
// potential macro expansions within a given context.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_POTENTIAL_MACRO_EXPANSIONS_H
#define SWIFT_AST_POTENTIAL_MACRO_EXPANSIONS_H

#include "swift/AST/Identifier.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"

namespace swift {

/// Describes the potential macro expansions within a given type or
/// extension context.
class PotentialMacroExpansions {
enum {
/// Whether there are any expanded macros.
AnyExpandedMacros = 0x01,

/// Whether any of the expanded macros introduces arbitrary names.
IntroducesArbitraryNames = 0x02,
};

using NameSet = llvm::SmallPtrSet<DeclName, 4>;

/// Storage for the set of potential macro expansions.
llvm::PointerIntPair<NameSet *, 2, unsigned> Storage;

/// Retrieve a pointer to the name set if there is one.
const NameSet *getIntroducedNamesIfAvailable() const {
return Storage.getPointer();
}

/// Get or create a nam
NameSet &getOrCreateIntroducedNames() {
if (auto nameSet = Storage.getPointer())
return *nameSet;

// Allocate a new set of introduced names.
auto nameSet = new NameSet();
Storage.setPointer(nameSet);
return *nameSet;
}

public:
PotentialMacroExpansions() : Storage() { }

PotentialMacroExpansions(const PotentialMacroExpansions &other)
: Storage(nullptr, other.Storage.getInt())
{
if (auto otherNameSet = other.getIntroducedNamesIfAvailable()) {
Storage.setPointer(new NameSet(*otherNameSet));
}
}

PotentialMacroExpansions(PotentialMacroExpansions &&other)
: Storage(other.Storage)
{
other.Storage.setPointer(nullptr);
}

PotentialMacroExpansions &operator=(const PotentialMacroExpansions &other) {
PotentialMacroExpansions tmp(other);
swap(tmp, *this);
return *this;
}

PotentialMacroExpansions &operator=(PotentialMacroExpansions &&other) {
if (&other != this) {
Storage = other.Storage;
other.Storage.setPointer(nullptr);
}
return *this;
}

~PotentialMacroExpansions() {
delete getIntroducedNamesIfAvailable();
}

/// Whether there are any expanded macros in this context.
explicit operator bool() const { return hasAnyExpandedMacro(); }

/// Whether there are any expanded macros in this context.
bool hasAnyExpandedMacro() const {
return Storage.getInt() & AnyExpandedMacros;
}

/// Note that we have expanded a macro.
void noteExpandedMacro() {
Storage.setInt(Storage.getInt() | AnyExpandedMacros);
}

/// Whether any expanded macro introduces arbitrary names.
bool introducesArbitraryNames() const {
return Storage.getInt() & IntroducesArbitraryNames;
}

/// Note that a macro expanded here introduced arbitrary names.
void noteIntroducesArbitraryNames() {
Storage.setInt(Storage.getInt() | IntroducesArbitraryNames);
}

/// Add a new introduced macro name.
void addIntroducedMacroName(DeclName name) {
getOrCreateIntroducedNames().insert(name.getBaseName());
}

/// Determine whether one should expand any macros in this context because
/// they could introduce a declaration with the given name.
bool shouldExpandForName(DeclName name) const {
// If any macro produces arbitraty names, we need to expand it.
if (introducesArbitraryNames())
return true;

auto introducedNames = getIntroducedNamesIfAvailable();
if (!introducedNames)
return false;

return introducedNames->count(name.getBaseName());
}

friend bool operator==(const PotentialMacroExpansions &lhs,
const PotentialMacroExpansions &rhs) {
// Check has-any-expanded-macro and introduces-arbitrary-names together.
if (lhs.Storage.getInt() != rhs.Storage.getInt())
return false;

// If they introduced arbitrary names, ignore the name sets... they are
// the same.
if (lhs.introducesArbitraryNames())
return true;

// Both expanded macros and did not introduce arbitrary names, so we need
// to check the actual names.
auto lhsIntroducedNames = lhs.getIntroducedNamesIfAvailable();
auto rhsIntroducedNames = rhs.getIntroducedNamesIfAvailable();

auto lhsIntroducedNamesCount =
lhsIntroducedNames ? lhsIntroducedNames->size() : 0;
auto rhsIntroducedNamesCount =
rhsIntroducedNames ? rhsIntroducedNames->size() : 0;
if (lhsIntroducedNamesCount != rhsIntroducedNamesCount)
return false;

// Check whether both are empty.
if (lhsIntroducedNamesCount == 0)
return true;

// Make sure all of the names of one are in the other.
for (auto lhsName : *lhsIntroducedNames) {
if (rhsIntroducedNames->count(lhsName) == 0)
return false;
}

return true;
}

friend bool operator!=(const PotentialMacroExpansions &lhs,
const PotentialMacroExpansions &rhs) {
return !(lhs == rhs);
}

friend void swap(
PotentialMacroExpansions &lhs, PotentialMacroExpansions &rhs) {
auto tmpStorage = lhs.Storage;
lhs.Storage = rhs.Storage;
rhs.Storage = tmpStorage;
}
};

}

#endif // SWIFT_AST_POTENTIAL_MACRO_EXPANSIONS_H
23 changes: 20 additions & 3 deletions include/swift/AST/TypeOrExtensionDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@
#include "swift/AST/TypeAlignments.h"
#include "llvm/ADT/PointerUnion.h"

namespace llvm {
class raw_ostream;
}

namespace swift {

class SourceLoc;
class DeclContext;
class IterableDeclContext;

Expand Down Expand Up @@ -51,11 +56,23 @@ struct TypeOrExtensionDecl {
bool isNull() const;
explicit operator bool() const { return !isNull(); }

bool operator==(TypeOrExtensionDecl rhs) { return Decl == rhs.Decl; }
bool operator!=(TypeOrExtensionDecl rhs) { return Decl != rhs.Decl; }
bool operator<(TypeOrExtensionDecl rhs) { return Decl < rhs.Decl; }
friend bool operator==(TypeOrExtensionDecl lhs, TypeOrExtensionDecl rhs) {
return lhs.Decl == rhs.Decl;
}
friend bool operator!=(TypeOrExtensionDecl lhs, TypeOrExtensionDecl rhs) {
return lhs.Decl != rhs.Decl;
}
friend bool operator<(TypeOrExtensionDecl lhs, TypeOrExtensionDecl rhs) {
return lhs.Decl < rhs.Decl;
}
friend llvm::hash_code hash_value(TypeOrExtensionDecl decl) {
return llvm::hash_value(decl.getAsDecl());
}
};

void simple_display(llvm::raw_ostream &out, TypeOrExtensionDecl container);
SourceLoc extractNearestSourceLoc(TypeOrExtensionDecl container);

} // end namespace swift

#endif
10 changes: 10 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10123,6 +10123,11 @@ void swift::simple_display(llvm::raw_ostream &out,
out << " }";
}

void swift::simple_display(llvm::raw_ostream &out,
TypeOrExtensionDecl container) {
simple_display(out, container.getAsDecl());
}

void swift::simple_display(llvm::raw_ostream &out, const ValueDecl *decl) {
if (decl) decl->dumpRef(out);
else out << "(null)";
Expand Down Expand Up @@ -10155,6 +10160,11 @@ SourceLoc swift::extractNearestSourceLoc(const Decl *decl) {
return extractNearestSourceLoc(decl->getDeclContext());
}

SourceLoc swift::extractNearestSourceLoc(TypeOrExtensionDecl container) {
return extractNearestSourceLoc(container.Decl);
}


Optional<BodyAndFingerprint>
ParseAbstractFunctionBodyRequest::getCachedResult() const {
using BodyKind = AbstractFunctionDecl::BodyKind;
Expand Down
Loading