aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/bugpoint/bugpoint.cpp3
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp2
-rw-r--r--llvm/tools/llc/llc.cpp4
-rw-r--r--llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp6
-rw-r--r--llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp207
-rw-r--r--llvm/tools/llvm-mc/Disassembler.cpp46
-rw-r--r--llvm/tools/llvm-mc/Disassembler.h3
-rw-r--r--llvm/tools/llvm-mc/llvm-mc.cpp37
-rw-r--r--llvm/tools/llvm-rc/llvm-rc.cpp2
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp11
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp119
-rw-r--r--llvm/tools/opt/NewPMDriver.cpp8
-rw-r--r--llvm/tools/opt/NewPMDriver.h2
-rw-r--r--llvm/tools/opt/optdriver.cpp12
-rw-r--r--llvm/tools/spirv-tools/CMakeLists.txt4
15 files changed, 333 insertions, 133 deletions
diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp
index e49efdf..87581e80a 100644
--- a/llvm/tools/bugpoint/bugpoint.cpp
+++ b/llvm/tools/bugpoint/bugpoint.cpp
@@ -22,6 +22,7 @@
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PluginLoader.h"
@@ -111,7 +112,7 @@ int main(int argc, char **argv) {
initializeInstCombine(Registry);
initializeTarget(Registry);
- if (std::getenv("bar") == (char*) -1) {
+ if (!llvm::getNonFoldableAlwaysTrue()) {
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index be1934f..362a999 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -331,7 +331,7 @@ static bool createDwarfSegment(const MCAssembler& Asm,uint64_t VMAddr, uint64_t
/* InitProt =*/3);
for (unsigned int i = 0, n = Writer.getSectionOrder().size(); i != n; ++i) {
- MCSection *Sec = Writer.getSectionOrder()[i];
+ auto *Sec = static_cast<MCSectionMachO *>(Writer.getSectionOrder()[i]);
if (!Asm.getSectionFileSize(*Sec))
continue;
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 93b4a50..b3d7185 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -733,8 +733,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
reportError("target does not support generation of this file type");
}
- const_cast<TargetLoweringObjectFile *>(Target->getObjFileLowering())
- ->Initialize(MMIWP->getMMI().getContext(), *Target);
+ Target->getObjFileLowering()->Initialize(MMIWP->getMMI().getContext(),
+ *Target);
if (MIR) {
assert(MMIWP && "Forgot to create MMIWP?");
if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
index 676479b..ea830bd 100644
--- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
@@ -651,8 +651,10 @@ static std::vector<MCInst> loadFP64RegBits32(const MCSubtargetInfo &STI,
}
std::vector<MCInst> Instrs = loadIntReg(STI, ScratchIntReg, Bits);
- Instrs.push_back(
- MCInstBuilder(RISCV::FCVT_D_W).addReg(Reg).addReg(ScratchIntReg));
+ Instrs.push_back(MCInstBuilder(RISCV::FCVT_D_W)
+ .addReg(Reg)
+ .addReg(ScratchIntReg)
+ .addImm(RISCVFPRndMode::RNE));
return Instrs;
}
diff --git a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
index e1e5fad..f6ed94b 100644
--- a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
+++ b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp
@@ -9,13 +9,20 @@
/// \file
/// This file implements the IR2Vec embedding generation tool.
///
-/// This tool provides two main functionalities:
+/// This tool provides three main modes:
///
/// 1. Triplet Generation Mode (--mode=triplets):
-/// Generates triplets (opcode, type, operands) for vocabulary training.
-/// Usage: llvm-ir2vec --mode=triplets input.bc -o triplets.txt
+/// Generates numeric triplets (head, tail, relation) for vocabulary
+/// training. Output format: MAX_RELATION=N header followed by
+/// head\ttail\trelation lines. Relations: 0=Type, 1=Next, 2+=Arg0,Arg1,...
+/// Usage: llvm-ir2vec --mode=triplets input.bc -o train2id.txt
///
-/// 2. Embedding Generation Mode (--mode=embeddings):
+/// 2. Entities Generation Mode (--mode=entities):
+/// Generates entity mappings for vocabulary training.
+/// Output format: <total_entities> header followed by entity\tid lines.
+/// Usage: llvm-ir2vec --mode=entities input.bc -o entity2id.txt
+///
+/// 3. Embedding Generation Mode (--mode=embeddings):
/// Generates IR2Vec embeddings using a trained vocabulary.
/// Usage: llvm-ir2vec --mode=embeddings --ir2vec-vocab-path=vocab.json
/// --level=func input.bc -o embeddings.txt Levels: --level=inst
@@ -60,16 +67,19 @@ static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
enum ToolMode {
TripletMode, // Generate triplets for vocabulary training
+ EntityMode, // Generate entity mappings for vocabulary training
EmbeddingMode // Generate embeddings using trained vocabulary
};
-static cl::opt<ToolMode>
- Mode("mode", cl::desc("Tool operation mode:"),
- cl::values(clEnumValN(TripletMode, "triplets",
- "Generate triplets for vocabulary training"),
- clEnumValN(EmbeddingMode, "embeddings",
- "Generate embeddings using trained vocabulary")),
- cl::init(EmbeddingMode), cl::cat(IR2VecToolCategory));
+static cl::opt<ToolMode> Mode(
+ "mode", cl::desc("Tool operation mode:"),
+ cl::values(clEnumValN(TripletMode, "triplets",
+ "Generate triplets for vocabulary training"),
+ clEnumValN(EntityMode, "entities",
+ "Generate entity mappings for vocabulary training"),
+ clEnumValN(EmbeddingMode, "embeddings",
+ "Generate embeddings using trained vocabulary")),
+ cl::init(EmbeddingMode), cl::cat(IR2VecToolCategory));
static cl::opt<std::string>
FunctionName("function", cl::desc("Process specific function only"),
@@ -94,6 +104,13 @@ static cl::opt<EmbeddingLevel>
namespace {
+/// Relation types for triplet generation
+enum RelationType {
+ TypeRelation = 0, ///< Instruction to type relationship
+ NextRelation = 1, ///< Sequential instruction relationship
+ ArgRelation = 2 ///< Instruction to operand relationship (ArgRelation + N)
+};
+
/// Helper class for collecting IR triplets and generating embeddings
class IR2VecTool {
private:
@@ -111,29 +128,101 @@ public:
// option
MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
MAM.registerPass([&] { return IR2VecVocabAnalysis(); });
+ // This will throw an error if vocab is not found or invalid
Vocab = &MAM.getResult<IR2VecVocabAnalysis>(M);
return Vocab->isValid();
}
- /// Generate triplets for the entire module
+ /// Generate triplets for the module
+ /// Output format: MAX_RELATION=N header followed by relationships
void generateTriplets(raw_ostream &OS) const {
- for (const Function &F : M)
- generateTriplets(F, OS);
+ unsigned MaxRelation = NextRelation; // Track maximum relation ID
+ std::string Relationships;
+ raw_string_ostream RelOS(Relationships);
+
+ for (const Function &F : M) {
+ unsigned FuncMaxRelation = generateTriplets(F, RelOS);
+ MaxRelation = std::max(MaxRelation, FuncMaxRelation);
+ }
+
+ RelOS.flush();
+
+ // Write metadata header followed by relationships
+ OS << "MAX_RELATION=" << MaxRelation << '\n';
+ OS << Relationships;
}
/// Generate triplets for a single function
- void generateTriplets(const Function &F, raw_ostream &OS) const {
+ /// Returns the maximum relation ID used in this function
+ unsigned generateTriplets(const Function &F, raw_ostream &OS) const {
if (F.isDeclaration())
- return;
+ return 0;
+
+ unsigned MaxRelation = 1;
+ unsigned PrevOpcode = 0;
+ bool HasPrevOpcode = false;
+
+ for (const BasicBlock &BB : F) {
+ for (const auto &I : BB.instructionsWithoutDebug()) {
+ unsigned Opcode = Vocabulary::getNumericID(I.getOpcode());
+ unsigned TypeID = Vocabulary::getNumericID(I.getType()->getTypeID());
+
+ // Add "Next" relationship with previous instruction
+ if (HasPrevOpcode) {
+ OS << PrevOpcode << '\t' << Opcode << '\t' << NextRelation << '\n';
+ LLVM_DEBUG(dbgs()
+ << Vocabulary::getVocabKeyForOpcode(PrevOpcode + 1) << '\t'
+ << Vocabulary::getVocabKeyForOpcode(Opcode + 1) << '\t'
+ << "Next\n");
+ }
- std::string LocalOutput;
- raw_string_ostream LocalOS(LocalOutput);
+ // Add "Type" relationship
+ OS << Opcode << '\t' << TypeID << '\t' << TypeRelation << '\n';
+ LLVM_DEBUG(
+ dbgs() << Vocabulary::getVocabKeyForOpcode(Opcode + 1) << '\t'
+ << Vocabulary::getVocabKeyForTypeID(I.getType()->getTypeID())
+ << '\t' << "Type\n");
+
+ // Add "Arg" relationships
+ unsigned ArgIndex = 0;
+ for (const Use &U : I.operands()) {
+ unsigned OperandID = Vocabulary::getNumericID(U.get());
+ unsigned RelationID = ArgRelation + ArgIndex;
+ OS << Opcode << '\t' << OperandID << '\t' << RelationID << '\n';
+
+ LLVM_DEBUG({
+ StringRef OperandStr = Vocabulary::getVocabKeyForOperandKind(
+ Vocabulary::getOperandKind(U.get()));
+ dbgs() << Vocabulary::getVocabKeyForOpcode(Opcode + 1) << '\t'
+ << OperandStr << '\t' << "Arg" << ArgIndex << '\n';
+ });
+
+ ++ArgIndex;
+ }
+ // Only update MaxRelation if there were operands
+ if (ArgIndex > 0) {
+ MaxRelation = std::max(MaxRelation, ArgRelation + ArgIndex - 1);
+ }
+ PrevOpcode = Opcode;
+ HasPrevOpcode = true;
+ }
+ }
- for (const BasicBlock &BB : F)
- traverseBasicBlock(BB, LocalOS);
+ return MaxRelation;
+ }
- LocalOS.flush();
- OS << LocalOutput;
+ /// Dump entity ID to string mappings
+ static void generateEntityMappings(raw_ostream &OS) {
+ // FIXME: Currently, the generated entity mappings are not one-to-one;
+ // Multiple TypeIDs map to same string key (Like Half, BFloat, etc. map to
+ // FloatTy). This would hinder learning good seed embeddings.
+ // We should fix this in the future by ensuring unique string keys either by
+ // post-processing here without changing the mapping in ir2vec::Vocabulary,
+ // or by changing the Vocabulary generation logic to ensure unique keys.
+ auto EntityLen = Vocabulary::expectedSize();
+ OS << EntityLen << "\n";
+ for (unsigned EntityID = 0; EntityID < EntityLen; ++EntityID)
+ OS << Vocabulary::getStringKey(EntityID) << '\t' << EntityID << '\n';
}
/// Generate embeddings for the entire module
@@ -197,31 +286,6 @@ public:
}
}
}
-
-private:
- /// Process a single basic block for triplet generation
- void traverseBasicBlock(const BasicBlock &BB, raw_string_ostream &OS) const {
- // Consider only non-debug and non-pseudo instructions
- for (const auto &I : BB.instructionsWithoutDebug()) {
- StringRef OpcStr = Vocabulary::getVocabKeyForOpcode(I.getOpcode());
- StringRef TypeStr =
- Vocabulary::getVocabKeyForTypeID(I.getType()->getTypeID());
-
- OS << '\n' << OpcStr << ' ' << TypeStr << ' ';
-
- LLVM_DEBUG({
- I.print(dbgs());
- dbgs() << "\n";
- I.getType()->print(dbgs());
- dbgs() << " Type\n";
- });
-
- for (const Use &U : I.operands())
- OS << Vocabulary::getVocabKeyForOperandKind(
- Vocabulary::getOperandKind(U.get()))
- << ' ';
- }
- }
};
Error processModule(Module &M, raw_ostream &OS) {
@@ -230,11 +294,9 @@ Error processModule(Module &M, raw_ostream &OS) {
if (Mode == EmbeddingMode) {
// Initialize vocabulary for embedding generation
// Note: Requires --ir2vec-vocab-path option to be set
- if (!Tool.initializeVocabulary())
- return createStringError(
- errc::invalid_argument,
- "Failed to initialize IR2Vec vocabulary. "
- "Make sure to specify --ir2vec-vocab-path for embedding mode.");
+ auto VocabStatus = Tool.initializeVocabulary();
+ assert(VocabStatus && "Failed to initialize IR2Vec vocabulary");
+ (void)VocabStatus;
if (!FunctionName.empty()) {
// Process single function
@@ -249,18 +311,7 @@ Error processModule(Module &M, raw_ostream &OS) {
Tool.generateEmbeddings(OS);
}
} else {
- // Triplet generation mode - no vocabulary needed
- if (!FunctionName.empty())
- // Process single function
- if (const Function *F = M.getFunction(FunctionName))
- Tool.generateTriplets(*F, OS);
- else
- return createStringError(errc::invalid_argument,
- "Function '%s' not found",
- FunctionName.c_str());
- else
- // Process all functions
- Tool.generateTriplets(OS);
+ Tool.generateTriplets(OS);
}
return Error::success();
}
@@ -284,8 +335,25 @@ int main(int argc, char **argv) {
"information.\n");
// Validate command line options
- if (Mode == TripletMode && Level.getNumOccurrences() > 0)
- errs() << "Warning: --level option is ignored in triplet mode\n";
+ if (Mode != EmbeddingMode) {
+ if (Level.getNumOccurrences() > 0)
+ errs() << "Warning: --level option is ignored\n";
+ if (FunctionName.getNumOccurrences() > 0)
+ errs() << "Warning: --function option is ignored\n";
+ }
+
+ std::error_code EC;
+ raw_fd_ostream OS(OutputFilename, EC);
+ if (EC) {
+ errs() << "Error opening output file: " << EC.message() << "\n";
+ return 1;
+ }
+
+ if (Mode == EntityMode) {
+ // Just dump entity mappings without processing any IR
+ IR2VecTool::generateEntityMappings(OS);
+ return 0;
+ }
// Parse the input LLVM IR file or stdin
SMDiagnostic Err;
@@ -296,13 +364,6 @@ int main(int argc, char **argv) {
return 1;
}
- std::error_code EC;
- raw_fd_ostream OS(OutputFilename, EC);
- if (EC) {
- errs() << "Error opening output file: " << EC.message() << "\n";
- return 1;
- }
-
if (Error Err = processModule(*M, OS)) {
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EIB) {
errs() << "Error: " << EIB.message() << "\n";
diff --git a/llvm/tools/llvm-mc/Disassembler.cpp b/llvm/tools/llvm-mc/Disassembler.cpp
index 8672793..2ee4221 100644
--- a/llvm/tools/llvm-mc/Disassembler.cpp
+++ b/llvm/tools/llvm-mc/Disassembler.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
@@ -32,24 +33,29 @@ using namespace llvm;
typedef std::pair<std::vector<unsigned char>, std::vector<const char *>>
ByteArrayTy;
-static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
+static MCDisassembler::DecodeStatus getInstruction(const MCDisassembler &DisAsm,
+ const MCSubtargetInfo &STI,
+ MCInst &Inst, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes,
+ uint64_t Address) {
+ if (STI.getTargetTriple().getArch() == Triple::hexagon)
+ return DisAsm.getInstructionBundle(Inst, Size, Bytes, Address, nulls());
+ return DisAsm.getInstruction(Inst, Size, Bytes, Address, nulls());
+}
+
+static bool printInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
SourceMgr &SM, MCStreamer &Streamer, bool InAtomicBlock,
- const MCSubtargetInfo &STI) {
+ const MCSubtargetInfo &STI, unsigned NumBenchmarkRuns) {
ArrayRef<uint8_t> Data(Bytes.first);
// Disassemble it to strings.
uint64_t Size;
- uint64_t Index;
- for (Index = 0; Index < Bytes.first.size(); Index += Size) {
- MCInst Inst;
+ for (uint64_t Index = 0; Index < Bytes.first.size(); Index += Size) {
- MCDisassembler::DecodeStatus S;
- if (STI.getTargetTriple().getArch() == Triple::hexagon)
- S = DisAsm.getInstructionBundle(Inst, Size, Data.slice(Index), Index,
- nulls());
- else
- S = DisAsm.getInstruction(Inst, Size, Data.slice(Index), Index, nulls());
+ MCInst Inst;
+ MCDisassembler::DecodeStatus S =
+ getInstruction(DisAsm, STI, Inst, Size, Data.slice(Index), Index);
switch (S) {
case MCDisassembler::Fail:
SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]),
@@ -74,6 +80,18 @@ static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
Streamer.emitInstruction(Inst, STI);
break;
}
+
+ if (S == MCDisassembler::Success && NumBenchmarkRuns != 0) {
+ // Benchmark mode, collect timing for decoding the instruction several
+ // times.
+ MCInst BMInst;
+ TimeTraceScope timeScope("getInstruction");
+ for (unsigned I = 0; I < NumBenchmarkRuns; ++I) {
+ BMInst.clear();
+ BMInst.setOpcode(0);
+ S = getInstruction(DisAsm, STI, BMInst, Size, Data.slice(Index), Index);
+ }
+ }
}
return false;
@@ -151,7 +169,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
MCSubtargetInfo &STI, MCStreamer &Streamer,
MemoryBuffer &Buffer, SourceMgr &SM,
MCContext &Ctx, const MCTargetOptions &MCOptions,
- bool HexBytes) {
+ bool HexBytes, unsigned NumBenchmarkRuns) {
std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
if (!MRI) {
errs() << "error: no register info for target " << Triple << "\n";
@@ -207,8 +225,8 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
ErrorOccurred |= byteArrayFromString(ByteArray, Str, SM, HexBytes);
if (!ByteArray.first.empty())
- ErrorOccurred |=
- PrintInsts(*DisAsm, ByteArray, SM, Streamer, InAtomicBlock, STI);
+ ErrorOccurred |= printInsts(*DisAsm, ByteArray, SM, Streamer,
+ InAtomicBlock, STI, NumBenchmarkRuns);
}
if (InAtomicBlock) {
diff --git a/llvm/tools/llvm-mc/Disassembler.h b/llvm/tools/llvm-mc/Disassembler.h
index 5efffca..5ee47d5 100644
--- a/llvm/tools/llvm-mc/Disassembler.h
+++ b/llvm/tools/llvm-mc/Disassembler.h
@@ -32,7 +32,8 @@ public:
static int disassemble(const Target &T, const std::string &Triple,
MCSubtargetInfo &STI, MCStreamer &Streamer,
MemoryBuffer &Buffer, SourceMgr &SM, MCContext &Ctx,
- const MCTargetOptions &MCOptions, bool HexBytes);
+ const MCTargetOptions &MCOptions, bool HexBytes,
+ unsigned NumBenchmarkRuns);
};
} // namespace llvm
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index da89af7..f69f7c7 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Disassembler.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameAnalyzer.h"
#include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.h"
#include "llvm/MC/MCAsmBackend.h"
@@ -37,6 +38,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/TargetParser/Host.h"
@@ -240,6 +242,23 @@ static cl::opt<ActionType> Action(
"Colored disassembly of strings of hex bytes")),
cl::cat(MCCategory));
+static cl::opt<unsigned>
+ NumBenchmarkRuns("runs", cl::desc("Number of runs for benchmarking"),
+ cl::cat(MCCategory));
+
+static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
+
+static cl::opt<unsigned> TimeTraceGranularity(
+ "time-trace-granularity",
+ cl::desc(
+ "Minimum time granularity (in microseconds) traced by time profiler"),
+ cl::init(500), cl::Hidden);
+
+static cl::opt<std::string>
+ TimeTraceFile("time-trace-file",
+ cl::desc("Specify time trace file destination"),
+ cl::value_desc("filename"));
+
static const Target *GetTarget(const char *ProgName) {
// Figure out the target triple.
if (TripleName.empty())
@@ -371,6 +390,20 @@ int main(int argc, char **argv) {
cl::HideUnrelatedOptions({&MCCategory, &getColorCategory()});
cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
+
+ if (TimeTrace)
+ timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
+
+ auto TimeTraceScopeExit = make_scope_exit([]() {
+ if (!TimeTrace)
+ return;
+ if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
+ logAllUnhandledErrors(std::move(E), errs());
+ return;
+ }
+ timeTraceProfilerCleanup();
+ });
+
MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
MCOptions.CompressDebugSections = CompressDebugSections.getValue();
MCOptions.ShowMCInst = ShowInst;
@@ -620,7 +653,8 @@ int main(int argc, char **argv) {
}
if (disassemble)
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer,
- SrcMgr, Ctx, MCOptions, HexBytes);
+ SrcMgr, Ctx, MCOptions, HexBytes,
+ NumBenchmarkRuns);
// Keep output if no errors.
if (Res == 0) {
@@ -628,5 +662,6 @@ int main(int argc, char **argv) {
if (DwoOut)
DwoOut->keep();
}
+
return Res;
}
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index 7362154..f623342 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -201,7 +201,7 @@ std::string getMingwTriple() {
Triple T(sys::getDefaultTargetTriple());
if (!isUsableArch(T.getArch()))
T.setArch(getDefaultFallbackArch());
- if (T.isWindowsGNUEnvironment())
+ if (T.isOSCygMing())
return T.str();
// Write out the literal form of the vendor/env here, instead of
// constructing them with enum values (which end up with them in
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index dce8e60..96e0a634 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -412,10 +412,19 @@ const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE),
};
+// clang-format off
static const EnumEntry<COFF::ExtendedDLLCharacteristics>
PEExtendedDLLCharacteristics[] = {
- LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_1 ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_2 ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_FORWARD_CFI_COMPAT ),
+ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE ),
};
+// clang-format on
static const EnumEntry<COFF::SectionCharacteristics>
ImageSectionCharacteristics[] = {
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 2699e10..94ce386 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -424,6 +424,9 @@ protected:
ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const;
+ void printSFrameHeader(const SFrameParser<ELFT::Endianness> &Parser);
+ void printSFrameFDEs(const SFrameParser<ELFT::Endianness> &Parser);
+
private:
mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap;
};
@@ -6440,6 +6443,90 @@ template <typename ELFT> void ELFDumper<ELFT>::printMemtag() {
}
template <typename ELFT>
+void ELFDumper<ELFT>::printSFrameHeader(
+ const SFrameParser<ELFT::Endianness> &Parser) {
+ DictScope HeaderScope(W, "Header");
+
+ const sframe::Preamble<ELFT::Endianness> &Preamble = Parser.getPreamble();
+ W.printHex("Magic", Preamble.Magic.value());
+ W.printEnum("Version", Preamble.Version.value(), sframe::getVersions());
+ W.printFlags("Flags", Preamble.Flags.value(), sframe::getFlags());
+
+ const sframe::Header<ELFT::Endianness> &Header = Parser.getHeader();
+ W.printEnum("ABI", Header.ABIArch.value(), sframe::getABIs());
+
+ W.printNumber(("CFA fixed FP offset" +
+ Twine(Parser.usesFixedFPOffset() ? "" : " (unused)"))
+ .str(),
+ Header.CFAFixedFPOffset.value());
+
+ W.printNumber(("CFA fixed RA offset" +
+ Twine(Parser.usesFixedRAOffset() ? "" : " (unused)"))
+ .str(),
+ Header.CFAFixedRAOffset.value());
+
+ W.printNumber("Auxiliary header length", Header.AuxHdrLen.value());
+ W.printNumber("Num FDEs", Header.NumFDEs.value());
+ W.printNumber("Num FREs", Header.NumFREs.value());
+ W.printNumber("FRE subsection length", Header.FRELen.value());
+ W.printNumber("FDE subsection offset", Header.FDEOff.value());
+ W.printNumber("FRE subsection offset", Header.FREOff.value());
+
+ if (Expected<ArrayRef<uint8_t>> Aux = Parser.getAuxHeader())
+ W.printHexList("Auxiliary header", *Aux);
+ else
+ reportWarning(Aux.takeError(), FileName);
+}
+
+template <typename ELFT>
+void ELFDumper<ELFT>::printSFrameFDEs(
+ const SFrameParser<ELFT::Endianness> &Parser) {
+ typename SFrameParser<ELFT::Endianness>::FDERange FDEs;
+ if (Error Err = Parser.fdes().moveInto(FDEs)) {
+ reportWarning(std::move(Err), FileName);
+ return;
+ }
+
+ ListScope IndexScope(W, "Function Index");
+ for (auto It = FDEs.begin(); It != FDEs.end(); ++It) {
+ DictScope FDEScope(
+ W,
+ formatv("FuncDescEntry [{0}]", std::distance(FDEs.begin(), It)).str());
+
+ W.printHex("PC", Parser.getAbsoluteStartAddress(It));
+ W.printHex("Size", It->Size);
+ W.printHex("Start FRE Offset", It->StartFREOff);
+ W.printNumber("Num FREs", It->NumFREs);
+
+ {
+ DictScope InfoScope(W, "Info");
+ W.printEnum("FRE Type", It->getFREType(), sframe::getFRETypes());
+ W.printEnum("FDE Type", It->getFDEType(), sframe::getFDETypes());
+ switch (Parser.getHeader().ABIArch) {
+ case sframe::ABI::AArch64EndianBig:
+ case sframe::ABI::AArch64EndianLittle:
+ W.printEnum("PAuth Key", sframe::AArch64PAuthKey(It->getPAuthKey()),
+ sframe::getAArch64PAuthKeys());
+ break;
+ case sframe::ABI::AMD64EndianLittle:
+ // unused
+ break;
+ }
+
+ W.printHex("Raw", It->Info);
+ }
+
+ W.printHex(
+ ("Repetitive block size" +
+ Twine(It->getFDEType() == sframe::FDEType::PCMask ? "" : " (unused)"))
+ .str(),
+ It->RepSize);
+
+ W.printHex("Padding2", It->Padding2);
+ }
+}
+
+template <typename ELFT>
void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
constexpr endianness E = ELFT::Endianness;
for (object::SectionRef Section :
@@ -6456,8 +6543,8 @@ void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
continue;
}
- Expected<object::SFrameParser<E>> Parser =
- object::SFrameParser<E>::create(arrayRefFromStringRef(SectionContent));
+ Expected<object::SFrameParser<E>> Parser = object::SFrameParser<E>::create(
+ arrayRefFromStringRef(SectionContent), Section.getAddress());
if (!Parser) {
reportWarning(createError("invalid sframe section: " +
toString(Parser.takeError())),
@@ -6465,32 +6552,8 @@ void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
continue;
}
- DictScope HeaderScope(W, "Header");
-
- const sframe::Preamble<E> &Preamble = Parser->getPreamble();
- W.printHex("Magic", Preamble.Magic.value());
- W.printEnum("Version", Preamble.Version.value(), sframe::getVersions());
- W.printFlags("Flags", Preamble.Flags.value(), sframe::getFlags());
-
- const sframe::Header<E> &Header = Parser->getHeader();
- W.printEnum("ABI", Header.ABIArch.value(), sframe::getABIs());
-
- W.printNumber(("CFA fixed FP offset" +
- Twine(Parser->usesFixedFPOffset() ? "" : " (unused)"))
- .str(),
- Header.CFAFixedFPOffset.value());
-
- W.printNumber(("CFA fixed RA offset" +
- Twine(Parser->usesFixedRAOffset() ? "" : " (unused)"))
- .str(),
- Header.CFAFixedRAOffset.value());
-
- W.printNumber("Auxiliary header length", Header.AuxHdrLen.value());
- W.printNumber("Num FDEs", Header.NumFDEs.value());
- W.printNumber("Num FREs", Header.NumFREs.value());
- W.printNumber("FRE subsection length", Header.FRELen.value());
- W.printNumber("FDE subsection offset", Header.FDEOff.value());
- W.printNumber("FRE subsection offset", Header.FREOff.value());
+ printSFrameHeader(*Parser);
+ printSFrameFDEs(*Parser);
}
}
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 7d168a6..b9b8929 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -40,6 +40,7 @@
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/Debugify.h"
+#include "llvm/Transforms/Utils/ProfileVerify.h"
using namespace llvm;
using namespace opt_tool;
@@ -356,7 +357,7 @@ bool llvm::runPassPipeline(
OutputKind OK, VerifierKind VK, bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder, bool EmitSummaryIndex,
bool EmitModuleHash, bool EnableDebugify, bool VerifyDIPreserve,
- bool UnifiedLTO) {
+ bool EnableProfcheck, bool UnifiedLTO) {
auto FS = vfs::getRealFileSystem();
std::optional<PGOOptions> P;
switch (PGOKindFlag) {
@@ -487,7 +488,8 @@ bool llvm::runPassPipeline(
if (VerifyDIPreserve)
MPM.addPass(NewPMDebugifyPass(DebugifyMode::OriginalDebugInfo, "",
&DebugInfoBeforePass));
-
+ if (EnableProfcheck)
+ MPM.addPass(createModuleToFunctionPassAdaptor(ProfileInjectorPass()));
// Add passes according to the -passes options.
if (!PassPipeline.empty()) {
if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) {
@@ -504,6 +506,8 @@ bool llvm::runPassPipeline(
MPM.addPass(NewPMCheckDebugifyPass(
false, "", nullptr, DebugifyMode::OriginalDebugInfo,
&DebugInfoBeforePass, VerifyDIPreserveExport));
+ if (EnableProfcheck)
+ MPM.addPass(createModuleToFunctionPassAdaptor(ProfileVerifierPass()));
// Add any relevant output pass at the end of the pipeline.
switch (OK) {
diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h
index 2daae57..6c21d6c 100644
--- a/llvm/tools/opt/NewPMDriver.h
+++ b/llvm/tools/opt/NewPMDriver.h
@@ -75,7 +75,7 @@ bool runPassPipeline(
bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder, bool EmitSummaryIndex,
bool EmitModuleHash, bool EnableDebugify, bool VerifyDIPreserve,
- bool UnifiedLTO = false);
+ bool EnableProfcheck, bool UnifiedLTO = false);
} // namespace llvm
#endif
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 892b63b..4a3b058 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -217,6 +217,15 @@ static cl::opt<bool> VerifyDebugInfoPreserve(
cl::desc("Start the pipeline with collecting and end it with checking of "
"debug info preservation."));
+static cl::opt<bool> EnableProfileVerification(
+ "enable-profcheck",
+#if defined(LLVM_ENABLE_PROFCHECK)
+ cl::init(true),
+#else
+ cl::init(false),
+#endif
+ cl::desc("Start the pipeline with prof-inject and end it with prof-check"));
+
static cl::opt<std::string> ClDataLayout("data-layout",
cl::desc("data layout string to use"),
cl::value_desc("layout-string"),
@@ -746,7 +755,8 @@ extern "C" int optMain(
RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks,
OK, VK, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash,
- EnableDebugify, VerifyDebugInfoPreserve, UnifiedLTO)
+ EnableDebugify, VerifyDebugInfoPreserve,
+ EnableProfileVerification, UnifiedLTO)
? 0
: 1;
}
diff --git a/llvm/tools/spirv-tools/CMakeLists.txt b/llvm/tools/spirv-tools/CMakeLists.txt
index c2c0f3e..5db7aec 100644
--- a/llvm/tools/spirv-tools/CMakeLists.txt
+++ b/llvm/tools/spirv-tools/CMakeLists.txt
@@ -5,10 +5,6 @@ if (NOT LLVM_INCLUDE_SPIRV_TOOLS_TESTS)
return()
endif ()
-if (NOT "SPIRV" IN_LIST LLVM_TARGETS_TO_BUILD)
- message(FATAL_ERROR "Building SPIRV-Tools tests is unsupported without the SPIR-V target")
-endif ()
-
# SPIRV_DIS, SPIRV_VAL, SPIRV_AS and SPIRV_LINK variables can be used to provide paths to existing
# spirv-dis, spirv-val, spirv-as, and spirv-link binaries, respectively. Otherwise, build them from
# SPIRV-Tools source.