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-rc/llvm-rc.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 11 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 189 | ||||
-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 |
12 files changed, 301 insertions, 149 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-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 2867d48..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; }; @@ -1087,26 +1090,25 @@ const EnumEntry<unsigned> ElfObjectFileType[] = { }; const EnumEntry<unsigned> ElfOSABI[] = { - {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE}, - {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX}, - {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD}, - {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX}, - {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD}, - {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS}, - {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX}, - {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX}, - {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD}, - {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64}, - {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO}, - {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD}, - {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS}, - {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK}, - {"AROS", "AROS", ELF::ELFOSABI_AROS}, - {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS}, - {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI}, - {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA}, - {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE} -}; + {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE}, + {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX}, + {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD}, + {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX}, + {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD}, + {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS}, + {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX}, + {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX}, + {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD}, + {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64}, + {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO}, + {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD}, + {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS}, + {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK}, + {"AROS", "AROS", ELF::ELFOSABI_AROS}, + {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS}, + {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI}, + {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA}, + {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}}; const EnumEntry<unsigned> AMDGPUElfOSABI[] = { {"AMDGPU_HSA", "AMDGPU - HSA", ELF::ELFOSABI_AMDGPU_HSA}, @@ -1671,16 +1673,17 @@ const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = { }; const EnumEntry<unsigned> ElfHeaderNVPTXFlags[] = { - ENUM_ENT(EF_CUDA_SM20, "sm_20"), ENUM_ENT(EF_CUDA_SM21, "sm_21"), - ENUM_ENT(EF_CUDA_SM30, "sm_30"), ENUM_ENT(EF_CUDA_SM32, "sm_32"), - ENUM_ENT(EF_CUDA_SM35, "sm_35"), ENUM_ENT(EF_CUDA_SM37, "sm_37"), - ENUM_ENT(EF_CUDA_SM50, "sm_50"), ENUM_ENT(EF_CUDA_SM52, "sm_52"), - ENUM_ENT(EF_CUDA_SM53, "sm_53"), ENUM_ENT(EF_CUDA_SM60, "sm_60"), - ENUM_ENT(EF_CUDA_SM61, "sm_61"), ENUM_ENT(EF_CUDA_SM62, "sm_62"), - ENUM_ENT(EF_CUDA_SM70, "sm_70"), ENUM_ENT(EF_CUDA_SM72, "sm_72"), - ENUM_ENT(EF_CUDA_SM75, "sm_75"), ENUM_ENT(EF_CUDA_SM80, "sm_80"), - ENUM_ENT(EF_CUDA_SM86, "sm_86"), ENUM_ENT(EF_CUDA_SM87, "sm_87"), - ENUM_ENT(EF_CUDA_SM89, "sm_89"), ENUM_ENT(EF_CUDA_SM90, "sm_90"), + ENUM_ENT(EF_CUDA_SM20, "sm_20"), ENUM_ENT(EF_CUDA_SM21, "sm_21"), + ENUM_ENT(EF_CUDA_SM30, "sm_30"), ENUM_ENT(EF_CUDA_SM32, "sm_32"), + ENUM_ENT(EF_CUDA_SM35, "sm_35"), ENUM_ENT(EF_CUDA_SM37, "sm_37"), + ENUM_ENT(EF_CUDA_SM50, "sm_50"), ENUM_ENT(EF_CUDA_SM52, "sm_52"), + ENUM_ENT(EF_CUDA_SM53, "sm_53"), ENUM_ENT(EF_CUDA_SM60, "sm_60"), + ENUM_ENT(EF_CUDA_SM61, "sm_61"), ENUM_ENT(EF_CUDA_SM62, "sm_62"), + ENUM_ENT(EF_CUDA_SM70, "sm_70"), ENUM_ENT(EF_CUDA_SM72, "sm_72"), + ENUM_ENT(EF_CUDA_SM75, "sm_75"), ENUM_ENT(EF_CUDA_SM80, "sm_80"), + ENUM_ENT(EF_CUDA_SM86, "sm_86"), ENUM_ENT(EF_CUDA_SM87, "sm_87"), + ENUM_ENT(EF_CUDA_SM89, "sm_89"), ENUM_ENT(EF_CUDA_SM90, "sm_90"), + ENUM_ENT(EF_CUDA_SM100, "sm_100"), ENUM_ENT(EF_CUDA_SM120, "sm_120"), }; const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = { @@ -3655,10 +3658,16 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { else if (e.e_machine == EM_XTENSA) ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags), unsigned(ELF::EF_XTENSA_MACH)); - else if (e.e_machine == EM_CUDA) + else if (e.e_machine == EM_CUDA) { ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderNVPTXFlags), unsigned(ELF::EF_CUDA_SM)); - else if (e.e_machine == EM_AMDGPU) { + if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V1 && + (e.e_flags & ELF::EF_CUDA_ACCELERATORS_V1)) + ElfFlags += "a"; + else if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V2 && + (e.e_flags & ELF::EF_CUDA_ACCELERATORS)) + ElfFlags += "a"; + } else if (e.e_machine == EM_AMDGPU) { switch (e.e_ident[ELF::EI_ABIVERSION]) { default: break; @@ -6434,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 : @@ -6450,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())), @@ -6459,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. |