Skip to content

Commit 25a5d3d

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:0502d8347020 into amd-gfx:4191fabcf57f
Local branch amd-gfx 4191fab Merged main:e8970141ec43 into amd-gfx:01e4b3298723 Remote branch main 0502d83 Minor fixes on the MLIR ActionProfiler (NFC)
2 parents 4191fab + 0502d83 commit 25a5d3d

File tree

9 files changed

+213
-51
lines changed

9 files changed

+213
-51
lines changed

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/* Indicate that this is LLVM compiled from the amd-gfx branch. */
1818
#define LLVM_HAVE_BRANCH_AMD_GFX
19-
#define LLVM_MAIN_REVISION 476601
19+
#define LLVM_MAIN_REVISION 476604
2020

2121
/* Define if LLVM_ENABLE_DUMP is enabled */
2222
#cmakedefine LLVM_ENABLE_DUMP

llvm/lib/Object/MachOUniversalWriter.cpp

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Slice::Slice(const IRObjectFile &IRO, uint32_t CPUType, uint32_t CPUSubType,
100100

101101
Slice::Slice(const MachOObjectFile &O) : Slice(O, calculateAlignment(O)) {}
102102

103-
using MachoCPUTy = std::pair<unsigned, unsigned>;
103+
using MachoCPUTy = std::pair<uint32_t, uint32_t>;
104104

105105
static Expected<MachoCPUTy> getMachoCPUFromTriple(Triple TT) {
106106
auto CPU = std::make_pair(MachO::getCPUType(TT), MachO::getCPUSubType(TT));
@@ -117,10 +117,15 @@ static Expected<MachoCPUTy> getMachoCPUFromTriple(StringRef TT) {
117117
return getMachoCPUFromTriple(Triple{TT});
118118
}
119119

120+
static MachoCPUTy getMachoCPUFromObjectFile(const MachOObjectFile &O) {
121+
return std::make_pair(O.getHeader().cputype, O.getHeader().cpusubtype);
122+
}
123+
120124
Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
121125
Error Err = Error::success();
122126
std::unique_ptr<MachOObjectFile> MFO = nullptr;
123127
std::unique_ptr<IRObjectFile> IRFO = nullptr;
128+
std::optional<MachoCPUTy> CPU = std::nullopt;
124129
for (const Archive::Child &Child : A.children(Err)) {
125130
Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(LLVMCtx);
126131
if (!ChildOrErr)
@@ -134,65 +139,56 @@ Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
134139
.c_str());
135140
if (Bin->isMachO()) {
136141
MachOObjectFile *O = cast<MachOObjectFile>(Bin);
137-
if (IRFO) {
138-
return createStringError(
139-
std::errc::invalid_argument,
140-
"archive member %s is a MachO, while previous archive member "
141-
"%s was an IR LLVM object",
142-
O->getFileName().str().c_str(), IRFO->getFileName().str().c_str());
143-
}
144-
if (MFO &&
145-
std::tie(MFO->getHeader().cputype, MFO->getHeader().cpusubtype) !=
146-
std::tie(O->getHeader().cputype, O->getHeader().cpusubtype)) {
142+
MachoCPUTy ObjectCPU = getMachoCPUFromObjectFile(*O);
143+
144+
if (CPU && CPU != ObjectCPU) {
145+
// If CPU != nullptr, one of MFO, IRFO will be != nullptr.
146+
StringRef PreviousName = MFO ? MFO->getFileName() : IRFO->getFileName();
147147
return createStringError(
148148
std::errc::invalid_argument,
149149
("archive member " + O->getFileName() + " cputype (" +
150-
Twine(O->getHeader().cputype) + ") and cpusubtype(" +
151-
Twine(O->getHeader().cpusubtype) +
150+
Twine(ObjectCPU.first) + ") and cpusubtype(" +
151+
Twine(ObjectCPU.second) +
152152
") does not match previous archive members cputype (" +
153-
Twine(MFO->getHeader().cputype) + ") and cpusubtype(" +
154-
Twine(MFO->getHeader().cpusubtype) +
155-
") (all members must match) " + MFO->getFileName())
153+
Twine(CPU->first) + ") and cpusubtype(" + Twine(CPU->second) +
154+
") (all members must match) " + PreviousName)
156155
.str()
157156
.c_str());
158157
}
159158
if (!MFO) {
160159
ChildOrErr.get().release();
161160
MFO.reset(O);
161+
if (!CPU)
162+
CPU.emplace(ObjectCPU);
162163
}
163164
} else if (Bin->isIR()) {
164165
IRObjectFile *O = cast<IRObjectFile>(Bin);
165-
if (MFO) {
166-
return createStringError(std::errc::invalid_argument,
167-
"archive member '%s' is an LLVM IR object, "
168-
"while previous archive member "
169-
"'%s' was a MachO",
170-
O->getFileName().str().c_str(),
171-
MFO->getFileName().str().c_str());
166+
Expected<MachoCPUTy> ObjectCPU =
167+
getMachoCPUFromTriple(O->getTargetTriple());
168+
if (!ObjectCPU)
169+
return ObjectCPU.takeError();
170+
171+
if (CPU && CPU != *ObjectCPU) {
172+
// If CPU != nullptr, one of MFO, IRFO will be != nullptr.
173+
StringRef PreviousName =
174+
IRFO ? IRFO->getFileName() : MFO->getFileName();
175+
return createStringError(
176+
std::errc::invalid_argument,
177+
("archive member " + O->getFileName() + " cputype (" +
178+
Twine(ObjectCPU->first) + ") and cpusubtype(" +
179+
Twine(ObjectCPU->second) +
180+
") does not match previous archive members cputype (" +
181+
Twine(CPU->first) + ") and cpusubtype(" + Twine(CPU->second) +
182+
") (all members must match) " + PreviousName)
183+
.str()
184+
.c_str());
172185
}
173-
if (IRFO) {
174-
Expected<MachoCPUTy> CPUO = getMachoCPUFromTriple(O->getTargetTriple());
175-
Expected<MachoCPUTy> CPUFO =
176-
getMachoCPUFromTriple(IRFO->getTargetTriple());
177-
if (!CPUO)
178-
return CPUO.takeError();
179-
if (!CPUFO)
180-
return CPUFO.takeError();
181-
if (*CPUO != *CPUFO) {
182-
return createStringError(
183-
std::errc::invalid_argument,
184-
("archive member " + O->getFileName() + " cputype (" +
185-
Twine(CPUO->first) + ") and cpusubtype(" + Twine(CPUO->second) +
186-
") does not match previous archive members cputype (" +
187-
Twine(CPUFO->first) + ") and cpusubtype(" +
188-
Twine(CPUFO->second) + ") (all members must match) " +
189-
IRFO->getFileName())
190-
.str()
191-
.c_str());
192-
}
193-
} else {
186+
187+
if (!IRFO) {
194188
ChildOrErr.get().release();
195189
IRFO.reset(O);
190+
if (!CPU)
191+
CPU.emplace(*ObjectCPU);
196192
}
197193
} else
198194
return createStringError(std::errc::invalid_argument,

llvm/test/tools/llvm-lipo/create-archive-input.test

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,27 @@
2828
# RUN: llvm-lipo %t-ir-armv7-x86_64-universal.o -thin x86_64 -output %t-ir-extracted-x86_64.o
2929
# RUN: cmp %t-ir-extracted-x86_64.o %t-ir-x86_64.o
3030

31-
# RUN: llvm-ar cr %t.different_types0.a %t-i386.o %t-ir-x86_64.o
32-
# RUN: not llvm-lipo -create %t.different_types0.a -output /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE-WITH-MACHO-AND-IR %s
33-
# RUN: llvm-ar cr %t.different_types1.a %t-ir-x86_64.o %t-i386.o
34-
# RUN: not llvm-lipo -create %t.different_types1.a -output /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE-WITH-IR-AND-MACHO %s
31+
# RUN: llvm-ar cr %t.different_types0-i386.a %t-i386.o
32+
# RUN: llvm-ar cr %t.different_types0-x86_64.a %t-x86_64.o %t-ir-x86_64.o
33+
# RUN: llvm-lipo -create %t.different_types0-i386.a %t.different_types0-x86_64.a -output %t.different_types0-universal.a
34+
# RUN: llvm-lipo %t.different_types0-universal.a -thin i386 -output %t.different_types0-extracted-i386.a
35+
# RUN: llvm-lipo %t.different_types0-universal.a -thin x86_64 -output %t.different_types0-extracted-x86_64.a
36+
# RUN: cmp %t.different_types0-extracted-i386.a %t.different_types0-i386.a
37+
# RUN: cmp %t.different_types0-extracted-x86_64.a %t.different_types0-x86_64.a
38+
39+
# RUN: llvm-ar cr %t.different_types1-i386.a %t-i386.o
40+
# RUN: llvm-ar cr %t.different_types1-x86_64.a %t-ir-x86_64.o %t-x86_64.o
41+
# RUN: llvm-lipo -create %t.different_types1-x86_64.a %t.different_types1-i386.a -output %t.different_types1-universal.a
42+
# RUN: llvm-lipo %t.different_types1-universal.a -thin i386 -output %t.different_types1-extracted-i386.a
43+
# RUN: llvm-lipo %t.different_types1-universal.a -thin x86_64 -output %t.different_types1-extracted-x86_64.a
44+
# RUN: cmp %t.different_types1-extracted-i386.a %t.different_types1-i386.a
45+
# RUN: cmp %t.different_types1-extracted-x86_64.a %t.different_types1-x86_64.a
46+
3547
# RUN: llvm-ar cr %t.different_architectures_ir.a %t-ir-x86_64.o %t-ir-armv7.o
3648
# RUN: not llvm-lipo -create %t.different_architectures_ir.a -output /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE-WITH-DIFFERENT-ARCHS %s
3749

3850
# EMPTY-ARCHIVE: empty archive
3951
# ARCHIVE-WITH-DIFFERENT-ARCHS: all members must match
40-
# ARCHIVE-WITH-MACHO-AND-IR: is an LLVM IR object, while previous archive member {{.*}} was a MachO
41-
# ARCHIVE-WITH-IR-AND-MACHO: is a MachO, while previous archive member {{.*}} was an IR LLVM object
4252
# ARCHIVE-WITH-FAT-BINARY: fat file (not allowed in an archive)
4353
#
4454
# INFO-i386-x86_64: i386 x86_64

mlir/include/mlir/Debug/CLOptionsSetup.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class DebugConfig {
5151
/// Get the filename to use for logging actions.
5252
StringRef getLogActionsTo() const { return logActionsToFlag; }
5353

54+
/// Get the filename to use for profiling actions.
55+
StringRef getProfileActionsTo() const { return profileActionsToFlag; }
56+
5457
/// Set a location breakpoint manager to filter out action logging based on
5558
/// the attached IR location in the Action context. Ownership stays with the
5659
/// caller.
@@ -71,6 +74,9 @@ class DebugConfig {
7174
/// Log action execution to the given file (or "-" for stdout)
7275
std::string logActionsToFlag;
7376

77+
/// Profile action execution to the given file (or "-" for stdout)
78+
std::string profileActionsToFlag;
79+
7480
/// Location Breakpoints to filter the action logging.
7581
std::vector<tracing::BreakpointManager *> logActionLocationFilter;
7682
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===- ActionProfiler.h - Profiling Actions *- C++ -*-=======================//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef MLIR_TRACING_OBSERVERS_ACTIONPROFILER_H
10+
#define MLIR_TRACING_OBSERVERS_ACTIONPROFILER_H
11+
12+
#include "mlir/Debug/ExecutionContext.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Support/raw_ostream.h"
15+
16+
#include <chrono>
17+
#include <mutex>
18+
19+
namespace mlir {
20+
namespace tracing {
21+
22+
/// This class defines an observer that profiles events before and after
23+
/// execution on the provided stream. The events are stored in the Chrome trace
24+
/// event format.
25+
struct ActionProfiler : public ExecutionContext::Observer {
26+
ActionProfiler(raw_ostream &os)
27+
: os(os), startTime(std::chrono::steady_clock::now()) {
28+
os << "[";
29+
}
30+
31+
~ActionProfiler() override { os << "]"; }
32+
33+
void beforeExecute(const ActionActiveStack *action, Breakpoint *breakpoint,
34+
bool willExecute) override;
35+
void afterExecute(const ActionActiveStack *action) override;
36+
37+
private:
38+
void print(const ActionActiveStack *action, llvm::StringRef phase);
39+
40+
raw_ostream &os;
41+
std::chrono::time_point<std::chrono::steady_clock> startTime;
42+
bool printComma = false;
43+
44+
/// A mutex used to guard printing from multiple threads.
45+
std::mutex mutex;
46+
};
47+
48+
} // namespace tracing
49+
} // namespace mlir
50+
51+
#endif // MLIR_TRACING_OBSERVERS_ACTIONPROFILER_H

mlir/lib/Debug/CLOptionsSetup.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mlir/Debug/DebuggerExecutionContextHook.h"
1313
#include "mlir/Debug/ExecutionContext.h"
1414
#include "mlir/Debug/Observers/ActionLogging.h"
15+
#include "mlir/Debug/Observers/ActionProfiler.h"
1516
#include "mlir/IR/MLIRContext.h"
1617
#include "mlir/Support/FileUtilities.h"
1718
#include "llvm/Support/CommandLine.h"
@@ -30,6 +31,12 @@ struct DebugConfigCLOptions : public DebugConfig {
3031
" '-' is passed"),
3132
cl::location(logActionsToFlag)};
3233

34+
static cl::opt<std::string, /*ExternalStorage=*/true> profileActionsTo{
35+
"profile-actions-to",
36+
cl::desc("Profile action execution to a file, or stderr if "
37+
" '-' is passed"),
38+
cl::location(profileActionsToFlag)};
39+
3340
static cl::list<std::string> logActionLocationFilter(
3441
"log-mlir-actions-filter",
3542
cl::desc(
@@ -71,6 +78,7 @@ class InstallDebugHandler::Impl {
7178
public:
7279
Impl(MLIRContext &context, const DebugConfig &config) {
7380
if (config.getLogActionsTo().empty() &&
81+
config.getProfileActionsTo().empty() &&
7482
!config.isDebuggerActionHookEnabled()) {
7583
if (tracing::DebugCounter::isActivated())
7684
context.registerActionHandler(tracing::DebugCounter());
@@ -97,6 +105,24 @@ class InstallDebugHandler::Impl {
97105
actionLogger->addBreakpointManager(locationBreakpoint);
98106
executionContext.registerObserver(actionLogger.get());
99107
}
108+
109+
if (!config.getProfileActionsTo().empty()) {
110+
std::string errorMessage;
111+
profileActionsFile =
112+
openOutputFile(config.getProfileActionsTo(), &errorMessage);
113+
if (!profileActionsFile) {
114+
emitError(UnknownLoc::get(&context),
115+
"Opening file for --profile-actions-to failed: ")
116+
<< errorMessage << "\n";
117+
return;
118+
}
119+
profileActionsFile->keep();
120+
raw_fd_ostream &profileActionsStream = profileActionsFile->os();
121+
actionProfiler =
122+
std::make_unique<tracing::ActionProfiler>(profileActionsStream);
123+
executionContext.registerObserver(actionProfiler.get());
124+
}
125+
100126
if (config.isDebuggerActionHookEnabled()) {
101127
errs() << " (with Debugger hook)";
102128
setupDebuggerExecutionContextHook(executionContext);
@@ -111,6 +137,8 @@ class InstallDebugHandler::Impl {
111137
std::unique_ptr<tracing::ActionLogger> actionLogger;
112138
std::vector<std::unique_ptr<tracing::FileLineColLocBreakpoint>>
113139
locationBreakpoints;
140+
std::unique_ptr<ToolOutputFile> profileActionsFile;
141+
std::unique_ptr<tracing::ActionProfiler> actionProfiler;
114142
};
115143

116144
InstallDebugHandler::InstallDebugHandler(MLIRContext &context,
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===- ActionProfiler.cpp - Profiling Actions *- C++ -*-=====================//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "mlir/Debug/Observers/ActionProfiler.h"
10+
#include "mlir/Debug/BreakpointManager.h"
11+
#include "mlir/IR/Action.h"
12+
#include "mlir/Rewrite/PatternApplicator.h"
13+
#include "llvm/Support/Casting.h"
14+
#include "llvm/Support/Threading.h"
15+
#include "llvm/Support/raw_ostream.h"
16+
#include <chrono>
17+
18+
using namespace mlir;
19+
using namespace mlir::tracing;
20+
21+
//===----------------------------------------------------------------------===//
22+
// ActionProfiler
23+
//===----------------------------------------------------------------------===//
24+
void ActionProfiler::beforeExecute(const ActionActiveStack *action,
25+
Breakpoint *breakpoint, bool willExecute) {
26+
print(action, "B"); // begin event.
27+
}
28+
29+
void ActionProfiler::afterExecute(const ActionActiveStack *action) {
30+
print(action, "E"); // end event.
31+
}
32+
33+
// Print an event in JSON format.
34+
void ActionProfiler::print(const ActionActiveStack *action,
35+
llvm::StringRef phase) {
36+
// Create the event.
37+
std::string str;
38+
llvm::raw_string_ostream event(str);
39+
if (printComma)
40+
event << ",\n";
41+
event << "{";
42+
event << R"("name": ")" << action->getAction().getTag() << "\", ";
43+
event << R"("cat": "PERF", )";
44+
event << R"("ph": ")" << phase << "\", ";
45+
event << R"("pid": 0, )";
46+
event << R"("tid": )" << llvm::get_threadid() << ", ";
47+
auto ts = std::chrono::steady_clock::now() - startTime;
48+
event << R"("ts": )"
49+
<< std::chrono::duration_cast<std::chrono::microseconds>(ts).count();
50+
if (phase == "B") {
51+
event << R"(, "args": {)";
52+
event << R"("desc": ")";
53+
action->getAction().print(event);
54+
event << "\"}";
55+
}
56+
event << "}";
57+
event.flush();
58+
59+
// Print the event, guard with a mutex to ensure the stream is correctly
60+
// formed.
61+
std::lock_guard<std::mutex> guard(mutex);
62+
printComma = true;
63+
os << event.str();
64+
}

mlir/lib/Debug/Observers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_mlir_library(MLIRObservers
22
ActionLogging.cpp
3+
ActionProfiler.cpp
34

45
ADDITIONAL_HEADER_DIRS
56
${MLIR_MAIN_INCLUDE_DIR}/mlir/Debug/Observers

mlir/test/Pass/action-profiler.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: mlir-opt %s --profile-actions-to=- -test-stats-pass -test-module-pass | FileCheck %s
2+
3+
// CHECK: {"name": "pass-execution", "cat": "PERF", "ph": "B", "pid": 0, "tid": {{[0-9]+}}, "ts": {{[0-9]+}}, "args": {"desc": "`pass-execution` running `{{.*}}TestStatisticPass` on Operation `builtin.module`"}},
4+
// CHECK-NEXT: {"name": "pass-execution", "cat": "PERF", "ph": "E", "pid": 0, "tid": {{[0-9]+}}, "ts": {{[0-9]+}}},
5+
// CHECK-NEXT: {"name": "pass-execution", "cat": "PERF", "ph": "B", "pid": 0, "tid": {{[0-9]+}}, "ts": {{[0-9]+}}, "args": {"desc": "`pass-execution` running `{{.*}}TestModulePass` on Operation `builtin.module`"}},
6+
// CHECK-NEXT: {"name": "pass-execution", "cat": "PERF", "ph": "E", "pid": 0, "tid": {{[0-9]+}}, "ts": {{[0-9]+}}}

0 commit comments

Comments
 (0)