Skip to content

Commit ea8dcd3

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: I2c84468be9f299fcdb41747352fd66d46d73d284
2 parents d5f3261 + 4acd84e commit ea8dcd3

File tree

33 files changed

+584
-42
lines changed

33 files changed

+584
-42
lines changed

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ class BoltAddressTranslation {
257257
std::as_const(*this).getBBHashMap(FuncOutputAddress));
258258
}
259259

260+
/// Returns the number of basic blocks in a function.
261+
size_t getNumBasicBlocks(uint64_t OutputAddress) const {
262+
return NumBasicBlocksMap.at(OutputAddress);
263+
}
264+
260265
private:
261266
FuncHashesTy FuncHashes;
262267
};

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,52 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
23102310
BP.Functions.emplace_back(
23112311
YAMLProfileWriter::convert(Function, /*UseDFS=*/false));
23122312
}
2313+
2314+
for (const auto &KV : NamesToBranches) {
2315+
const StringRef FuncName = KV.first;
2316+
const FuncBranchData &Branches = KV.second;
2317+
yaml::bolt::BinaryFunctionProfile YamlBF;
2318+
BinaryData *BD = BC.getBinaryDataByName(FuncName);
2319+
assert(BD);
2320+
uint64_t FuncAddress = BD->getAddress();
2321+
if (!BAT->isBATFunction(FuncAddress))
2322+
continue;
2323+
// Filter out cold fragments
2324+
if (!BD->getSectionName().equals(BC.getMainCodeSectionName()))
2325+
continue;
2326+
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(FuncAddress);
2327+
assert(BF);
2328+
YamlBF.Name = FuncName.str();
2329+
YamlBF.Id = BF->getFunctionNumber();
2330+
YamlBF.Hash = BAT->getBFHash(FuncAddress);
2331+
YamlBF.ExecCount = BF->getKnownExecutionCount();
2332+
YamlBF.NumBasicBlocks = BAT->getNumBasicBlocks(FuncAddress);
2333+
const BoltAddressTranslation::BBHashMapTy &BlockMap =
2334+
BAT->getBBHashMap(FuncAddress);
2335+
2336+
auto addSuccProfile = [&](yaml::bolt::BinaryBasicBlockProfile &YamlBB,
2337+
uint64_t SuccOffset, unsigned SuccDataIdx) {
2338+
const llvm::bolt::BranchInfo &BI = Branches.Data.at(SuccDataIdx);
2339+
yaml::bolt::SuccessorInfo SI;
2340+
SI.Index = BlockMap.getBBIndex(SuccOffset);
2341+
SI.Count = BI.Branches;
2342+
SI.Mispreds = BI.Mispreds;
2343+
YamlBB.Successors.emplace_back(SI);
2344+
};
2345+
2346+
for (const auto &[FromOffset, SuccKV] : Branches.IntraIndex) {
2347+
yaml::bolt::BinaryBasicBlockProfile YamlBB;
2348+
if (!BlockMap.isInputBlock(FromOffset))
2349+
continue;
2350+
YamlBB.Index = BlockMap.getBBIndex(FromOffset);
2351+
YamlBB.Hash = BlockMap.getBBHash(FromOffset);
2352+
for (const auto &[SuccOffset, SuccDataIdx] : SuccKV)
2353+
addSuccProfile(YamlBB, SuccOffset, SuccDataIdx);
2354+
if (YamlBB.ExecCount || !YamlBB.Successors.empty())
2355+
YamlBF.Blocks.emplace_back(YamlBB);
2356+
}
2357+
BP.Functions.emplace_back(YamlBF);
2358+
}
23132359
}
23142360

23152361
// Write the profile.

bolt/test/X86/bolt-address-translation-yaml.test

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries
2525
READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries
2626

