Skip to content

Commit

Permalink
Merged master:6239d670018 into amd-gfx:c08830d801d
Browse files Browse the repository at this point in the history
Local branch amd-gfx c08830d Merged master:59491b208f3 into amd-gfx:66793841c4c
Remote branch master 6239d67 [GISel][NFC]: Add unit test for clarifying CSE behavior
  • Loading branch information
Sw authored and Sw committed Jun 11, 2020
2 parents c08830d + 6239d67 commit 78c4105
Show file tree
Hide file tree
Showing 109 changed files with 4,947 additions and 461 deletions.
11 changes: 10 additions & 1 deletion clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2509,7 +2509,11 @@ class UnaryExprOrTypeTraitExpr : public Expr {
SourceLocation rp)
: Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary),
OpLoc(op), RParenLoc(rp) {
assert(ExprKind <= UETT_Last && "invalid enum value!");
UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
assert(static_cast<unsigned>(ExprKind) ==
UnaryExprOrTypeTraitExprBits.Kind &&
"UnaryExprOrTypeTraitExprBits.Kind overflow!");
UnaryExprOrTypeTraitExprBits.IsType = true;
Argument.Ty = TInfo;
setDependence(computeDependence(this));
Expand All @@ -2526,7 +2530,12 @@ class UnaryExprOrTypeTraitExpr : public Expr {
UnaryExprOrTypeTrait getKind() const {
return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
}
void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;}
void setKind(UnaryExprOrTypeTrait K) {
assert(K <= UETT_Last && "invalid enum value!");
UnaryExprOrTypeTraitExprBits.Kind = K;
assert(static_cast<unsigned>(K) == UnaryExprOrTypeTraitExprBits.Kind &&
"UnaryExprOrTypeTraitExprBits.Kind overflow!");
}

bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
QualType getArgumentType() const {
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -2749,6 +2749,8 @@ class ArrayTypeTraitExpr : public Expr {
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att),
Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
QueriedType(queried) {
assert(att <= ATT_Last && "invalid enum value!");
assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
setDependence(computeDependence(this));
}

Expand Down Expand Up @@ -2813,6 +2815,8 @@ class ExpressionTraitExpr : public Expr {
: Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary),
ET(et), Value(value), Loc(loc), RParen(rparen),
QueriedExpression(queried) {
assert(et <= ET_Last && "invalid enum value!");
assert(static_cast<unsigned>(et) == ET && "ET overflow!");
setDependence(computeDependence(this));
}

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ class TextNodeDumper
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
void VisitCXXNewExpr(const CXXNewExpr *Node);
void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
void VisitTypeTraitExpr(const TypeTraitExpr *Node);
void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node);
void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node);
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
void VisitExprWithCleanups(const ExprWithCleanups *Node);
void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
Expand Down
34 changes: 33 additions & 1 deletion clang/include/clang/AST/VTableBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ class VTableLayout {
typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
AddressPointsMapTy;

// Mapping between the VTable index and address point index. This is useful
// when you don't care about the base subobjects and only want the address
// point for a given vtable index.
typedef llvm::SmallVector<unsigned, 4> AddressPointsIndexMapTy;

private:
// Stores the component indices of the first component of each virtual table in
// the virtual table group. To save a little memory in the common case where
Expand All @@ -253,6 +258,9 @@ class VTableLayout {
/// Address points for all vtables.
AddressPointsMapTy AddressPoints;

/// Address points for all vtable indices.
AddressPointsIndexMapTy AddressPointIndices;

public:
VTableLayout(ArrayRef<size_t> VTableIndices,
ArrayRef<VTableComponent> VTableComponents,
Expand All @@ -277,6 +285,10 @@ class VTableLayout {
return AddressPoints;
}

const AddressPointsIndexMapTy &getAddressPointIndices() const {
return AddressPointIndices;
}

size_t getNumVTables() const {
if (VTableIndices.empty())
return 1;
Expand Down Expand Up @@ -371,7 +383,17 @@ class ItaniumVTableContext : public VTableContextBase {
void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;

public:
ItaniumVTableContext(ASTContext &Context);
enum VTableComponentLayout {
/// Components in the vtable are pointers to other structs/functions.
Pointer,

/// Components in the vtable are relative offsets between the vtable and the
/// other structs/functions.
Relative,
};

ItaniumVTableContext(ASTContext &Context,
VTableComponentLayout ComponentLayout = Pointer);
~ItaniumVTableContext() override;

const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
Expand Down Expand Up @@ -402,6 +424,16 @@ class ItaniumVTableContext : public VTableContextBase {
static bool classof(const VTableContextBase *VT) {
return !VT->isMicrosoft();
}

VTableComponentLayout getVTableComponentLayout() const {
return ComponentLayout;
}

bool isPointerLayout() const { return ComponentLayout == Pointer; }
bool isRelativeLayout() const { return ComponentLayout == Relative; }

private:
VTableComponentLayout ComponentLayout;
};

/// Holds information about the inheritance path to a virtual base or function
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled")

LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled")

LANGOPT(RelativeCXXABIVTables, 1, 0,
"Use an ABI-incompatible v-table layout that uses relative references")

#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
Expand Down
23 changes: 21 additions & 2 deletions clang/include/clang/CodeGen/ConstantInitBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ class ConstantAggregateBuilderBase {
add(getRelativeOffset(type, target));
}

/// Same as addRelativeOffset(), but instead relative to an element in this
/// aggregate, identified by its index.
void addRelativeOffsetToPosition(llvm::IntegerType *type,
llvm::Constant *target, size_t position) {
add(getRelativeOffsetToPosition(type, target, position));
}

/// Add a relative offset to the target address, plus a small
/// constant offset. This is primarily useful when the relative
/// offset is known to be a multiple of (say) four and therefore
Expand Down Expand Up @@ -298,10 +305,18 @@ class ConstantAggregateBuilderBase {
/// position to be filled. This is computed with an indexed
/// getelementptr rather than by computing offsets.
///
/// The returned pointer will have type T*, where T is the given
/// position.
/// The returned pointer will have type T*, where T is the given type. This
/// type can differ from the type of the actual element.
llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);

/// Produce an address which points to a position in the aggregate being
/// constructed. This is computed with an indexed getelementptr rather than by
/// computing offsets.
///
/// The returned pointer will have type T*, where T is the given type. This
/// type can differ from the type of the actual element.
llvm::Constant *getAddrOfPosition(llvm::Type *type, size_t position);

llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
llvm::SmallVectorImpl<llvm::Constant*> &indices) {
getGEPIndicesTo(indices, Builder.Buffer.size());
Expand All @@ -319,6 +334,10 @@ class ConstantAggregateBuilderBase {
llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
llvm::Constant *target);

llvm::Constant *getRelativeOffsetToPosition(llvm::IntegerType *offsetType,
llvm::Constant *target,
size_t position);

CharUnits getOffsetFromGlobalTo(size_t index) const;
};

Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,13 @@ def fno_fine_grained_bitfield_accesses : Flag<["-"],
"fno-fine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Use large-integer access for consecutive bitfield runs.">;

def fexperimental_relative_cxx_abi_vtables : Flag<["-"], "fexperimental-relative-c++-abi-vtables">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use the experimental C++ class ABI for classes with virtual tables">;
def fno_experimental_relative_cxx_abi_vtables : Flag<["-"], "fno-experimental-relative-c++-abi-vtables">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Do not use the experimental C++ class ABI for classes with virtual tables">;

def flat__namespace : Flag<["-"], "flat_namespace">;
def flax_vector_conversions_EQ : Joined<["-"], "flax-vector-conversions=">, Group<f_Group>,
HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">, Flags<[CC1Option]>;
Expand Down
11 changes: 8 additions & 3 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10600,10 +10600,15 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {

VTableContextBase *ASTContext::getVTableContext() {
if (!VTContext.get()) {
if (Target->getCXXABI().isMicrosoft())
auto ABI = Target->getCXXABI();
if (ABI.isMicrosoft())
VTContext.reset(new MicrosoftVTableContext(*this));
else
VTContext.reset(new ItaniumVTableContext(*this));
else {
auto ComponentLayout = getLangOpts().RelativeCXXABIVTables
? ItaniumVTableContext::Relative
: ItaniumVTableContext::Pointer;
VTContext.reset(new ItaniumVTableContext(*this, ComponentLayout));
}
}
return VTContext.get();
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,10 @@ UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr(
SourceLocation op, SourceLocation rp)
: Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary),
OpLoc(op), RParenLoc(rp) {
assert(ExprKind <= UETT_Last && "invalid enum value!");
UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
assert(static_cast<unsigned>(ExprKind) == UnaryExprOrTypeTraitExprBits.Kind &&
"UnaryExprOrTypeTraitExprBits.Kind overflow!");
UnaryExprOrTypeTraitExprBits.IsType = false;
Argument.Ex = E;
setDependence(computeDependence(this));
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,7 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
SourceLocation RParenLoc, bool Value)
: Expr(TypeTraitExprClass, T, VK_RValue, OK_Ordinary), Loc(Loc),
RParenLoc(RParenLoc) {
assert(Kind <= TT_Last && "invalid enum value!");
TypeTraitExprBits.Kind = Kind;
assert(static_cast<unsigned>(Kind) == TypeTraitExprBits.Kind &&
"TypeTraitExprBits.Kind overflow!");
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,18 @@ void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
}
}

void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
OS << " " << getTraitSpelling(Node->getTrait());
}

void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
OS << " " << getTraitSpelling(Node->getTrait());
}

void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
OS << " " << getTraitSpelling(Node->getTrait());
}

void TextNodeDumper::VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *Node) {
if (const ValueDecl *VD = Node->getExtendingDecl()) {
Expand Down
77 changes: 57 additions & 20 deletions clang/lib/AST/VTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ class VCallAndVBaseOffsetBuilder {
VBaseOffsetOffsetsMapTy;

private:
const ItaniumVTableContext &VTables;

/// MostDerivedClass - The most derived class for which we're building vcall
/// and vbase offsets.
const CXXRecordDecl *MostDerivedClass;
Expand Down Expand Up @@ -583,13 +585,15 @@ class VCallAndVBaseOffsetBuilder {
CharUnits getCurrentOffsetOffset() const;

public:
VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass,
VCallAndVBaseOffsetBuilder(const ItaniumVTableContext &VTables,
const CXXRecordDecl *MostDerivedClass,
const CXXRecordDecl *LayoutClass,
const FinalOverriders *Overriders,
BaseSubobject Base, bool BaseIsVirtual,
CharUnits OffsetInLayoutClass)
: MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass),
Context(MostDerivedClass->getASTContext()), Overriders(Overriders) {
: VTables(VTables), MostDerivedClass(MostDerivedClass),
LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
Overriders(Overriders) {

// Add vcall and vbase offsets.
AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass);
Expand Down Expand Up @@ -662,9 +666,13 @@ CharUnits VCallAndVBaseOffsetBuilder::getCurrentOffsetOffset() const {
// vcall offset itself).
int64_t OffsetIndex = -(int64_t)(3 + Components.size());

CharUnits PointerWidth =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
CharUnits OffsetOffset = PointerWidth * OffsetIndex;
// Under the relative ABI, the offset widths are 32-bit ints instead of
// pointer widths.
CharUnits OffsetWidth = Context.toCharUnitsFromBits(
VTables.isRelativeLayout() ? 32
: Context.getTargetInfo().getPointerWidth(0));
CharUnits OffsetOffset = OffsetWidth * OffsetIndex;

return OffsetOffset;
}

Expand Down Expand Up @@ -1271,13 +1279,13 @@ ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment(
if (VCallOffsets.empty()) {
// We don't have vcall offsets for this virtual base, go ahead and
// build them.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
/*Overriders=*/nullptr,
BaseSubobject(Offset.VirtualBase,
CharUnits::Zero()),
/*BaseIsVirtual=*/true,
/*OffsetInLayoutClass=*/
CharUnits::Zero());
VCallAndVBaseOffsetBuilder Builder(
VTables, MostDerivedClass, MostDerivedClass,
/*Overriders=*/nullptr,
BaseSubobject(Offset.VirtualBase, CharUnits::Zero()),
/*BaseIsVirtual=*/true,
/*OffsetInLayoutClass=*/
CharUnits::Zero());

VCallOffsets = Builder.getVCallOffsets();
}
Expand Down Expand Up @@ -1635,9 +1643,9 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
VTableIndices.push_back(VTableIndex);

// Add vcall and vbase offsets for this vtable.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders,
Base, BaseIsVirtualInLayoutClass,
OffsetInLayoutClass);
VCallAndVBaseOffsetBuilder Builder(
VTables, MostDerivedClass, LayoutClass, &Overriders, Base,
BaseIsVirtualInLayoutClass, OffsetInLayoutClass);
Components.append(Builder.components_begin(), Builder.components_end());

// Check if we need to add these vcall offsets.
Expand Down Expand Up @@ -2200,12 +2208,40 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
}
}

static VTableLayout::AddressPointsIndexMapTy
MakeAddressPointIndices(const VTableLayout::AddressPointsMapTy &addressPoints,
unsigned numVTables) {
VTableLayout::AddressPointsIndexMapTy indexMap(numVTables);

for (auto it = addressPoints.begin(); it != addressPoints.end(); ++it) {
const auto &addressPointLoc = it->second;
unsigned vtableIndex = addressPointLoc.VTableIndex;
unsigned addressPoint = addressPointLoc.AddressPointIndex;
if (indexMap[vtableIndex]) {
// Multiple BaseSubobjects can map to the same AddressPointLocation, but
// every vtable index should have a unique address point.
assert(indexMap[vtableIndex] == addressPoint &&
"Every vtable index should have a unique address point. Found a "
"vtable that has two different address points.");
} else {
indexMap[vtableIndex] = addressPoint;
}
}

// Note that by this point, not all the address may be initialized if the
// AddressPoints map is empty. This is ok if the map isn't needed. See
// MicrosoftVTableContext::computeVTableRelatedInformation() which uses an
// emprt map.
return indexMap;
}

VTableLayout::VTableLayout(ArrayRef<size_t> VTableIndices,
ArrayRef<VTableComponent> VTableComponents,
ArrayRef<VTableThunkTy> VTableThunks,
const AddressPointsMapTy &AddressPoints)
: VTableComponents(VTableComponents), VTableThunks(VTableThunks),
AddressPoints(AddressPoints) {
AddressPoints(AddressPoints), AddressPointIndices(MakeAddressPointIndices(
AddressPoints, VTableIndices.size())) {
if (VTableIndices.size() <= 1)
assert(VTableIndices.size() == 1 && VTableIndices[0] == 0);
else
Expand All @@ -2221,8 +2257,9 @@ VTableLayout::VTableLayout(ArrayRef<size_t> VTableIndices,

VTableLayout::~VTableLayout() { }

ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context)
: VTableContextBase(/*MS=*/false) {}
ItaniumVTableContext::ItaniumVTableContext(
ASTContext &Context, VTableComponentLayout ComponentLayout)
: VTableContextBase(/*MS=*/false), ComponentLayout(ComponentLayout) {}

ItaniumVTableContext::~ItaniumVTableContext() {}

Expand Down Expand Up @@ -2251,7 +2288,7 @@ ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
if (I != VirtualBaseClassOffsetOffsets.end())
return I->second;

VCallAndVBaseOffsetBuilder Builder(RD, RD, /*Overriders=*/nullptr,
VCallAndVBaseOffsetBuilder Builder(*this, RD, RD, /*Overriders=*/nullptr,
BaseSubobject(RD, CharUnits::Zero()),
/*BaseIsVirtual=*/false,
/*OffsetInLayoutClass=*/CharUnits::Zero());
Expand Down
Loading

0 comments on commit 78c4105

Please sign in to comment.