Skip to content

Commit

Permalink
Merge branch 'main' into Libcxx
Browse files Browse the repository at this point in the history
  • Loading branch information
jhuber6 authored Aug 1, 2024
2 parents aab10be + 2771ea4 commit 04ffb56
Show file tree
Hide file tree
Showing 604 changed files with 32,954 additions and 18,456 deletions.
17 changes: 13 additions & 4 deletions bolt/include/bolt/Core/DIEBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class DIEBuilder {
DWARFContext *DwarfContext{nullptr};
DWARFUnit *SkeletonCU{nullptr};
uint64_t UnitSize{0};
/// Adds separate UnitSize counter for updating DebugNames
/// so there is no dependency between the functions.
uint64_t DebugNamesUnitSize{0};
llvm::DenseSet<uint64_t> AllProcessed;
DWARF5AcceleratorTable &DebugNamesTable;
// Unordered map to handle name collision if output DWO directory is
Expand Down Expand Up @@ -203,13 +206,16 @@ class DIEBuilder {
/// Update references once the layout is finalized.
void updateReferences();

/// Update the Offset and Size of DIE, populate DebugNames table.
/// Update the Offset and Size of DIE.
/// Along with current CU, and DIE being processed and the new DIE offset to
/// be updated, it takes in Parents vector that can be empty if this DIE has
/// no parents.
uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain, uint32_t &CurOffset);
uint32_t finalizeDIEs(DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);

/// Populates DebugNames table.
void populateDebugNamesTable(DWARFUnit &CU, const DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain);

void registerUnit(DWARFUnit &DU, bool NeedSort);

Expand Down Expand Up @@ -338,6 +344,9 @@ class DIEBuilder {
/// Finish current DIE construction.
void finish();

/// Update debug names table.
void updateDebugNamesTable();

// Interface to edit DIE
template <class T> T *allocateDIEValue() {
return new (getState().DIEAlloc) T;
Expand Down
8 changes: 8 additions & 0 deletions bolt/include/bolt/Core/GDBIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class GDBIndex {
const GDBIndexTUEntryType &getGDBIndexTUEntryVector() const {
return GDBIndexTUEntryVector;
}

/// Sorts entries in GDBIndexTUEntryVector according to the TypeHash.
void sortGDBIndexTUEntryVector() {
llvm::stable_sort(GDBIndexTUEntryVector, [](const GDBIndexTUEntry &LHS,
const GDBIndexTUEntry &RHS) {
return LHS.TypeHash > RHS.TypeHash;
});
}
};

} // namespace bolt
Expand Down
62 changes: 46 additions & 16 deletions bolt/lib/Core/DIEBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,17 +461,11 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx,
return nullptr;
}

uint32_t
DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain, uint32_t &CurOffset) {
uint32_t DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die,
uint32_t &CurOffset) {
getState().DWARFDieAddressesParsed.erase(Die.getOffset());
uint32_t CurSize = 0;
Die.setOffset(CurOffset);
std::optional<BOLTDWARF5AccelTableData *> NameEntry =
DebugNamesTable.addAccelTableEntry(
CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt,
NumberParentsInChain, Parent);
// It is possible that an indexed debugging information entry has a parent
// that is not indexed (for example, if its parent does not have a name
// attribute). In such a case, a parent attribute may point to a nameless
Expand All @@ -485,18 +479,13 @@ DIEBuilder::finalizeDIEs(DWARFUnit &CU, DIE &Die,
// If Parent is nullopt and NumberParentsInChain is not zero, then forward
// declaration was encountered in this DF traversal. Propagating nullopt for
// Parent to children.
if (!Parent && NumberParentsInChain)
NameEntry = std::nullopt;
if (NameEntry)
++NumberParentsInChain;
for (DIEValue &Val : Die.values())
CurSize += Val.sizeOf(CU.getFormParams());
CurSize += getULEB128Size(Die.getAbbrevNumber());
CurOffset += CurSize;

for (DIE &Child : Die.children()) {
uint32_t ChildSize =
finalizeDIEs(CU, Child, NameEntry, NumberParentsInChain, CurOffset);
uint32_t ChildSize = finalizeDIEs(CU, Child, CurOffset);
CurSize += ChildSize;
}
// for children end mark.
Expand All @@ -514,10 +503,9 @@ void DIEBuilder::finish() {
DIE *UnitDIE = getUnitDIEbyUnit(CU);
uint32_t HeaderSize = CU.getHeaderSize();
uint32_t CurOffset = HeaderSize;
DebugNamesTable.setCurrentUnit(CU, UnitStartOffset);
std::vector<std::optional<BOLTDWARF5AccelTableData *>> Parents;
Parents.push_back(std::nullopt);
finalizeDIEs(CU, *UnitDIE, std::nullopt, 0, CurOffset);
finalizeDIEs(CU, *UnitDIE, CurOffset);

DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU);
CurUnitInfo.UnitOffset = UnitStartOffset;
Expand Down Expand Up @@ -548,6 +536,48 @@ void DIEBuilder::finish() {
dbgs() << Twine::utohexstr(Address) << "\n";
}
}
}