2727
YAML-BAT-CHECK: functions:
28+
# Function not covered by BAT - has insns in basic block
2829
YAML-BAT-CHECK: - name: main
2930
YAML-BAT-CHECK-NEXT: fid: 2
3031
YAML-BAT-CHECK-NEXT: hash: 0x9895746D48B2C876
@@ -35,6 +36,17 @@ YAML-BAT-CHECK-NEXT: - bid: 0
3536
YAML-BAT-CHECK-NEXT: insns: 26
3637
YAML-BAT-CHECK-NEXT: hash: 0xA900AE79CFD40000
3738
YAML-BAT-CHECK-NEXT: succ: [ { bid: 3, cnt: 0 }, { bid: 1, cnt: 0 } ]
39+
# Function covered by BAT - doesn't have insns in basic block
40+
YAML-BAT-CHECK: - name: usqrt
41+
YAML-BAT-CHECK-NEXT: fid: [[#]]
42+
YAML-BAT-CHECK-NEXT: hash: 0x99E67ED32A203023
43+
YAML-BAT-CHECK-NEXT: exec: 21
44+
YAML-BAT-CHECK-NEXT: nblocks: 5
45+
YAML-BAT-CHECK-NEXT: blocks:
46+
YAML-BAT-CHECK: - bid: 1
47+
YAML-BAT-CHECK-NEXT: insns: [[#]]
48+
YAML-BAT-CHECK-NEXT: hash: 0xD70DC695320E0010
49+
YAML-BAT-CHECK-NEXT: succ: {{.*}} { bid: 2, cnt: [[#]] }
3850

3951
CHECK-BOLT-YAML: pre-processing profile using YAML profile reader
40-
CHECK-BOLT-YAML-NEXT: 1 out of 16 functions in the binary (6.2%) have non-empty execution profile
52+
CHECK-BOLT-YAML-NEXT: 5 out of 16 functions in the binary (31.2%) have non-empty execution profile

compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ const int SIGFPE = 8;
126126
const int SIGSEGV = 11;
127127
const int SIGPIPE = 13;
128128
const int SIGTERM = 15;
129-
const int SIGPROF = 27;
130129
#if defined(__mips__) || SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD
131130
const int SIGBUS = 10;
132131
const int SIGSYS = 12;
@@ -2180,8 +2179,7 @@ void sighandler(int sig, __sanitizer_siginfo *info, void *ctx) {
21802179
return;
21812180
}
21822181
// Don't mess with synchronous signals.
2183-
const bool sync = is_sync_signal(sctx, sig, info) ||
2184-
(sig == SIGPROF && thr->is_inited && !thr->is_dead);
2182+
const bool sync = is_sync_signal(sctx, sig, info);
21852183
if (sync ||
21862184
// If we are in blocking function, we can safely process it now
21872185
// (but check if we are in a recursive interceptor,

compiler-rt/test/tsan/signal_errno.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static void MyHandler(int, siginfo_t *s, void *c) {
1818

1919
static void* sendsignal(void *p) {
2020
barrier_wait(&barrier);
21-
pthread_kill(mainth, SIGALRM);
21+
pthread_kill(mainth, SIGPROF);
2222
return 0;
2323
}
2424

@@ -37,7 +37,7 @@ int main() {
3737
mainth = pthread_self();
3838
struct sigaction act = {};
3939
act.sa_sigaction = &MyHandler;
40-
sigaction(SIGALRM, &act, 0);
40+
sigaction(SIGPROF, &act, 0);
4141
pthread_t th;
4242
pthread_create(&th, 0, sendsignal, 0);
4343
loop();
@@ -46,7 +46,7 @@ int main() {
4646
}
4747

4848
// CHECK: WARNING: ThreadSanitizer: signal handler spoils errno
49-
// CHECK: Signal 14 handler invoked at:
49+
// CHECK: Signal 27 handler invoked at:
5050
// CHECK: #0 MyHandler(int, {{(__)?}}siginfo{{(_t)?}}*, void*) {{.*}}signal_errno.cpp
5151
// CHECK: main
5252
// CHECK: SUMMARY: ThreadSanitizer: signal handler spoils errno{{.*}}MyHandler

compiler-rt/test/tsan/signal_reset.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ static void* reset(void *p) {
2828
struct sigaction act = {};
2929
for (int i = 0; i < 1000000; i++) {
3030
act.sa_handler = &handler;
31-
if (sigaction(SIGALRM, &act, 0)) {
31+
if (sigaction(SIGPROF, &act, 0)) {
3232
perror("sigaction");
3333
exit(1);
3434
}
3535
act.sa_handler = SIG_IGN;
36-
if (sigaction(SIGALRM, &act, 0)) {
36+
if (sigaction(SIGPROF, &act, 0)) {
3737
perror("sigaction");
3838
exit(1);
3939
}
@@ -44,7 +44,7 @@ static void* reset(void *p) {
4444
int main() {
4545
struct sigaction act = {};
4646
act.sa_handler = SIG_IGN;
47-
if (sigaction(SIGALRM, &act, 0)) {
47+
if (sigaction(SIGPROF, &act, 0)) {
4848
perror("sigaction");
4949
exit(1);
5050
}
@@ -53,7 +53,7 @@ int main() {
5353
t.it_value.tv_sec = 0;
5454
t.it_value.tv_usec = 10;
5555
t.it_interval = t.it_value;
56-
if (setitimer(ITIMER_REAL, &t, 0)) {
56+
if (setitimer(ITIMER_PROF, &t, 0)) {
5757
perror("setitimer");
5858
exit(1);
5959
}

compiler-rt/test/tsan/signal_sync.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int main() {
3030

3131
struct sigaction act = {};
3232
act.sa_handler = &handler;
33-
if (sigaction(SIGVTALRM, &act, 0)) {
33+
if (sigaction(SIGPROF, &act, 0)) {
3434
perror("sigaction");
3535
exit(1);
3636
}
@@ -39,7 +39,7 @@ int main() {
3939
t.it_value.tv_sec = 0;
4040
t.it_value.tv_usec = 10;
4141
t.it_interval = t.it_value;
42-
if (setitimer(ITIMER_VIRTUAL, &t, 0)) {
42+
if (setitimer(ITIMER_PROF, &t, 0)) {
4343
perror("setitimer");
4444
exit(1);
4545
}

compiler-rt/test/tsan/signal_thread.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static void* thr(void *p) {
2424
int main() {
2525
struct sigaction act = {};
2626
act.sa_handler = &handler;
27-
if (sigaction(SIGVTALRM, &act, 0)) {
27+
if (sigaction(SIGPROF, &act, 0)) {
2828
perror("sigaction");
2929
exit(1);
3030
}
@@ -33,7 +33,7 @@ int main() {
3333
t.it_value.tv_sec = 0;
3434
t.it_value.tv_usec = 10;
3535
t.it_interval = t.it_value;
36-
if (setitimer(ITIMER_VIRTUAL, &t, 0)) {
36+
if (setitimer(ITIMER_PROF, &t, 0)) {
3737
perror("setitimer");
3838
exit(1);
3939
}

compiler-rt/test/tsan/signal_thread2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static void *thr(void *p) {
4040
int main() {
4141
struct sigaction act = {};
4242
act.sa_handler = &handler;
43-
if (sigaction(SIGALRM, &act, 0)) {
43+
if (sigaction(SIGPROF, &act, 0)) {
4444
perror("sigaction");
4545
exit(1);
4646
}
@@ -49,7 +49,7 @@ int main() {
4949
t.it_value.tv_sec = 0;
5050
t.it_value.tv_usec = 10;
5151
t.it_interval = t.it_value;
52-
if (setitimer(ITIMER_REAL, &t, 0)) {
52+
if (setitimer(ITIMER_PROF, &t, 0)) {
5353
perror("setitimer");
5454
exit(1);
5555
}

llvm/include/llvm/ProfileData/MemProf.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef LLVM_PROFILEDATA_MEMPROF_H_
22
#define LLVM_PROFILEDATA_MEMPROF_H_
33

4+
#include "llvm/ADT/MapVector.h"
45
#include "llvm/ADT/STLFunctionalExtras.h"
56
#include "llvm/ADT/SmallVector.h"
67
#include "llvm/IR/GlobalValue.h"
@@ -252,18 +253,26 @@ struct Frame {
252253
}
253254
};
254255

256+
// A type representing the index into the table of call stacks.
257+
using CallStackId = uint64_t;
258+
255259
// Holds allocation information in a space efficient format where frames are
256260
// represented using unique identifiers.
257261
struct IndexedAllocationInfo {
258262
// The dynamic calling context for the allocation in bottom-up (leaf-to-root)
259263
// order. Frame contents are stored out-of-line.
264+
// TODO: Remove once we fully transition to CSId.
260265
llvm::SmallVector<FrameId> CallStack;
266+
// Conceptually the same as above. We are going to keep both CallStack and
267+
// CallStackId while we are transitioning from CallStack to CallStackId.
268+
CallStackId CSId = 0;
261269
// The statistics obtained from the runtime for the allocation.
262270
PortableMemInfoBlock Info;
263271

264272
IndexedAllocationInfo() = default;
265-
IndexedAllocationInfo(ArrayRef<FrameId> CS, const MemInfoBlock &MB)
266-
: CallStack(CS.begin(), CS.end()), Info(MB) {}
273+
IndexedAllocationInfo(ArrayRef<FrameId> CS, CallStackId CSId,
274+
const MemInfoBlock &MB)
275+
: CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB) {}
267276

268277
// Returns the size in bytes when this allocation info struct is serialized.
269278
size_t serializedSize() const {
@@ -622,6 +631,16 @@ class FrameLookupTrait {
622631
return Frame::deserialize(D);
623632
}
624633
};
634+
635+
// Compute a CallStackId for a given call stack.
636+
CallStackId hashCallStack(ArrayRef<FrameId> CS);
637+
638+
// Verify that each CallStackId is computed with hashCallStack. This function
639+
// is intended to help transition from CallStack to CSId in
640+
// IndexedAllocationInfo.
641+
void verifyFunctionProfileData(
642+
const llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>
643+
&FunctionProfileData);
625644
} // namespace memprof
626645
} // namespace llvm
627646

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6916,6 +6916,11 @@ TargetLowering::prepareSREMEqFold(EVT SETCCVT, SDValue REMNode,
69166916
// Q = floor((2 * A) / (2^K))
69176917
APInt Q = (2 * A).udiv(APInt::getOneBitSet(W, K));
69186918

6919+
assert(APInt::getAllOnes(SVT.getSizeInBits()).ugt(A) &&
6920+
"We are expecting that A is always less than all-ones for SVT");
6921+
assert(APInt::getAllOnes(ShSVT.getSizeInBits()).ugt(K) &&
6922+
"We are expecting that K is always less than all-ones for ShSVT");
6923+
69196924
// If D was a power of two, apply the alternate constant derivation.
69206925
if (D0.isOne()) {
69216926
// A = 2^(W-1)
@@ -6924,11 +6929,6 @@ TargetLowering::prepareSREMEqFold(EVT SETCCVT, SDValue REMNode,
69246929
Q = APInt::getAllOnes(W - K).zext(W);
69256930
}
69266931

6927-
assert(APInt::getAllOnes(SVT.getSizeInBits()).ugt(A) &&
6928-
"We are expecting that A is always less than all-ones for SVT");
6929-
assert(APInt::getAllOnes(ShSVT.getSizeInBits()).ugt(K) &&
6930-
"We are expecting that K is always less than all-ones for ShSVT");
6931-
69326932
// If the divisor is 1 the result can be constant-folded. Likewise, we
69336933
// don't care about INT_MIN lanes, those can be set to undef if appropriate.
69346934
if (D.isOne()) {

llvm/lib/ProfileData/MemProf.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
#include "llvm/IR/Function.h"
44
#include "llvm/ProfileData/InstrProf.h"
55
#include "llvm/ProfileData/SampleProf.h"
6+
#include "llvm/Support/BLAKE3.h"
67
#include "llvm/Support/Endian.h"
78
#include "llvm/Support/EndianStream.h"
9+
#include "llvm/Support/HashBuilder.h"
810

911
namespace llvm {
1012
namespace memprof {
@@ -117,5 +119,28 @@ Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer) {
117119
return Result;
118120
}
119121

122+
CallStackId hashCallStack(ArrayRef<FrameId> CS) {
123+
llvm::HashBuilder<llvm::TruncatedBLAKE3<8>, llvm::endianness::little>
124+
HashBuilder;
125+
for (FrameId F : CS)
126+
HashBuilder.add(F);
127+
llvm::BLAKE3Result<8> Hash = HashBuilder.final();
128+
CallStackId CSId;
129+
std::memcpy(&CSId, Hash.data(), sizeof(Hash));
130+
return CSId;
131+
}
132+
133+
void verifyFunctionProfileData(
134+
const llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>
135+
&FunctionProfileData) {
136+
for (const auto &[GUID, Record] : FunctionProfileData) {
137+
(void)GUID;
138+
for (const auto &AS : Record.AllocSites) {
139+
assert(AS.CSId == hashCallStack(AS.CallStack));
140+
(void)AS;
141+
}
142+
}
143+
}
144+
120145
} // namespace memprof
121146
} // namespace llvm

llvm/lib/ProfileData/RawMemProfReader.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,14 +446,16 @@ Error RawMemProfReader::mapRawProfileToRecords() {
446446
Callstack.append(Frames.begin(), Frames.end());
447447
}
448448

449+
CallStackId CSId = hashCallStack(Callstack);
450+
449451
// We attach the memprof record to each function bottom-up including the
450452
// first non-inline frame.
451453
for (size_t I = 0; /*Break out using the condition below*/; I++) {
452454
const Frame &F = idToFrame(Callstack[I]);
453455
auto Result =
454456
FunctionProfileData.insert({F.Function, IndexedMemProfRecord()});
455457
IndexedMemProfRecord &Record = Result.first->second;
456-
Record.AllocSites.emplace_back(Callstack, Entry.second);
458+
Record.AllocSites.emplace_back(Callstack, CSId, Entry.second);
457459

458460
if (!F.IsInlineFrame)
459461
break;
@@ -471,6 +473,8 @@ Error RawMemProfReader::mapRawProfileToRecords() {
471473
}
472474
}
473475

476+
verifyFunctionProfileData(FunctionProfileData);
477+
474478
return Error::success();
475479
}
476480

llvm/lib/Target/Mips/MipsExpandPseudo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,15 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
500500
.addReg(Incr, RegState::Kill)
501501
.addImm(ShiftImm);
502502
}
503+
} else {
504+
// and OldVal, OldVal, Mask
505+
// and Incr, Incr, Mask
506+
BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
507+
.addReg(OldVal)
508+
.addReg(Mask);
509+
BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr)
510+
.addReg(Incr)
511+
.addReg(Mask);
503512
}
504513
}
505514
// unsigned: sltu Scratch4, oldVal, Incr

0 commit comments

Comments
 (0)