diff options
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/bugpoint/bugpoint.cpp | 3 | ||||
-rw-r--r-- | llvm/tools/dsymutil/MachOUtils.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llc/llc.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp | 207 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/Disassembler.cpp | 46 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/Disassembler.h | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/llvm-mc.cpp | 37 | ||||
-rw-r--r-- | llvm/tools/llvm-rc/llvm-rc.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 11 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 119 | ||||
-rw-r--r-- | llvm/tools/opt/NewPMDriver.cpp | 8 | ||||
-rw-r--r-- | llvm/tools/opt/NewPMDriver.h | 2 | ||||
-rw-r--r-- | llvm/tools/opt/optdriver.cpp | 12 | ||||
-rw-r--r-- | llvm/tools/spirv-tools/CMakeLists.txt | 4 |
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. |