void DIEBuilder::populateDebugNamesTable(
DWARFUnit &CU, const DIE &Die,
std::optional<BOLTDWARF5AccelTableData *> Parent,
uint32_t NumberParentsInChain) {
std::optional<BOLTDWARF5AccelTableData *> NameEntry =
DebugNamesTable.addAccelTableEntry(
CU, Die, SkeletonCU ? SkeletonCU->getDWOId() : std::nullopt,
NumberParentsInChain, Parent);
if (!Parent && NumberParentsInChain)
NameEntry = std::nullopt;
if (NameEntry)
++NumberParentsInChain;

for (const DIE &Child : Die.children())
populateDebugNamesTable(CU, Child, NameEntry, NumberParentsInChain);
}

void DIEBuilder::updateDebugNamesTable() {
auto finalizeDebugNamesTableForCU = [&](DWARFUnit &CU,
uint64_t &UnitStartOffset) -> void {
DIE *UnitDIE = getUnitDIEbyUnit(CU);
DebugNamesTable.setCurrentUnit(CU, UnitStartOffset);
populateDebugNamesTable(CU, *UnitDIE, std::nullopt, 0);

DWARFUnitInfo &CurUnitInfo = getUnitInfoByDwarfUnit(CU);
UnitStartOffset += CurUnitInfo.UnitLength;
};

uint64_t TypeUnitStartOffset = 0;
for (DWARFUnit *CU : getState().DUList) {
if (!(CU->getVersion() < 5 && CU->isTypeUnit()))
break;
finalizeDebugNamesTableForCU(*CU, TypeUnitStartOffset);
}

for (DWARFUnit *CU : getState().DUList) {
if (CU->getVersion() < 5 && CU->isTypeUnit())
continue;
finalizeDebugNamesTableForCU(*CU, DebugNamesUnitSize);
}
updateReferences();
}

Expand Down
3 changes: 1 addition & 2 deletions bolt/lib/Core/GDBIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ void GDBIndex::updateGdbIndexSection(
DebugARangesSectionWriter &ARangesSectionWriter) {
if (!BC.getGdbIndexSection())
return;

// See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
// for .gdb_index section format.

Expand Down Expand Up @@ -141,7 +140,7 @@ void GDBIndex::updateGdbIndexSection(
write64le(Buffer + 8, CUInfo.second.Length + 4);
Buffer += 16;
}

sortGDBIndexTUEntryVector();
// Rewrite TU CU List, since abbrevs can be different.
// Entry example:
// 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature =
Expand Down
16 changes: 12 additions & 4 deletions bolt/lib/Rewrite/DWARFRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,8 @@ void DWARFRewriter::updateDebugInfo() {
DebugRangesSectionWriter &TempRangesSectionWriter,
DebugAddrWriter &AddressWriter,
const std::string &DWOName,
const std::optional<std::string> &DwarfOutputPath) {
DIEBuilder DWODIEBuilder(BC, &(SplitCU).getContext(), DebugNamesTable,
&Unit);
const std::optional<std::string> &DwarfOutputPath,
DIEBuilder &DWODIEBuilder) {
DWODIEBuilder.buildDWOUnit(SplitCU);
DebugStrOffsetsWriter DWOStrOffstsWriter(BC);
DebugStrWriter DWOStrWriter((SplitCU).getContext(), true);
Expand Down Expand Up @@ -719,6 +718,7 @@ void DWARFRewriter::updateDebugInfo() {
CUPartitionVector PartVec = partitionCUs(*BC.DwCtx);
for (std::vector<DWARFUnit *> &Vec : PartVec) {
DIEBlder.buildCompileUnits(Vec);
llvm::SmallVector<std::unique_ptr<DIEBuilder>, 72> DWODIEBuildersByCU;
for (DWARFUnit *CU : DIEBlder.getProcessedCUs()) {
createRangeLocListAddressWriters(*CU);
std::optional<DWARFUnit *> SplitCU;
Expand All @@ -738,11 +738,17 @@ void DWARFRewriter::updateDebugInfo() {
: std::optional<std::string>(opts::DwarfOutputPath.c_str());
std::string DWOName = DIEBlder.updateDWONameCompDir(
*StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt);
auto DWODIEBuilderPtr = std::make_unique<DIEBuilder>(
BC, &(**SplitCU).getContext(), DebugNamesTable, CU);
DIEBuilder &DWODIEBuilder =
*DWODIEBuildersByCU.emplace_back(std::move(DWODIEBuilderPtr)).get();
if (CU->getVersion() >= 5)
StrOffstsWriter->finalizeSection(*CU, DIEBlder);
processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter,
AddressWriter, DWOName, DwarfOutputPath);
AddressWriter, DWOName, DwarfOutputPath, DWODIEBuilder);
}
for (std::unique_ptr<DIEBuilder> &DWODIEBuilderPtr : DWODIEBuildersByCU)
DWODIEBuilderPtr->updateDebugNamesTable();
for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
processMainBinaryCU(*CU, DIEBlder);
finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
Expand Down Expand Up @@ -1442,6 +1448,7 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder,
// generate and populate abbrevs here
DIEBlder.generateAbbrevs();
DIEBlder.finish();
DIEBlder.updateDebugNamesTable();
SmallVector<char, 20> OutBuffer;
std::shared_ptr<raw_svector_ostream> ObjOS =
std::make_shared<raw_svector_ostream>(OutBuffer);
Expand Down Expand Up @@ -1646,6 +1653,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
}
DIEBlder.generateAbbrevs();
DIEBlder.finish();
DIEBlder.updateDebugNamesTable();
// generate debug_info and CUMap
for (DWARFUnit *CU : CUs) {
emitUnit(DIEBlder, Streamer, *CU);
Expand Down
11 changes: 11 additions & 0 deletions bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,18 +3131,24 @@ void RewriteInstance::initializeMetadataManager() {
}

void RewriteInstance::processSectionMetadata() {
NamedRegionTimer T("processmetadata-section", "process section metadata",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
initializeMetadataManager();

MetadataManager.runSectionInitializers();
}

void RewriteInstance::processMetadataPreCFG() {
NamedRegionTimer T("processmetadata-precfg", "process metadata pre-CFG",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
MetadataManager.runInitializersPreCFG();

processProfileDataPreCFG();
}

void RewriteInstance::processMetadataPostCFG() {
NamedRegionTimer T("processmetadata-postcfg", "process metadata post-CFG",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
MetadataManager.runInitializersPostCFG();
}

Expand Down Expand Up @@ -3194,6 +3200,7 @@ void RewriteInstance::processProfileData() {
if (opts::AggregateOnly) {
PrintProgramStats PPS(&*BAT);
BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*BC));
TimerGroup::printAll(outs());
exit(0);
}
}
Expand Down Expand Up @@ -3536,10 +3543,14 @@ void RewriteInstance::emitAndLink() {
}

void RewriteInstance::finalizeMetadataPreEmit() {
NamedRegionTimer T("finalizemetadata-preemit", "finalize metadata pre-emit",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
MetadataManager.runFinalizersPreEmit();
}

void RewriteInstance::updateMetadata() {
NamedRegionTimer T("updatemetadata-postemit", "update metadata post-emit",
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
MetadataManager.runFinalizersAfterEmit();

if (opts::UpdateDebugSections) {
Expand Down
8 changes: 4 additions & 4 deletions bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
# POSTCHECK-NEXT: 0: Offset = 0x0, Length = 0x34
# POSTCHECK-NEXT: 1: Offset = 0x34, Length = 0x34
# POSTCHECK: Types CU list offset = 0x38, has 4 entries
# POSTCHECK-NEXT: 0: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x675d23e4f33235f2
# POSTCHECK-NEXT: 1: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0x49dc260088be7e56
# POSTCHECK-NEXT: 2: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x104ec427d2ebea6f
# POSTCHECK-NEXT: 3: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0xb4580bc1535df1e4
# POSTCHECK-NEXT: 0: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0xb4580bc1535df1e4
# POSTCHECK-NEXT: 1: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x675d23e4f33235f2
# POSTCHECK-NEXT: 2: offset = 0x0000004a, type_offset = 0x0000001e, type_signature = 0x49dc260088be7e56
# POSTCHECK-NEXT: 3: offset = 0x00000000, type_offset = 0x0000001e, type_signature = 0x104ec427d2ebea6f
# POSTCHECK: Address area offset = 0x98, has 2 entries
# POSTCHECK-NEXT: Low/High address = [0x[[#%.4x,ADDR:]],
# POSTCHECK-SAME: 0x[[#ADDR + 0x7a]]) (Size: 0x7a), CU id = 0
Expand Down
22 changes: 22 additions & 0 deletions bolt/test/timers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* This test checks timers for metadata manager phases.
# RUN: %clang %cflags %s -o %t.exe
# RUN: link_fdata %s %t.exe %t.fdata
# RUN: llvm-bolt %t.exe -o %t.null --data %t.fdata -w %t.yaml --time-rewrite \
# RUN: 2>&1 | FileCheck %s
# RUN: link_fdata %s %t.exe %t.preagg PREAGG
# RUN: perf2bolt %t.exe -o %t.null -p %t.preagg --pa --time-rewrite \
# RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-P2B
# CHECK-DAG: update metadata post-emit
# CHECK-DAG: process section metadata
# CHECK-DAG: process metadata pre-CFG
# CHECK-DAG: process metadata post-CFG
# CHECK-DAG: finalize metadata pre-emit
# CHECK-P2B-DAG: process section metadata
# CHECK-P2B-DAG: process metadata pre-CFG
# FDATA: 0 [unknown] 0 1 main 0 1 0
# PREAGG: B X:0 #main# 1 0
*/
int main() { return 0; }
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ Miscellaneous Clang Crashes Fixed
- Fixed a crash in C due to incorrect lookup that members in nested anonymous struct/union
can be found as ordinary identifiers in struct/union definition. (#GH31295)

- Fixed a crash caused by long chains of ``sizeof`` and other similar operators
that can be followed by a non-parenthesized expression. (#GH45061)

OpenACC Specific Changes
------------------------

Expand Down
40 changes: 37 additions & 3 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2498,15 +2498,49 @@ Check for pointer arithmetic on locations other than array elements.
alpha.core.PointerSub (C)
"""""""""""""""""""""""""
Check for pointer subtractions on two pointers pointing to different memory chunks.
Check for pointer subtractions on two pointers pointing to different memory
chunks. According to the C standard §6.5.6 only subtraction of pointers that
point into (or one past the end) the same array object is valid (for this
purpose non-array variables are like arrays of size 1).
.. code-block:: c
void test() {
int x, y;
int d = &y - &x; // warn
int a, b, c[10], d[10];
int x = &c[3] - &c[1];
x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays
x = (&a + 1) - &a;
x = &b - &a; // warn: 'a' and 'b' are different variables
x = (&a + 2) - &a; // warn: for a variable it is only valid to have a pointer
// to one past the address of it
x = &c[10] - &c[0];
x = &c[11] - &c[0]; // warn: index larger than one past the end
x = &c[-1] - &c[0]; // warn: negative index
}
struct S {
int x[10];
int y[10];
};
void test1() {
struct S a[10];
struct S b;
int d = &a[4] - &a[6];
d = &a[0].x[3] - &a[0].x[1];
d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects
d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object
d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it
}
There may be existing applications that use code like above for calculating
offsets of members in a structure, using pointer subtractions. This is still
undefined behavior according to the standard and code like this can be replaced
with the `offsetof` macro.
The checker only reports cases where stack-allocated objects are involved (no
warnings on pointers to memory allocated by `malloc`).
.. _alpha-core-StackAddressAsyncEscape:
alpha.core.StackAddressAsyncEscape (C)
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,13 @@ class CXXRecordDecl : public RecordDecl {
return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields;
}

/// If this is a standard-layout class or union, any and all data members will
/// be declared in the same type.
///
/// This retrieves the type where any fields are declared,
/// or the current class if there is no class with fields.
const CXXRecordDecl *getStandardLayoutBaseWithFields() const;

/// Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
Expand Down
Loading

0 comments on commit 04ffb56

Please sign in to comment.