diff --git a/.gitattributes b/.gitattributes index e7d6fd6d93d99734bdec6eb7827570673fea58ce..a16d741a7e746f8ec70fe76511ff9a37136427a2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,11 @@ # binary files test/Object/Inputs/*.a-* binary -test/tools/dsymutil/Inputs/* binary +test/tools/dsymutil/Inputs/*.o binary +test/tools/dsymutil/Inputs/*.a binary +test/tools/dsymutil/Inputs/*.i386 binary +test/tools/dsymutil/Inputs/*.x86_64 binary +test/tools/dsymutil/Inputs/*.armv7m binary +test/tools/dsymutil/Inputs/*.dylib binary test/tools/llvm-ar/Inputs/*.lib binary test/tools/llvm-objdump/Inputs/*.a binary test/tools/llvm-rc/Inputs/* binary diff --git a/CMakeLists.txt b/CMakeLists.txt index 4513304079a2ec524def963e52125cfc4daffb2b..a22e6e9fcd2b77867bce08206b02cd83ffa65d8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,9 +194,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1) option(LLVM_INSTALL_BINUTILS_SYMLINKS "Install symlinks from the binutils tool names to the corresponding LLVM tools." OFF) -option(LLVM_INSTALL_CCTOOLS_SYMLINKS - "Install symlinks from the cctools tool names to the corresponding LLVM tools." OFF) - option(LLVM_INSTALL_UTILS "Include utility binaries in the 'install' target." OFF) option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) @@ -366,6 +363,8 @@ set(LLVM_ENABLE_LIBXML2 "ON" CACHE STRING "Use libxml2 if available. Can be ON, option(LLVM_ENABLE_LIBEDIT "Use libedit if available." ON) +option(LLVM_ENABLE_LIBPFM "Use libpfm for performance counters if available." ON) + option(LLVM_ENABLE_THREADS "Use threads if available." ON) option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON) @@ -439,6 +438,7 @@ endif( LLVM_USE_OPROFILE ) set(LLVM_USE_SANITIZER "" CACHE STRING "Define the sanitizer used to build binaries and tests.") +option(LLVM_OPTIMIZE_SANITIZED_BUILDS "Pass -O1 on debug sanitizer builds" ON) set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH "Path to fuzzing library for linking with fuzz targets") @@ -520,6 +520,7 @@ option (LLVM_INCLUDE_DOCS "Generate build targets for llvm documentation." ON) option (LLVM_ENABLE_DOXYGEN "Use doxygen to generate llvm API documentation." OFF) option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF) option (LLVM_ENABLE_OCAMLDOC "Build OCaml bindings documentation." ON) +option (LLVM_ENABLE_BINDINGS "Build bindings." ON) set(LLVM_INSTALL_DOXYGEN_HTML_DIR "share/doc/llvm/doxygen-html" CACHE STRING "Doxygen-generated HTML documentation install directory") @@ -744,9 +745,6 @@ configure_file( configure_file( ${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/abi-breaking.h.cmake ${LLVM_INCLUDE_DIR}/llvm/Config/abi-breaking.h) -configure_file( - ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/DataTypes.h.cmake - ${LLVM_INCLUDE_DIR}/llvm-c/DataTypes.h) # Add target for generating source rpm package. set(LLVM_SRPM_USER_BINARY_SPECFILE ${CMAKE_CURRENT_SOURCE_DIR}/llvm.spec.in @@ -1001,7 +999,7 @@ if(LLVM_DISTRIBUTION_COMPONENTS) add_custom_target(distribution) add_custom_target(install-distribution) add_custom_target(install-distribution-stripped) - foreach(target ${LLVM_DISTRIBUTION_COMPONENTS}) + foreach(target ${LLVM_DISTRIBUTION_COMPONENTS} ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) if(TARGET ${target}) add_dependencies(distribution ${target}) else() diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index 8bc1c5d69f80a0e87b95a34f3c1ca62b02c220c9..14b51e4ff3eed79b6f2ef234f5d72297795b0fd8 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -61,13 +61,18 @@ E: peter@pcc.me.uk D: llgo, libLTO (lib/LTO/* tools/lto/*), LLVM Bitcode (lib/Bitcode/* include/llvm/Bitcode/*) N: Quentin Colombet -E: qcolombet@apple.com +E: quentin.colombet@gmail.com D: Loop Strength Reduction, Register allocators N: Simon Dardis E: simon.dardis@mips.com D: MIPS Backend (lib/Target/Mips/*) +N: Andrea Di Biagio +E: andrea.dibiagio@sony.com +E: andrea.dibiagio@gmail.com +D: llvm-mca + N: Duncan P. N. Exon Smith E: dexonsmith@apple.com D: Branch weights and BlockFrequencyInfo @@ -212,4 +217,4 @@ D: Release management (x.y.0 releases) N: whitequark E: whitequark@whitequark.org -D: OCaml bindings +D: C API, OCaml bindings diff --git a/CREDITS.TXT b/CREDITS.TXT index f3b9fc94dc0f6cdcfd58b52c4f43515d2a8ecd9e..a66697d81eb516c22707cf766ec945b7fcd50109 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -23,7 +23,8 @@ D: MingW Win32 API portability layer N: Aaron Ballman E: aaron@aaronballman.com -D: __declspec attributes, Windows support, general bug fixing +D: Clang frontend, frontend attributes, Windows support, general bug fixing +I: AaronBallman N: Nate Begeman E: natebegeman@mac.com @@ -107,8 +108,8 @@ E: stefanus.du.toit@intel.com D: Bug fixes and minor improvements N: Rafael Avila de Espindola -E: rafael.espindola@gmail.com -D: The ARM backend +E: rafael@espindo.la +D: MC and LLD work N: Dave Estes E: cestes@codeaurora.org @@ -224,6 +225,11 @@ N: Rod Kay E: rkay@auroraux.org D: Author of LLVM Ada bindings +N: Erich Keane +E: erich.keane@intel.com +D: A variety of Clang contributions including function multiversioning, regcall/vectorcall. +I: ErichKeane + N: Eric Kidd W: http://randomhacks.net/ D: llvm-config script diff --git a/bindings/go/llvm/DIBuilderBindings.cpp b/bindings/go/llvm/DIBuilderBindings.cpp deleted file mode 100644 index ea53694b9c1367260a19b6f84b25efac8cd28c2f..0000000000000000000000000000000000000000 --- a/bindings/go/llvm/DIBuilderBindings.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//===- DIBuilderBindings.cpp - Bindings for DIBuilder ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines C bindings for the DIBuilder class. -// -//===----------------------------------------------------------------------===// - -#include "DIBuilderBindings.h" -#include "IRBindings.h" -#include "llvm/IR/DIBuilder.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Module.h" - -using namespace llvm; - -LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) { - Module *m = unwrap(mref); - return wrap(new DIBuilder(*m)); -} - -void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) { - DIBuilder *d = unwrap(dref); - delete d; -} - -LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref, - LLVMMetadataRef Scope, - LLVMMetadataRef File, - unsigned Line, - unsigned Column) { - DIBuilder *D = unwrap(Dref); - auto *LB = D->createLexicalBlock(unwrap(Scope), - unwrap(File), Line, Column); - return wrap(LB); -} - -LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref, - LLVMMetadataRef Scope, - LLVMMetadataRef File, - unsigned Discriminator) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createLexicalBlockFile(unwrap(Scope), - unwrap(File), Discriminator)); -} - -LLVMMetadataRef LLVMDIBuilderCreateFunction( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - const char *LinkageName, LLVMMetadataRef File, unsigned Line, - LLVMMetadataRef CompositeType, int IsLocalToUnit, int IsDefinition, - unsigned ScopeLine, unsigned Flags, int IsOptimized) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createFunction( - unwrap(Scope), Name, LinkageName, - File ? unwrap(File) : nullptr, Line, - unwrap(CompositeType), IsLocalToUnit, IsDefinition, - ScopeLine, static_cast(Flags), IsOptimized)); -} - -LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags, uint32_t AlignInBits) { - DIBuilder *D = unwrap(Dref); - return wrap( - D->createAutoVariable(unwrap(Scope), Name, unwrap(File), - Line, unwrap(Ty), AlwaysPreserve, - static_cast(Flags), AlignInBits)); -} - -LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - unsigned ArgNo, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, - int AlwaysPreserve, unsigned Flags) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createParameterVariable( - unwrap(Scope), Name, ArgNo, unwrap(File), Line, - unwrap(Ty), AlwaysPreserve, static_cast(Flags))); -} - -LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, - const char *Name, - uint64_t SizeInBits, - unsigned Encoding) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createBasicType(Name, SizeInBits, Encoding)); -} - -LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref, - LLVMMetadataRef PointeeType, - uint64_t SizeInBits, - uint32_t AlignInBits, - const char *Name) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createPointerType(unwrap(PointeeType), SizeInBits, - AlignInBits, /* DWARFAddressSpace */ None, - Name)); -} - -LLVMMetadataRef -LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, LLVMMetadataRef File, - LLVMMetadataRef ParameterTypes) { - DIBuilder *D = unwrap(Dref); - return wrap( - D->createSubroutineType(DITypeRefArray(unwrap(ParameterTypes)))); -} - -LLVMMetadataRef LLVMDIBuilderCreateStructType( - LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom, - LLVMMetadataRef ElementTypes) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createStructType( - unwrap(Scope), Name, File ? unwrap(File) : nullptr, Line, - SizeInBits, AlignInBits, static_cast(Flags), - DerivedFrom ? unwrap(DerivedFrom) : nullptr, - ElementTypes ? DINodeArray(unwrap(ElementTypes)) : nullptr)); -} - -LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType( - LLVMDIBuilderRef Dref, unsigned Tag, const char *Name, - LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, - unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, - unsigned Flags) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createReplaceableCompositeType( - Tag, Name, unwrap(Scope), File ? unwrap(File) : nullptr, - Line, RuntimeLang, SizeInBits, AlignInBits, - static_cast(Flags))); -} - -LLVMMetadataRef -LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Dref, LLVMMetadataRef Scope, - const char *Name, LLVMMetadataRef File, - unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, LLVMMetadataRef Ty) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createMemberType( - unwrap(Scope), Name, File ? unwrap(File) : nullptr, Line, - SizeInBits, AlignInBits, OffsetInBits, - static_cast(Flags), unwrap(Ty))); -} - -LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref, - uint64_t SizeInBits, - uint32_t AlignInBits, - LLVMMetadataRef ElementType, - LLVMMetadataRef Subscripts) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createArrayType(SizeInBits, AlignInBits, - unwrap(ElementType), - DINodeArray(unwrap(Subscripts)))); -} - -LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, - LLVMMetadataRef Ty, const char *Name, - LLVMMetadataRef File, unsigned Line, - LLVMMetadataRef Context) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createTypedef(unwrap(Ty), Name, - File ? unwrap(File) : nullptr, Line, - Context ? unwrap(Context) : nullptr)); -} - -LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref, - int64_t Lo, int64_t Count) { - DIBuilder *D = unwrap(Dref); - return wrap(D->getOrCreateSubrange(Lo, Count)); -} - -LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref, - LLVMMetadataRef *Data, - size_t Length) { - DIBuilder *D = unwrap(Dref); - Metadata **DataValue = unwrap(Data); - ArrayRef Elements(DataValue, Length); - DINodeArray A = D->getOrCreateArray(Elements); - return wrap(A.get()); -} - -LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref, - LLVMMetadataRef *Data, - size_t Length) { - DIBuilder *D = unwrap(Dref); - Metadata **DataValue = unwrap(Data); - ArrayRef Elements(DataValue, Length); - DITypeRefArray A = D->getOrCreateTypeArray(Elements); - return wrap(A.get()); -} - -LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, - int64_t *Addr, size_t Length) { - DIBuilder *D = unwrap(Dref); - return wrap(D->createExpression(ArrayRef(Addr, Length))); -} - -LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref, - LLVMValueRef Storage, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block) { - // Fail immediately here until the llgo folks update their bindings. The - // called function is going to assert out anyway. - llvm_unreachable("DIBuilder API change requires a DebugLoc"); - - DIBuilder *D = unwrap(Dref); - Instruction *Instr = D->insertDeclare( - unwrap(Storage), unwrap(VarInfo), - unwrap(Expr), /* DebugLoc */ nullptr, unwrap(Block)); - return wrap(Instr); -} - -LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef Dref, - LLVMValueRef Val, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block) { - // Fail immediately here until the llgo folks update their bindings. The - // called function is going to assert out anyway. - llvm_unreachable("DIBuilder API change requires a DebugLoc"); - - DIBuilder *D = unwrap(Dref); - Instruction *Instr = D->insertDbgValueIntrinsic( - unwrap(Val), unwrap(VarInfo), unwrap(Expr), - /* DebugLoc */ nullptr, unwrap(Block)); - return wrap(Instr); -} diff --git a/bindings/go/llvm/DIBuilderBindings.h b/bindings/go/llvm/DIBuilderBindings.h deleted file mode 100644 index cc5d2c1177f64affebfc48e3f4880b4c8063378c..0000000000000000000000000000000000000000 --- a/bindings/go/llvm/DIBuilderBindings.h +++ /dev/null @@ -1,134 +0,0 @@ -//===- DIBuilderBindings.h - Bindings for DIBuilder -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines C bindings for the DIBuilder class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H -#define LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H - -#include "IRBindings.h" -#include "llvm-c/Core.h" -#include "llvm-c/DebugInfo.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// FIXME: These bindings shouldn't be Go-specific and should eventually move to -// a (somewhat) less stable collection of C APIs for use in creating bindings of -// LLVM in other languages. - -typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef; - -LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m); - -void LLVMDIBuilderDestroy(LLVMDIBuilderRef d); - -LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D, - LLVMMetadataRef Scope, - LLVMMetadataRef File, - unsigned Line, unsigned Column); - -LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef D, - LLVMMetadataRef Scope, - LLVMMetadataRef File, - unsigned Discriminator); - -LLVMMetadataRef LLVMDIBuilderCreateFunction( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, - const char *LinkageName, LLVMMetadataRef File, unsigned Line, - LLVMMetadataRef CompositeType, int IsLocalToUnit, int IsDefinition, - unsigned ScopeLine, unsigned Flags, int IsOptimized); - -LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags, uint32_t AlignInBits); - -LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, unsigned ArgNo, - LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, - unsigned Flags); - -LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D, - const char *Name, - uint64_t SizeInBits, - unsigned Encoding); - -LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D, - LLVMMetadataRef PointeeType, - uint64_t SizeInBits, - uint32_t AlignInBits, - const char *Name); - -LLVMMetadataRef -LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D, LLVMMetadataRef File, - LLVMMetadataRef ParameterTypes); - -LLVMMetadataRef LLVMDIBuilderCreateStructType( - LLVMDIBuilderRef D, LLVMMetadataRef Scope, const char *Name, - LLVMMetadataRef File, unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Flags, LLVMMetadataRef DerivedFrom, - LLVMMetadataRef ElementTypes); - -LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType( - LLVMDIBuilderRef D, unsigned Tag, const char *Name, LLVMMetadataRef Scope, - LLVMMetadataRef File, unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned Flags); - -LLVMMetadataRef -LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef D, LLVMMetadataRef Scope, - const char *Name, LLVMMetadataRef File, - unsigned Line, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, LLVMMetadataRef Ty); - -LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D, - uint64_t SizeInBits, - uint32_t AlignInBits, - LLVMMetadataRef ElementType, - LLVMMetadataRef Subscripts); - -LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D, - LLVMMetadataRef Ty, const char *Name, - LLVMMetadataRef File, unsigned Line, - LLVMMetadataRef Context); - -LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef D, int64_t Lo, - int64_t Count); - -LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef D, - LLVMMetadataRef *Data, - size_t Length); - -LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D, - LLVMMetadataRef *Data, - size_t Length); - -LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, - int64_t *Addr, size_t Length); - -LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D, - LLVMValueRef Storage, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block); - -LLVMValueRef LLVMDIBuilderInsertValueAtEnd(LLVMDIBuilderRef D, LLVMValueRef Val, - LLVMMetadataRef VarInfo, - LLVMMetadataRef Expr, - LLVMBasicBlockRef Block); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/bindings/go/llvm/IRBindings.cpp b/bindings/go/llvm/IRBindings.cpp index 4bfa1bbaf0cc8ac81972947abbc97350e2ec3267..b8e3063eb9ac0d49d118cf67ce58c507975a4c1b 100644 --- a/bindings/go/llvm/IRBindings.cpp +++ b/bindings/go/llvm/IRBindings.cpp @@ -36,13 +36,6 @@ LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs, MDNode::get(*unwrap(C), ArrayRef(unwrap(MDs), Count))); } -LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs, - unsigned Count) { - return wrap(MDTuple::getTemporary(*unwrap(C), - ArrayRef(unwrap(MDs), Count)) - .release()); -} - void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name, LLVMMetadataRef Val) { NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); @@ -58,12 +51,6 @@ void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) { unwrap(Inst)->setMetadata(KindID, N); } -void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) { - auto *Node = unwrap(MD); - Node->replaceAllUsesWith(unwrap(New)); - MDNode::deleteTemporary(Node); -} - void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Bref, unsigned Line, unsigned Col, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt) { @@ -84,6 +71,3 @@ LLVMDebugLocMetadata LLVMGetCurrentDebugLocation2(LLVMBuilderRef Bref) { return md; } -void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP) { - unwrap(Func)->setSubprogram(unwrap(SP)); -} diff --git a/bindings/go/llvm/IRBindings.h b/bindings/go/llvm/IRBindings.h index 25a00b13804423ad8ad491184d760b7675777161..66b328c4325774d62b630ecfb55f7b843bca459c 100644 --- a/bindings/go/llvm/IRBindings.h +++ b/bindings/go/llvm/IRBindings.h @@ -15,6 +15,7 @@ #define LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H #include "llvm-c/Core.h" +#include "llvm-c/DebugInfo.h" #ifdef __cplusplus #include "llvm/IR/Metadata.h" #include "llvm/Support/CBindingWrapping.h" @@ -38,23 +39,17 @@ LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef Val); LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen); LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs, unsigned Count); -LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs, - unsigned Count); void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name, LLVMMetadataRef Val); void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD); -void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New); - void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Bref, unsigned Line, unsigned Col, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt); struct LLVMDebugLocMetadata LLVMGetCurrentDebugLocation2(LLVMBuilderRef Bref); -void LLVMSetSubprogram(LLVMValueRef Fn, LLVMMetadataRef SP); - #ifdef __cplusplus } diff --git a/bindings/go/llvm/dibuilder.go b/bindings/go/llvm/dibuilder.go index 475fa685cc4b7b42dc89b99fef62603278cb7b96..8ec8f3cd2805baa228c23df32f4b6558b8212dac 100644 --- a/bindings/go/llvm/dibuilder.go +++ b/bindings/go/llvm/dibuilder.go @@ -14,7 +14,7 @@ package llvm /* -#include "DIBuilderBindings.h" +#include "IRBindings.h" #include */ import "C" @@ -95,13 +95,13 @@ type DIBuilder struct { // NewDIBuilder creates a new DIBuilder, associated with the given module. func NewDIBuilder(m Module) *DIBuilder { - d := C.LLVMNewDIBuilder(m.C) + d := C.LLVMCreateDIBuilder(m.C) return &DIBuilder{ref: d, m: m} } // Destroy destroys the DIBuilder. func (d *DIBuilder) Destroy() { - C.LLVMDIBuilderDestroy(d.ref) + C.LLVMDisposeDIBuilder(d.ref) } // FInalize finalizes the debug information generated by the DIBuilder. @@ -147,7 +147,7 @@ func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata { return Metadata{C: result} } -// CreateCompileUnit creates file debug metadata. +// CreateFile creates file debug metadata. func (d *DIBuilder) CreateFile(filename, dir string) Metadata { cfilename := C.CString(filename) defer C.free(unsafe.Pointer(cfilename)) @@ -166,7 +166,7 @@ type DILexicalBlock struct { Column int } -// CreateCompileUnit creates lexical block debug metadata. +// CreateLexicalBlock creates lexical block debug metadata. func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata { result := C.LLVMDIBuilderCreateLexicalBlock( d.ref, @@ -198,7 +198,7 @@ type DIFunction struct { Optimized bool } -// CreateCompileUnit creates function debug metadata. +// CreateFunction creates function debug metadata. func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata { name := C.CString(f.Name) defer C.free(unsafe.Pointer(name)) @@ -207,16 +207,16 @@ func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata { result := C.LLVMDIBuilderCreateFunction( d.ref, diScope.C, - name, - linkageName, + name, C.size_t(len(f.Name)), + linkageName, C.size_t(len(f.LinkageName)), f.File.C, C.unsigned(f.Line), f.Type.C, - boolToCInt(f.LocalToUnit), - boolToCInt(f.IsDefinition), + C.LLVMBool(boolToCInt(f.LocalToUnit)), + C.LLVMBool(boolToCInt(f.IsDefinition)), C.unsigned(f.ScopeLine), - C.unsigned(f.Flags), - boolToCInt(f.Optimized), + C.LLVMDIFlags(f.Flags), + C.LLVMBool(boolToCInt(f.Optimized)), ) return Metadata{C: result} } @@ -239,12 +239,12 @@ func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadat result := C.LLVMDIBuilderCreateAutoVariable( d.ref, scope.C, - name, + name, C.size_t(len(v.Name)), v.File.C, C.unsigned(v.Line), v.Type.C, - boolToCInt(v.AlwaysPreserve), - C.unsigned(v.Flags), + C.LLVMBool(boolToCInt(v.AlwaysPreserve)), + C.LLVMDIFlags(v.Flags), C.uint32_t(v.AlignInBits), ) return Metadata{C: result} @@ -271,13 +271,13 @@ func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariabl result := C.LLVMDIBuilderCreateParameterVariable( d.ref, scope.C, - name, + name, C.size_t(len(v.Name)), C.unsigned(v.ArgNo), v.File.C, C.unsigned(v.Line), v.Type.C, - boolToCInt(v.AlwaysPreserve), - C.unsigned(v.Flags), + C.LLVMBool(boolToCInt(v.AlwaysPreserve)), + C.LLVMDIFlags(v.Flags), ) return Metadata{C: result} } @@ -296,6 +296,7 @@ func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata { result := C.LLVMDIBuilderCreateBasicType( d.ref, name, + C.size_t(len(t.Name)), C.uint64_t(t.SizeInBits), C.unsigned(t.Encoding), ) @@ -307,10 +308,11 @@ type DIPointerType struct { Pointee Metadata SizeInBits uint64 AlignInBits uint32 // optional + AddressSpace uint32 Name string // optional } -// CreateBasicType creates basic type debug metadata. +// CreatePointerType creates a type that represents a pointer to another type. func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata { name := C.CString(t.Name) defer C.free(unsafe.Pointer(name)) @@ -319,7 +321,9 @@ func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata { t.Pointee.C, C.uint64_t(t.SizeInBits), C.uint32_t(t.AlignInBits), + C.unsigned(t.AddressSpace), name, + C.size_t(len(t.Name)), ) return Metadata{C: result} } @@ -332,12 +336,20 @@ type DISubroutineType struct { // Parameters contains the subroutine parameter types, // including the return type at the 0th index. Parameters []Metadata + + Flags int } // CreateSubroutineType creates subroutine type debug metadata. func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata { - params := d.getOrCreateTypeArray(t.Parameters) - result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C) + params, length := llvmMetadataRefs(t.Parameters) + result := C.LLVMDIBuilderCreateSubroutineType( + d.ref, + t.File.C, + params, + length, + C.LLVMDIFlags(t.Flags), + ) return Metadata{C: result} } @@ -351,24 +363,34 @@ type DIStructType struct { Flags int DerivedFrom Metadata Elements []Metadata + VTableHolder Metadata // optional + UniqueID string } // CreateStructType creates struct type debug metadata. func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata { - elements := d.getOrCreateArray(t.Elements) + elements, length := llvmMetadataRefs(t.Elements) name := C.CString(t.Name) + uniqueID := C.CString(t.UniqueID) defer C.free(unsafe.Pointer(name)) + defer C.free(unsafe.Pointer(uniqueID)) result := C.LLVMDIBuilderCreateStructType( d.ref, scope.C, name, + C.size_t(len(t.Name)), t.File.C, C.unsigned(t.Line), C.uint64_t(t.SizeInBits), C.uint32_t(t.AlignInBits), - C.unsigned(t.Flags), + C.LLVMDIFlags(t.Flags), t.DerivedFrom.C, - elements.C, + elements, + length, + C.unsigned(0), // Optional Objective-C runtime version. + t.VTableHolder.C, + uniqueID, + C.size_t(len(t.UniqueID)), ) return Metadata{C: result} } @@ -384,23 +406,29 @@ type DIReplaceableCompositeType struct { SizeInBits uint64 AlignInBits uint32 Flags int + UniqueID string } // CreateReplaceableCompositeType creates replaceable composite type debug metadata. func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata { name := C.CString(t.Name) + uniqueID := C.CString(t.UniqueID) defer C.free(unsafe.Pointer(name)) + defer C.free(unsafe.Pointer(uniqueID)) result := C.LLVMDIBuilderCreateReplaceableCompositeType( d.ref, C.unsigned(t.Tag), name, + C.size_t(len(t.Name)), scope.C, t.File.C, C.unsigned(t.Line), C.unsigned(t.RuntimeLang), C.uint64_t(t.SizeInBits), C.uint32_t(t.AlignInBits), - C.unsigned(t.Flags), + C.LLVMDIFlags(t.Flags), + uniqueID, + C.size_t(len(t.UniqueID)), ) return Metadata{C: result} } @@ -425,12 +453,13 @@ func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata { d.ref, scope.C, name, + C.size_t(len(t.Name)), t.File.C, C.unsigned(t.Line), C.uint64_t(t.SizeInBits), C.uint32_t(t.AlignInBits), C.uint64_t(t.OffsetInBits), - C.unsigned(t.Flags), + C.LLVMDIFlags(t.Flags), t.Type.C, ) return Metadata{C: result} @@ -456,13 +485,14 @@ func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata { for i, s := range t.Subscripts { subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count) } - subscripts := d.getOrCreateArray(subscriptsSlice) + subscripts, length := llvmMetadataRefs(subscriptsSlice) result := C.LLVMDIBuilderCreateArrayType( d.ref, C.uint64_t(t.SizeInBits), C.uint32_t(t.AlignInBits), t.ElementType.C, - subscripts.C, + subscripts, + length, ) return Metadata{C: result} } @@ -484,6 +514,7 @@ func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata { d.ref, t.Type.C, name, + C.size_t(len(t.Name)), t.File.C, C.unsigned(t.Line), t.Context.C, @@ -534,20 +565,38 @@ func (d *DIBuilder) CreateExpression(addr []int64) Metadata { // InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the // specified basic block for the given value and associated debug metadata. func (d *DIBuilder) InsertDeclareAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value { - result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C) + result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, nil, bb.C) return Value{C: result} } // InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the // specified basic block for the given value and associated debug metadata. func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, bb BasicBlock) Value { - result := C.LLVMDIBuilderInsertValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C) + result := C.LLVMDIBuilderInsertDbgValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, nil, bb.C) return Value{C: result} } +func (v Value) SetSubprogram(sp Metadata) { + C.LLVMSetSubprogram(v.C, sp.C) +} + func boolToCInt(v bool) C.int { if v { return 1 } return 0 } + +//------------------------------------------------------------------------- +// llvm.Metadata +//------------------------------------------------------------------------- + +func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) { + ptr, nvals := llvmMetadataRefs(mds) + md.C = C.LLVMTemporaryMDNode(c.C, ptr, C.size_t(nvals)) + return +} + +func (md Metadata) ReplaceAllUsesWith(new Metadata) { + C.LLVMMetadataReplaceAllUsesWith(md.C, new.C) +} diff --git a/bindings/go/llvm/ir.go b/bindings/go/llvm/ir.go index 0a379e47dc6517ffcd73e198800235a35e7b24ea..a336c0ef44c77b0bf7b3126bc04582ac0c93b7f2 100644 --- a/bindings/go/llvm/ir.go +++ b/bindings/go/llvm/ir.go @@ -784,11 +784,6 @@ func (c Context) MDNode(mds []Metadata) (md Metadata) { md.C = C.LLVMMDNode2(c.C, ptr, nvals) return } -func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) { - ptr, nvals := llvmMetadataRefs(mds) - md.C = C.LLVMTemporaryMDNode(c.C, ptr, nvals) - return -} func (v Value) ConstantAsMetadata() (md Metadata) { md.C = C.LLVMConstantAsMetadata(v.C) return @@ -1037,6 +1032,8 @@ func (v Value) IsThreadLocal() bool { return C.LLVMIsThreadLocal(v.C) != 0 func (v Value) SetThreadLocal(tl bool) { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) } func (v Value) IsGlobalConstant() bool { return C.LLVMIsGlobalConstant(v.C) != 0 } func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) } +func (v Value) IsVolatile() bool { return C.LLVMGetVolatile(v.C) != 0 } +func (v Value) SetVolatile(volatile bool) { C.LLVMSetVolatile(v.C, boolToLLVMBool(volatile)) } // Operations on aliases func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) { @@ -1138,9 +1135,6 @@ func (v Value) AddTargetDependentFunctionAttr(attr, value string) { func (v Value) SetPersonality(p Value) { C.LLVMSetPersonalityFn(v.C, p.C) } -func (v Value) SetSubprogram(sp Metadata) { - C.LLVMSetSubprogram(v.C, sp.C) -} // Operations on parameters func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } @@ -1917,11 +1911,3 @@ func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassMan // the module provider. // See llvm::PassManagerBase::~PassManagerBase. func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) } - -//------------------------------------------------------------------------- -// llvm.Metadata -//------------------------------------------------------------------------- - -func (md Metadata) ReplaceAllUsesWith(new Metadata) { - C.LLVMMetadataReplaceAllUsesWith(md.C, new.C) -} diff --git a/bindings/go/llvm/ir_test.go b/bindings/go/llvm/ir_test.go index 5cd782b7d96f7f9533fc3b921a45a65a7c0935cf..10f4968ba89f2c803eb9fbe04eb5ee33f2bcb530 100644 --- a/bindings/go/llvm/ir_test.go +++ b/bindings/go/llvm/ir_test.go @@ -112,7 +112,11 @@ func TestDebugLoc(t *testing.T) { }() file := d.CreateFile("dummy_file", "dummy_dir") voidInfo := d.CreateBasicType(DIBasicType{Name: "void"}) - typeInfo := d.CreateSubroutineType(DISubroutineType{file, []Metadata{voidInfo}}) + typeInfo := d.CreateSubroutineType(DISubroutineType{ + File: file, + Parameters: []Metadata{voidInfo}, + Flags: 0, + }) scope := d.CreateFunction(file, DIFunction{ Name: "foo", LinkageName: "foo", diff --git a/bindings/go/llvm/transforms_scalar.go b/bindings/go/llvm/transforms_scalar.go index 6492a85a7faed2a72e99bfa052740560fb105e5b..cb46f6881859b2bd6c53a0a5f5dbdce205600ef9 100644 --- a/bindings/go/llvm/transforms_scalar.go +++ b/bindings/go/llvm/transforms_scalar.go @@ -15,6 +15,7 @@ package llvm /* #include "llvm-c/Transforms/Scalar.h" +#include "llvm-c/Transforms/Utils.h" */ import "C" diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 137b17f26bfb2316086896f315edfb876168e60e..77689edcf6d1b12ef33154d430a15adbb5184182 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -20,6 +20,7 @@ #include #include "llvm-c/Core.h" #include "llvm-c/Support.h" +#include "llvm/Config/llvm-config.h" #include "caml/alloc.h" #include "caml/custom.h" #include "caml/memory.h" diff --git a/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml b/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml index 88831daf51941f20d32345bd655c6d7d48cebd20..f9f6be26d7f18372c427ff354bc52290dbf3445c 100644 --- a/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml +++ b/bindings/ocaml/transforms/vectorize/llvm_vectorize.ml @@ -7,9 +7,6 @@ * *===----------------------------------------------------------------------===*) -external add_bb_vectorize - : [ unit - = "llvm_add_bb_vectorize" external add_loop_vectorize : [ unit = "llvm_add_loop_vectorize" diff --git a/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli b/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli index 23a68a28dadf8b3b5a5dfbd3cdaff28b0c49b62a..f9b4ce5aae583e9732dee7f62b1abfe643626fa4 100644 --- a/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli +++ b/bindings/ocaml/transforms/vectorize/llvm_vectorize.mli @@ -12,11 +12,6 @@ This interface provides an OCaml API for LLVM vectorize transforms, the classes in the [LLVMVectorize] library. *) -(** See the [llvm::createBBVectorizePass] function. *) -external add_bb_vectorize - : [ unit - = "llvm_add_bb_vectorize" - (** See the [llvm::createLoopVectorizePass] function. *) external add_loop_vectorize : [ unit diff --git a/bindings/ocaml/transforms/vectorize/vectorize_ocaml.c b/bindings/ocaml/transforms/vectorize/vectorize_ocaml.c index 1c8104951c4aa4271daceac5c6c7d48377887637..dcd9231b5bf275f7d66d334850ade09890e07dc2 100644 --- a/bindings/ocaml/transforms/vectorize/vectorize_ocaml.c +++ b/bindings/ocaml/transforms/vectorize/vectorize_ocaml.c @@ -19,12 +19,6 @@ #include "caml/mlvalues.h" #include "caml/misc.h" -/* [ unit */ -CAMLprim value llvm_add_bb_vectorize(LLVMPassManagerRef PM) { - LLVMAddBBVectorizePass(PM); - return Val_unit; -} - /* [ unit */ CAMLprim value llvm_add_loop_vectorize(LLVMPassManagerRef PM) { LLVMAddLoopVectorizePass(PM); diff --git a/bindings/python/llvm/core.py b/bindings/python/llvm/core.py index 47e81dd1a4f948192b73e8b152d7ba28ccee3304..6b3da6d867929ffeeca0af48e63594e2dc1b39ec 100644 --- a/bindings/python/llvm/core.py +++ b/bindings/python/llvm/core.py @@ -456,6 +456,9 @@ def register_library(library): library.LLVMInitializeInstCombine.argtypes = [PassRegistry] library.LLVMInitializeInstCombine.restype = None + library.LLVMInitializeAggressiveInstCombiner.argtypes = [PassRegistry] + library.LLVMInitializeAggressiveInstCombiner.restype = None + library.LLVMInitializeIPO.argtypes = [PassRegistry] library.LLVMInitializeIPO.restype = None diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index 91055429600805b3dac91288a87da2ce3f92843a..a1666783cfb5bc6fb339362e2a9c393cc3945775 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -4,13 +4,10 @@ if( WIN32 AND NOT CYGWIN ) endif() include(CheckIncludeFile) -include(CheckIncludeFileCXX) include(CheckLibraryExists) include(CheckSymbolExists) include(CheckFunctionExists) include(CheckCCompilerFlag) -include(CheckCXXSourceCompiles) -include(TestBigEndian) include(CheckCompilerVersion) include(HandleLLVMStdlib) @@ -25,49 +22,24 @@ if( CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE" AND list(APPEND CMAKE_REQUIRED_LIBRARIES "cxxrt") endif() -# Helper macros and functions -macro(add_cxx_include result files) - set(${result} "") - foreach (file_name ${files}) - set(${result} "${${result}}#include<${file_name}>\n") - endforeach() -endmacro(add_cxx_include files result) - -function(check_type_exists type files variable) - add_cxx_include(includes "${files}") - CHECK_CXX_SOURCE_COMPILES(" - ${includes} ${type} typeVar; - int main() { - return 0; - } - " ${variable}) -endfunction() - # include checks -check_include_file(dirent.h HAVE_DIRENT_H) check_include_file(dlfcn.h HAVE_DLFCN_H) check_include_file(errno.h HAVE_ERRNO_H) check_include_file(fcntl.h HAVE_FCNTL_H) -check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(link.h HAVE_LINK_H) check_include_file(malloc.h HAVE_MALLOC_H) check_include_file(malloc/malloc.h HAVE_MALLOC_MALLOC_H) -check_include_file(ndir.h HAVE_NDIR_H) if( NOT PURE_WINDOWS ) check_include_file(pthread.h HAVE_PTHREAD_H) endif() check_include_file(signal.h HAVE_SIGNAL_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(sys/dir.h HAVE_SYS_DIR_H) check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) check_include_file(sys/mman.h HAVE_SYS_MMAN_H) -check_include_file(sys/ndir.h HAVE_SYS_NDIR_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H) check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(sys/uio.h HAVE_SYS_UIO_H) check_include_file(termios.h HAVE_TERMIOS_H) check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H) @@ -117,6 +89,9 @@ if( NOT PURE_WINDOWS ) check_library_exists(rt clock_gettime "" HAVE_LIBRT) endif() +# Check for libpfm. +include(FindLibpfm) + if(HAVE_LIBPTHREAD) # We want to find pthreads library and at the moment we do want to # have it reported as '-l' instead of '-pthread'. @@ -218,9 +193,6 @@ check_symbol_exists(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE) if( HAVE_SIGNAL_H AND NOT LLVM_USE_SANITIZER MATCHES ".*Address.*" AND NOT APPLE ) check_symbol_exists(sigaltstack signal.h HAVE_SIGALTSTACK) endif() -if( HAVE_SYS_UIO_H ) - check_symbol_exists(writev sys/uio.h HAVE_WRITEV) -endif() set(CMAKE_REQUIRED_DEFINITIONS "-D_LARGEFILE64_SOURCE") check_symbol_exists(lseek64 "sys/types.h;unistd.h" HAVE_LSEEK64) set(CMAKE_REQUIRED_DEFINITIONS "") @@ -228,17 +200,11 @@ check_symbol_exists(mallctl malloc_np.h HAVE_MALLCTL) check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO) check_symbol_exists(malloc_zone_statistics malloc/malloc.h HAVE_MALLOC_ZONE_STATISTICS) -check_symbol_exists(mkdtemp "stdlib.h;unistd.h" HAVE_MKDTEMP) -check_symbol_exists(mkstemp "stdlib.h;unistd.h" HAVE_MKSTEMP) -check_symbol_exists(mktemp "stdlib.h;unistd.h" HAVE_MKTEMP) -check_symbol_exists(getcwd unistd.h HAVE_GETCWD) -check_symbol_exists(gettimeofday sys/time.h HAVE_GETTIMEOFDAY) check_symbol_exists(getrlimit "sys/types.h;sys/time.h;sys/resource.h" HAVE_GETRLIMIT) check_symbol_exists(posix_spawn spawn.h HAVE_POSIX_SPAWN) check_symbol_exists(pread unistd.h HAVE_PREAD) check_symbol_exists(realpath stdlib.h HAVE_REALPATH) check_symbol_exists(sbrk unistd.h HAVE_SBRK) -check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL) check_symbol_exists(strerror string.h HAVE_STRERROR) check_symbol_exists(strerror_r string.h HAVE_STRERROR_R) check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S) @@ -286,28 +252,17 @@ endif() # This check requires _GNU_SOURCE check_symbol_exists(sched_getaffinity sched.h HAVE_SCHED_GETAFFINITY) check_symbol_exists(CPU_COUNT sched.h HAVE_CPU_COUNT) -if(HAVE_LIBPTHREAD) - check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP) - check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP) -elseif(PTHREAD_IN_LIBC) - check_library_exists(c pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP) - check_library_exists(c pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP) -endif() - -set(headers "sys/types.h") - -if (HAVE_INTTYPES_H) - set(headers ${headers} "inttypes.h") -endif() - -if (HAVE_STDINT_H) - set(headers ${headers} "stdint.h") +if (NOT PURE_WINDOWS) + if (LLVM_PTHREAD_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${LLVM_PTHREAD_LIB}) + endif() + check_symbol_exists(pthread_getname_np pthread.h HAVE_PTHREAD_GETNAME_NP) + check_symbol_exists(pthread_setname_np pthread.h HAVE_PTHREAD_SETNAME_NP) + if (LLVM_PTHREAD_LIB) + list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${LLVM_PTHREAD_LIB}) + endif() endif() -check_type_exists(int64_t "${headers}" HAVE_INT64_T) -check_type_exists(uint64_t "${headers}" HAVE_UINT64_T) -check_type_exists(u_int64_t "${headers}" HAVE_U_INT64_T) - # available programs checks function(llvm_find_program name) string(TOUPPER ${name} NAME) @@ -479,23 +434,6 @@ else () endif () endif () -if( MINGW ) - set(HAVE_LIBPSAPI 1) - set(HAVE_LIBSHELL32 1) - # TODO: Check existence of libraries. - # include(CheckLibraryExists) -endif( MINGW ) - -if (NOT HAVE_STRTOLL) - # Use _strtoi64 if strtoll is not available. - check_symbol_exists(_strtoi64 stdlib.h have_strtoi64) - if (have_strtoi64) - set(HAVE_STRTOLL 1) - set(strtoll "_strtoi64") - set(strtoull "_strtoui64") - endif () -endif () - if( MSVC ) set(SHLIBEXT ".lib") set(stricmp "_stricmp") @@ -573,10 +511,10 @@ else() endif() set(LLVM_BINDINGS "") -if(WIN32) +find_program(GO_EXECUTABLE NAMES go DOC "go executable") +if(WIN32 OR NOT LLVM_ENABLE_BINDINGS) message(STATUS "Go bindings disabled.") else() - find_program(GO_EXECUTABLE NAMES go DOC "go executable") if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND") message(STATUS "Go bindings disabled.") else() @@ -616,7 +554,7 @@ endif() # Keep the version requirements in sync with bindings/ocaml/README.txt. include(FindOCaml) include(AddOCaml) -if(WIN32) +if(WIN32 OR NOT LLVM_ENABLE_BINDINGS) message(STATUS "OCaml bindings disabled.") else() find_package(OCaml) diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index 2f470105ff5d161e14e746b7fbf294c4208521dd..d631fcc0f0570a1286b438b705b2d3122f683179 100644 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -152,7 +152,8 @@ if(NOT WIN32 AND NOT APPLE) if( LLVM_USE_LINKER ) set(command ${CMAKE_C_COMPILER} -fuse-ld=${LLVM_USE_LINKER} -Wl,--version) else() - set(command ${CMAKE_C_COMPILER} -Wl,--version) + separate_arguments(flags UNIX_COMMAND "${CMAKE_EXE_LINKER_FLAGS}") + set(command ${CMAKE_C_COMPILER} ${flags} -Wl,--version) endif() execute_process( COMMAND ${command} @@ -1545,7 +1546,7 @@ function(llvm_externalize_debuginfo name) if(APPLE) set(strip_command COMMAND xcrun strip -Sxl $) else() - set(strip_command COMMAND strip -gx $) + set(strip_command COMMAND ${CMAKE_STRIP} -gx $) endif() endif() @@ -1563,9 +1564,9 @@ function(llvm_externalize_debuginfo name) ) else() add_custom_command(TARGET ${name} POST_BUILD - COMMAND objcopy --only-keep-debug $ $.debug + COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $ $.debug ${strip_command} -R .gnu_debuglink - COMMAND objcopy --add-gnu-debuglink=$.debug $ + COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$.debug $ ) endif() endfunction() @@ -1614,10 +1615,10 @@ function(setup_dependency_debugging name) return() endif() - set(deny_attributes_gen "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.gen\"))") - set(deny_intrinsics_gen "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.gen\"))") + set(deny_attributes_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.inc\"))") + set(deny_intrinsics_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.inc\"))") - set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_gen} ${deny_intrinsics_gen}'") + set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_inc} ${deny_intrinsics_inc}'") set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command}) endfunction() diff --git a/cmake/modules/FindLibpfm.cmake b/cmake/modules/FindLibpfm.cmake new file mode 100644 index 0000000000000000000000000000000000000000..202bb030e3803273ace553266d26303fb1b94de1 --- /dev/null +++ b/cmake/modules/FindLibpfm.cmake @@ -0,0 +1,23 @@ +# CMake module for finding libpfm4. +# +# If successful, the following variables will be defined: +# HAVE_LIBPFM +# +# Libpfm can be disabled by setting LLVM_ENABLE_LIBPFM to 0. + +include(CheckIncludeFile) +include(CheckLibraryExists) + +if (LLVM_ENABLE_LIBPFM) + check_library_exists(pfm pfm_initialize "" HAVE_LIBPFM_INITIALIZE) + if(HAVE_LIBPFM_INITIALIZE) + check_include_file(perfmon/perf_event.h HAVE_PERFMON_PERF_EVENT_H) + check_include_file(perfmon/pfmlib.h HAVE_PERFMON_PFMLIB_H) + check_include_file(perfmon/pfmlib_perf_event.h HAVE_PERFMON_PFMLIB_PERF_EVENT_H) + if(HAVE_PERFMON_PERF_EVENT_H AND HAVE_PERFMON_PFMLIB_H AND HAVE_PERFMON_PFMLIB_PERF_EVENT_H) + set(HAVE_LIBPFM 1) + endif() + endif() +endif() + + diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index 86ce0bbcfd0e6e8c0d14b3c1c4301cf1e3dfbd96..3d2dd48018cc2d479d2ffa3f655691ad67ba7142 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -48,14 +48,6 @@ elseif(LLVM_PARALLEL_LINK_JOBS) message(WARNING "Job pooling is only available with Ninja generators.") endif() -if (LINKER_IS_LLD_LINK) - # Pass /MANIFEST:NO so that CMake doesn't run mt.exe on our binaries. Adding - # manifests with mt.exe breaks LLD's symbol tables and takes as much time as - # the link. See PR24476. - append("/MANIFEST:NO" - CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) -endif() - if( LLVM_ENABLE_ASSERTIONS ) # MSVC doesn't like _DEBUG on release builds. See PR 4379. if( NOT MSVC ) @@ -115,7 +107,7 @@ if(WIN32) set(LLVM_ON_UNIX 0) endif(CYGWIN) else(WIN32) - if(UNIX) + if(FUCHSIA OR UNIX) set(LLVM_ON_WIN32 0) set(LLVM_ON_UNIX 1) if(APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "AIX") @@ -123,9 +115,9 @@ else(WIN32) else() set(LLVM_HAVE_LINK_VERSION_SCRIPT 1) endif() - else(UNIX) + else(FUCHSIA OR UNIX) MESSAGE(SEND_ERROR "Unable to determine platform") - endif(UNIX) + endif(FUCHSIA OR UNIX) endif(WIN32) set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) @@ -563,7 +555,7 @@ if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)) append("-Wall" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() - append("-W -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("-Wextra -Wno-unused-parameter -Wwrite-strings" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) append("-Wcast-qual" CMAKE_CXX_FLAGS) # Turn off missing field initializer warnings for gcc to avoid noise from @@ -639,7 +631,7 @@ macro(append_common_sanitizer_flags) add_flag_if_supported("-gline-tables-only" GLINE_TABLES_ONLY) endif() # Use -O1 even in debug mode, otherwise sanitizers slowdown is too large. - if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND LLVM_OPTIMIZE_SANITIZED_BUILDS) add_flag_if_supported("-O1" O1) endif() elseif (CLANG_CL) @@ -720,11 +712,13 @@ add_definitions( -D__STDC_CONSTANT_MACROS ) add_definitions( -D__STDC_FORMAT_MACROS ) add_definitions( -D__STDC_LIMIT_MACROS ) -# clang doesn't print colored diagnostics when invoked from Ninja +# clang and gcc don't default-print colored diagnostics when invoked from Ninja. if (UNIX AND - CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND - CMAKE_GENERATOR STREQUAL "Ninja") - append("-fcolor-diagnostics" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + CMAKE_GENERATOR STREQUAL "Ninja" AND + (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR + (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)))) + append("-fdiagnostics-color" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() # lld doesn't print colored diagnostics when invoked from Ninja diff --git a/cmake/modules/HandleLLVMStdlib.cmake b/cmake/modules/HandleLLVMStdlib.cmake index c0512ac34f6dab5e8b84fedd9f72c4349bae4c7c..a0706d8e0846a52c310d5f8d80b902f467651101 100644 --- a/cmake/modules/HandleLLVMStdlib.cmake +++ b/cmake/modules/HandleLLVMStdlib.cmake @@ -13,10 +13,12 @@ if(NOT DEFINED LLVM_STDLIB_HANDLED) endfunction() include(CheckCXXCompilerFlag) + include(CheckLinkerFlag) if(LLVM_ENABLE_LIBCXX) if(LLVM_COMPILER_IS_GCC_COMPATIBLE) - check_cxx_compiler_flag("-stdlib=libc++" CXX_SUPPORTS_STDLIB) - if(CXX_SUPPORTS_STDLIB) + check_cxx_compiler_flag("-stdlib=libc++" CXX_COMPILER_SUPPORTS_STDLIB) + check_linker_flag("-stdlib=libc++" CXX_LINKER_SUPPORTS_STDLIB) + if(CXX_COMPILER_SUPPORTS_STDLIB AND CXX_LINKER_SUPPORTS_STDLIB) append("-stdlib=libc++" CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) diff --git a/cmake/modules/LLVMConfig.cmake.in b/cmake/modules/LLVMConfig.cmake.in index e7001867984656434f8d1e75e7f8edb99d740765..88918ba30c774dd62179e210b56cc454ba690131 100644 --- a/cmake/modules/LLVMConfig.cmake.in +++ b/cmake/modules/LLVMConfig.cmake.in @@ -58,7 +58,6 @@ set(LLVM_EXPORT_SYMBOLS_FOR_PLUGINS @LLVM_EXPORT_SYMBOLS_FOR_PLUGINS@) set(LLVM_PLUGIN_EXT @LLVM_PLUGIN_EXT@) set(LLVM_ON_UNIX @LLVM_ON_UNIX@) -set(LLVM_ON_WIN32 @LLVM_ON_WIN32@) set(LLVM_LIBDIR_SUFFIX @LLVM_LIBDIR_SUFFIX@) diff --git a/docs/AMDGPUUsage.rst b/docs/AMDGPUUsage.rst index 3076332661a358b3c3e441050c4a2028283cf139..7a264af62f40cbfde335918ae8ff53eb60c95197 100644 --- a/docs/AMDGPUUsage.rst +++ b/docs/AMDGPUUsage.rst @@ -198,8 +198,15 @@ names from both the *Processor* and *Alternative Processor* can be used. - Radeon RX Vega 64 Liquid - Radeon Instinct MI25 - ``gfx902`` ``amdgcn`` APU - xnack *TBA* - [on] + ``gfx902`` ``amdgcn`` APU - xnack - Ryzen 3 2200G + [on] - Ryzen 5 2400G + ``gfx904`` ``amdgcn`` dGPU - xnack *TBA* + [off] + .. TODO + Add product + names. + ``gfx906`` ``amdgcn`` dGPU - xnack *TBA* + [off] .. TODO Add product names. @@ -550,8 +557,8 @@ The AMDGPU backend uses the following ELF header: ``EF_AMDGPU_MACH_AMDGCN_GFX810`` 0x02b ``gfx810`` ``EF_AMDGPU_MACH_AMDGCN_GFX900`` 0x02c ``gfx900`` ``EF_AMDGPU_MACH_AMDGCN_GFX902`` 0x02d ``gfx902`` - *reserved* 0x02e Reserved. - *reserved* 0x02f Reserved. + ``EF_AMDGPU_MACH_AMDGCN_GFX904`` 0x02e ``gfx904`` + ``EF_AMDGPU_MACH_AMDGCN_GFX906`` 0x02f ``gfx906`` *reserved* 0x030 Reserved. ================================= ========== ============================= @@ -763,12 +770,16 @@ The following relocation types are supported: Relocation Type Kind Value Field Calculation ========================== ======= ===== ========== ============================== ``R_AMDGPU_NONE`` 0 *none* *none* - ``R_AMDGPU_ABS32_LO`` Dynamic 1 ``word32`` (S + A) & 0xFFFFFFFF - ``R_AMDGPU_ABS32_HI`` Dynamic 2 ``word32`` (S + A) >> 32 - ``R_AMDGPU_ABS64`` Dynamic 3 ``word64`` S + A + ``R_AMDGPU_ABS32_LO`` Static, 1 ``word32`` (S + A) & 0xFFFFFFFF + Dynamic + ``R_AMDGPU_ABS32_HI`` Static, 2 ``word32`` (S + A) >> 32 + Dynamic + ``R_AMDGPU_ABS64`` Static, 3 ``word64`` S + A + Dynamic ``R_AMDGPU_REL32`` Static 4 ``word32`` S + A - P ``R_AMDGPU_REL64`` Static 5 ``word64`` S + A - P - ``R_AMDGPU_ABS32`` Static 6 ``word32`` S + A + ``R_AMDGPU_ABS32`` Static, 6 ``word32`` S + A + Dynamic ``R_AMDGPU_GOTPCREL`` Static 7 ``word32`` G + GOT + A - P ``R_AMDGPU_GOTPCREL32_LO`` Static 8 ``word32`` (G + GOT + A - P) & 0xFFFFFFFF ``R_AMDGPU_GOTPCREL32_HI`` Static 9 ``word32`` (G + GOT + A - P) >> 32 @@ -778,6 +789,12 @@ The following relocation types are supported: ``R_AMDGPU_RELATIVE64`` Dynamic 13 ``word64`` B + A ========================== ======= ===== ========== ============================== +``R_AMDGPU_ABS32_LO`` and ``R_AMDGPU_ABS32_HI`` are only supported by +the ``mesa3d`` OS, which does not support ``R_AMDGPU_ABS64``. + +There is no current OS loader support for 32 bit programs and so +``R_AMDGPU_ABS32`` is not used. + .. _amdgpu-dwarf: DWARF @@ -1841,17 +1858,13 @@ CP microcode requires the Kernel descritor to be allocated on 64 byte alignment. Used by CP to set up ``COMPUTE_PGM_RSRC2.USER_SGPR``. - 6 1 bit ENABLE_TRAP_HANDLER Set to 1 if code contains a - TRAP instruction which - requires a trap handler to - be enabled. - - CP sets - ``COMPUTE_PGM_RSRC2.TRAP_PRESENT`` - if the runtime has - installed a trap handler - regardless of the setting - of this field. + 6 1 bit ENABLE_TRAP_HANDLER Must be 0. + + This bit represents + ``COMPUTE_PGM_RSRC2.TRAP_PRESENT``, + which is set by the CP if + the runtime has installed a + trap handler. 7 1 bit ENABLE_SGPR_WORKGROUP_ID_X Enable the setup of the system SGPR register for the work-group id in the X @@ -2269,7 +2282,7 @@ VGPR register initial state is defined in > 1) wavefront lane. ========== ========================== ====== ============================== -The setting of registers is is done by GPU CP/ADC/SPI hardware as follows: +The setting of registers is done by GPU CP/ADC/SPI hardware as follows: 1. SGPRs before the Work-Group Ids are set by CP using the 16 User Data registers. @@ -3771,16 +3784,154 @@ the ``s_trap`` instruction with the following usage: ``queue_ptr`` terminated and its associated queue put into the error state. - ``llvm.debugtrap`` ``s_trap 0x03`` ``SGPR0-1``: If debugger not - ``queue_ptr`` installed handled - same as ``llvm.trap``. - debugger breakpoint ``s_trap 0x07`` Reserved for debugger + ``llvm.debugtrap`` ``s_trap 0x03`` - If debugger not + installed then + behaves as a + no-operation. The + trap handler is + entered and + immediately returns + to continue + execution of the + wavefront. + - If the debugger is + installed, causes + the debug trap to be + reported by the + debugger and the + wavefront is put in + the halt state until + resumed by the + debugger. + reserved ``s_trap 0x04`` Reserved. + reserved ``s_trap 0x05`` Reserved. + reserved ``s_trap 0x06`` Reserved. + debugger breakpoint ``s_trap 0x07`` Reserved for debugger breakpoints. - debugger ``s_trap 0x08`` Reserved for debugger. - debugger ``s_trap 0xfe`` Reserved for debugger. - debugger ``s_trap 0xff`` Reserved for debugger. + reserved ``s_trap 0x08`` Reserved. + reserved ``s_trap 0xfe`` Reserved. + reserved ``s_trap 0xff`` Reserved. =================== =============== =============== ======================= +AMDPAL +------ + +This section provides code conventions used when the target triple OS is +``amdpal`` (see :ref:`amdgpu-target-triples`) for passing runtime parameters +from the application/runtime to each invocation of a hardware shader. These +parameters include both generic, application-controlled parameters called +*user data* as well as system-generated parameters that are a product of the +draw or dispatch execution. + +User Data +~~~~~~~~~ + +Each hardware stage has a set of 32-bit *user data registers* which can be +written from a command buffer and then loaded into SGPRs when waves are launched +via a subsequent dispatch or draw operation. This is the way most arguments are +passed from the application/runtime to a hardware shader. + +Compute User Data +~~~~~~~~~~~~~~~~~ + +Compute shader user data mappings are simpler than graphics shaders, and have a +fixed mapping. + +Note that there are always 10 available *user data entries* in registers - +entries beyond that limit must be fetched from memory (via the spill table +pointer) by the shader. + + .. table:: PAL Compute Shader User Data Registers + :name: pal-compute-user-data-registers + + ============= ================================ + User Register Description + ============= ================================ + 0 Global Internal Table (32-bit pointer) + 1 Per-Shader Internal Table (32-bit pointer) + 2 - 11 Application-Controlled User Data (10 32-bit values) + 12 Spill Table (32-bit pointer) + 13 - 14 Thread Group Count (64-bit pointer) + 15 GDS Range + ============= ================================ + +Graphics User Data +~~~~~~~~~~~~~~~~~~ + +Graphics pipelines support a much more flexible user data mapping: + + .. table:: PAL Graphics Shader User Data Registers + :name: pal-graphics-user-data-registers + + ============= ================================ + User Register Description + ============= ================================ + 0 Global Internal Table (32-bit pointer) + + Per-Shader Internal Table (32-bit pointer) + + 1-15 Application Controlled User Data + (1-15 Contiguous 32-bit Values in Registers) + + Spill Table (32-bit pointer) + + Draw Index (First Stage Only) + + Vertex Offset (First Stage Only) + + Instance Offset (First Stage Only) + ============= ================================ + + The placement of the global internal table remains fixed in the first *user + data SGPR register*. Otherwise all parameters are optional, and can be mapped + to any desired *user data SGPR register*, with the following regstrictions: + + * Draw Index, Vertex Offset, and Instance Offset can only be used by the first + activehardware stage in a graphics pipeline (i.e. where the API vertex + shader runs). + + * Application-controlled user data must be mapped into a contiguous range of + user data registers. + + * The application-controlled user data range supports compaction remapping, so + only *entries* that are actually consumed by the shader must be assigned to + corresponding *registers*. Note that in order to support an efficient runtime + implementation, the remapping must pack *registers* in the same order as + *entries*, with unused *entries* removed. + +.. _pal_global_internal_table: + +Global Internal Table +~~~~~~~~~~~~~~~~~~~~~ + +The global internal table is a table of *shader resource descriptors* (SRDs) that +define how certain engine-wide, runtime-managed resources should be accessed +from a shader. The majority of these resources have HW-defined formats, and it +is up to the compiler to write/read data as required by the target hardware. + +The following table illustrates the required format: + + .. table:: PAL Global Internal Table + :name: pal-git-table + + ============= ================================ + Offset Description + ============= ================================ + 0-3 Graphics Scratch SRD + 4-7 Compute Scratch SRD + 8-11 ES/GS Ring Output SRD + 12-15 ES/GS Ring Input SRD + 16-19 GS/VS Ring Output #0 + 20-23 GS/VS Ring Output #1 + 24-27 GS/VS Ring Output #2 + 28-31 GS/VS Ring Output #3 + 32-35 GS/VS Ring Input SRD + 36-39 Tessellation Factor Buffer SRD + 40-43 Off-Chip LDS Buffer SRD + 44-47 Off-Chip Param Cache Buffer SRD + 48-51 Sample Position Buffer SRD + 52 vaRange::ShadowDescriptorTable High Bits + ============= ================================ + + The pointer to the global internal table passed to the shader as user data + is a 32-bit pointer. The top 32 bits should be assumed to be the same as + the top 32 bits of the pipeline, so the shader may use the program + counter's top 32 bits. + Unspecified OS -------------- diff --git a/docs/AliasAnalysis.rst b/docs/AliasAnalysis.rst index 0a5cb00a48d3b0c844474dc3208285c96c69c5e2..14decfeca6e72c0e7169d1b623f363c7f5a9a50b 100644 --- a/docs/AliasAnalysis.rst +++ b/docs/AliasAnalysis.rst @@ -389,11 +389,6 @@ in its ``getAnalysisUsage`` that it does so. Some passes attempt to use ``AU.addPreserved``, however this doesn't actually have any effect. -``AliasAnalysisCounter`` (``-count-aa``) are implemented as ``ModulePass`` -classes, so if your alias analysis uses ``FunctionPass``, it won't be able to -use these utilities. If you try to use them, the pass manager will silently -route alias analysis queries directly to ``BasicAliasAnalysis`` instead. - Similarly, the ``opt -p`` option introduces ``ModulePass`` passes between each pass, which prevents the use of ``FunctionPass`` alias analysis passes. @@ -408,17 +403,10 @@ before it appears in an alias query. However, popular clients such as ``GVN`` don't support this, and are known to trigger errors when run with the ``AliasAnalysisDebugger``. -Due to several of the above limitations, the most obvious use for the -``AliasAnalysisCounter`` utility, collecting stats on all alias queries in a -compilation, doesn't work, even if the ``AliasAnalysis`` implementations don't -use ``FunctionPass``. There's no way to set a default, much less a default -sequence, and there's no way to preserve it. - The ``AliasSetTracker`` class (which is used by ``LICM``) makes a -non-deterministic number of alias queries. This can cause stats collected by -``AliasAnalysisCounter`` to have fluctuations among identical runs, for -example. Another consequence is that debugging techniques involving pausing -execution after a predetermined number of queries can be unreliable. +non-deterministic number of alias queries. This can cause debugging techniques +involving pausing execution after a predetermined number of queries to be +unreliable. Many alias queries can be reformulated in terms of other alias queries. When multiple ``AliasAnalysis`` queries are chained together, it would make sense to @@ -676,21 +664,6 @@ you're using the ``AliasSetTracker`` class. To use it, use something like: % opt -ds-aa -print-alias-sets -disable-output -The ``-count-aa`` pass -^^^^^^^^^^^^^^^^^^^^^^ - -The ``-count-aa`` pass is useful to see how many queries a particular pass is -making and what responses are returned by the alias analysis. As an example: - -.. code-block:: bash - - % opt -basicaa -count-aa -ds-aa -count-aa -licm - -will print out how many queries (and what responses are returned) by the -``-licm`` pass (of the ``-ds-aa`` pass) and how many queries are made of the -``-basicaa`` pass by the ``-ds-aa`` pass. This can be useful when debugging a -transformation or an alias analysis implementation. - The ``-aa-eval`` pass ^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/BitCodeFormat.rst b/docs/BitCodeFormat.rst index 6da69bc694d824e752c2548006cbd7a126e64ecd..5e1c5cacb439cbc9aa6d88dc2921a98fe5e0c156 100644 --- a/docs/BitCodeFormat.rst +++ b/docs/BitCodeFormat.rst @@ -1056,6 +1056,7 @@ The integer codes are mapped to well-known attributes as follows. * code 55: ``sanitize_hwaddress`` * code 56: ``nocf_check`` * code 57: ``optforfuzzing`` +* code 58: ``shadowcallstack`` .. note:: The ``allocsize`` attribute has a special encoding for its arguments. Its two diff --git a/docs/Bugpoint.rst b/docs/Bugpoint.rst index 27732e0fffbdd52a5ffb710ec6e2922ffdac91bf..f3bb54cffb54e12e878ff7c1f38bab3740576d32 100644 --- a/docs/Bugpoint.rst +++ b/docs/Bugpoint.rst @@ -198,14 +198,14 @@ desired ranges. For example: static int calledCount = 0; calledCount++; - DEBUG(if (calledCount < 212) return false); - DEBUG(if (calledCount > 217) return false); - DEBUG(if (calledCount == 213) return false); - DEBUG(if (calledCount == 214) return false); - DEBUG(if (calledCount == 215) return false); - DEBUG(if (calledCount == 216) return false); - DEBUG(dbgs() << "visitXOR calledCount: " << calledCount << "\n"); - DEBUG(dbgs() << "I: "; I->dump()); + LLVM_DEBUG(if (calledCount < 212) return false); + LLVM_DEBUG(if (calledCount > 217) return false); + LLVM_DEBUG(if (calledCount == 213) return false); + LLVM_DEBUG(if (calledCount == 214) return false); + LLVM_DEBUG(if (calledCount == 215) return false); + LLVM_DEBUG(if (calledCount == 216) return false); + LLVM_DEBUG(dbgs() << "visitXOR calledCount: " << calledCount << "\n"); + LLVM_DEBUG(dbgs() << "I: "; I->dump()); could be added to ``visitXOR`` to limit ``visitXor`` to being applied only to calls 212 and 217. This is from an actual test case and raises an important diff --git a/docs/CFIVerify.rst b/docs/CFIVerify.rst index 7424d01c90b510cc4f3c4ea4aa2784aa3d2d194a..a1182a8fcfc2cabaeba8b3a8a146b82c5671a3c3 100644 --- a/docs/CFIVerify.rst +++ b/docs/CFIVerify.rst @@ -25,8 +25,8 @@ This tool will be present as a part of the LLVM toolchain, and will reside in the "/llvm/tools/llvm-cfi-verify" directory, relative to the LLVM trunk. It will be tested in two methods: -- Unit tests to validate code sections, present in "/llvm/unittests/llvm-cfi- - verify". +- Unit tests to validate code sections, present in + "/llvm/unittests/tools/llvm-cfi-verify". - Integration tests, present in "/llvm/tools/clang/test/LLVMCFIVerify". These integration tests are part of clang as part of a continuous integration framework, ensuring updates to the compiler that reduce CFI coverage on diff --git a/docs/CMake.rst b/docs/CMake.rst index b3fa4b4149e4313fbf9f0765107d3bceb98dc9d5..7ee1682d51e5d5defbd266f7cb2bea79810b2f39 100644 --- a/docs/CMake.rst +++ b/docs/CMake.rst @@ -228,10 +228,6 @@ LLVM-specific variables Install symlinks from the binutils tool names to the corresponding LLVM tools. For example, ar will be symlinked to llvm-ar. -**LLVM_INSTALL_CCTOOLS_SYMLINKS**:BOOL - Install symliks from the cctools tool names to the corresponding LLVM tools. - For example, dsymutil will be symlinked to llvm-dsymutil. - **LLVM_BUILD_EXAMPLES**:BOOL Build LLVM examples. Defaults to OFF. Targets for building each example are generated in any case. See documentation for *LLVM_BUILD_TOOLS* above for more @@ -374,6 +370,11 @@ LLVM-specific variables **LLVM_USE_INTEL_JITEVENTS**:BOOL Enable building support for Intel JIT Events API. Defaults to OFF. +**LLVM_ENABLE_LIBPFM**:BOOL + Enable building with libpfm to support hardware counter measurements in LLVM + tools. + Defaults to ON. + **LLVM_ENABLE_ZLIB**:BOOL Enable building with zlib to support compression/uncompression in LLVM tools. Defaults to ON. diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst index 4c515f6ace82a4063ef8a841f9d1e7000d396663..feb3bf0eb03a62a3af2bd89f28cba06b7848c044 100644 --- a/docs/CodingStandards.rst +++ b/docs/CodingStandards.rst @@ -91,9 +91,9 @@ guidance below to help you know what to expect. Each toolchain provides a good reference for what it accepts: -* Clang: http://clang.llvm.org/cxx_status.html -* GCC: http://gcc.gnu.org/projects/cxx0x.html -* MSVC: http://msdn.microsoft.com/en-us/library/hh567368.aspx +* Clang: https://clang.llvm.org/cxx_status.html +* GCC: https://gcc.gnu.org/projects/cxx-status.html#cxx11 +* MSVC: https://msdn.microsoft.com/en-us/library/hh567368.aspx In most cases, the MSVC list will be the dominating factor. Here is a summary of the features that are expected to work. Features not on this list are @@ -184,7 +184,7 @@ you hit a type trait which doesn't work we can then add support to LLVM's traits header to emulate it. .. _the libstdc++ manual: - http://gcc.gnu.org/onlinedocs/gcc-4.8.0/libstdc++/manual/manual/status.html#status.iso.2011 + https://gcc.gnu.org/onlinedocs/gcc-4.8.0/libstdc++/manual/manual/status.html#status.iso.2011 Other Languages --------------- @@ -591,7 +591,7 @@ understood for formatting nested function calls. Examples: This formatting scheme also makes it particularly easy to get predictable, consistent, and automatic formatting with tools like `Clang Format`_. -.. _Clang Format: http://clang.llvm.org/docs/ClangFormat.html +.. _Clang Format: https://clang.llvm.org/docs/ClangFormat.html Language and Compiler Issues ---------------------------- @@ -667,14 +667,14 @@ Do not use Static Constructors Static constructors and destructors (e.g. global variables whose types have a constructor or destructor) should not be added to the code base, and should be removed wherever possible. Besides `well known problems -`_ where the order of +`_ where the order of initialization is undefined between globals in different source files, the entire concept of static constructors is at odds with the common use case of LLVM as a library linked into a larger application. Consider the use of LLVM as a JIT linked into another application (perhaps for -`OpenGL, custom languages `_, `shaders in movies -`_, etc). Due to the +`OpenGL, custom languages `_, `shaders in movies +`_, etc). Due to the design of static constructors, they must be executed at startup time of the entire application, regardless of whether or how LLVM is used in that larger application. There are two problems with this: @@ -692,7 +692,7 @@ target or other library into an application, but static constructors violate this goal. That said, LLVM unfortunately does contain static constructors. It would be a -`great project `_ for someone to purge all static +`great project `_ for someone to purge all static constructors from LLVM, and then enable the ``-Wglobal-constructors`` warning flag (when building with Clang) to ensure we do not regress in the future. @@ -808,8 +808,8 @@ As a rule of thumb, use ``auto &`` unless you need to copy the result, and use for (auto Val : Container) { Val.change(); saveSomewhere(Val); } // Copy pointers, but make it clear that they're pointers. - for (const auto \*Ptr : Container) { observe(\*Ptr); } - for (auto \*Ptr : Container) { Ptr->change(); } + for (const auto *Ptr : Container) { observe(*Ptr); } + for (auto *Ptr : Container) { Ptr->change(); } Beware of non-determinism due to ordering of pointers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -826,6 +826,17 @@ As a rule of thumb, in case an ordered result is expected, remember to sort an unordered container before iteration. Or use ordered containers like vector/MapVector/SetVector if you want to iterate pointer keys. +Beware of non-deterministic sorting order of equal elements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +std::sort uses a non-stable sorting algorithm in which the order of equal +elements is not guaranteed to be preserved. Thus using std::sort for a +container having equal elements may result in non-determinstic behavior. +To uncover such instances of non-determinism, LLVM has introduced a new +llvm::sort wrapper function. For an EXPENSIVE_CHECKS build this will randomly +shuffle the container before sorting. As a rule of thumb, always make sure to +use llvm::sort instead of std::sort. + Style Issues ============ @@ -1686,12 +1697,12 @@ A lot of these comments and recommendations have been culled from other sources. Two particularly important books for our work are: #. `Effective C++ - `_ + `_ by Scott Meyers. Also interesting and useful are "More Effective C++" and "Effective STL" by the same author. #. `Large-Scale C++ Software Design - `_ + `_ by John Lakos If you get some free time, and you haven't read them: do so, you might learn diff --git a/docs/CommandGuide/dsymutil.rst b/docs/CommandGuide/dsymutil.rst index a89ee1879220a7762d9726acbfb7c49e3be3bd84..ceaa54019a819b24a93354b2bdff7ea696035c0b 100644 --- a/docs/CommandGuide/dsymutil.rst +++ b/docs/CommandGuide/dsymutil.rst @@ -70,6 +70,13 @@ OPTIONS Specifies a ``path`` to prepend to all debug symbol object file paths. +.. option:: --papertrail + + When running dsymutil as part of your build system, it can be desirable for + warnings to be part of the end product, rather than just being emitted to the + output stream. When enabled warnings are embedded in the linked DWARF debug + information. + .. option:: -s, --symtab Dumps the symbol table found in *executable* or object file(s) and exits. diff --git a/docs/CommandGuide/index.rst b/docs/CommandGuide/index.rst index d596667abcb9684619805e7ce4567953461f34b2..95efffdb65693380a01ba3b9ace67adebfeab99f 100644 --- a/docs/CommandGuide/index.rst +++ b/docs/CommandGuide/index.rst @@ -53,5 +53,6 @@ Developer Tools tblgen lit llvm-build + llvm-exegesis llvm-pdbutil llvm-readobj diff --git a/docs/CommandGuide/lit.rst b/docs/CommandGuide/lit.rst index fbe1a9ab1843f950fd61efe4b20da40862f4e6f7..0d39311152d2a785b485bf16754d4763551afc08 100644 --- a/docs/CommandGuide/lit.rst +++ b/docs/CommandGuide/lit.rst @@ -85,6 +85,10 @@ OUTPUT OPTIONS Echo all commands to stdout, as they are being executed. This can be valuable for debugging test failures, as the last echoed command will be the one which has failed. + :program:`lit` normally inserts a no-op command (``:`` in the case of bash) + with argument ``'RUN: at line N'`` before each command pipeline, and this + option also causes those no-op commands to be echoed to stdout to help you + locate the source line of the failed command. This option implies ``--verbose``. .. option:: -a, --show-all diff --git a/docs/CommandGuide/llvm-cov.rst b/docs/CommandGuide/llvm-cov.rst index 85c8dde64961f4703a9470f858d8237d6d1b7cd4..8e9c78c23a1a28acaf35c7c691b85c78b3f56a2f 100644 --- a/docs/CommandGuide/llvm-cov.rst +++ b/docs/CommandGuide/llvm-cov.rst @@ -246,6 +246,10 @@ OPTIONS Show code coverage only for functions that match the given regular expression. +.. option:: -ignore-filename-regex= + + Skip source code files with file paths that match the given regular expression. + .. option:: -format= Use the specified output format. The supported formats are: "text", "html". @@ -351,6 +355,10 @@ OPTIONS Show statistics for all function instantiations. Defaults to false. +.. option:: -ignore-filename-regex= + + Skip source code files with file paths that match the given regular expression. + .. program:: llvm-cov export .. _llvm-cov-export: @@ -390,3 +398,7 @@ OPTIONS will not export coverage information for smaller units such as individual functions or regions. The result will be the same as produced by :program: `llvm-cov report` command, but presented in JSON format rather than text. + +.. option:: -ignore-filename-regex= + + Skip source code files with file paths that match the given regular expression. diff --git a/docs/CommandGuide/llvm-exegesis-analysis.png b/docs/CommandGuide/llvm-exegesis-analysis.png new file mode 100644 index 0000000000000000000000000000000000000000..e232f5f123559a7f91b13ba214e9d60e14f4508e Binary files /dev/null and b/docs/CommandGuide/llvm-exegesis-analysis.png differ diff --git a/docs/CommandGuide/llvm-exegesis.rst b/docs/CommandGuide/llvm-exegesis.rst new file mode 100644 index 0000000000000000000000000000000000000000..1cba978858431cfc442299ab283c5196073eb55c --- /dev/null +++ b/docs/CommandGuide/llvm-exegesis.rst @@ -0,0 +1,182 @@ +llvm-exegesis - LLVM Machine Instruction Benchmark +================================================== + +SYNOPSIS +-------- + +:program:`llvm-exegesis` [*options*] + +DESCRIPTION +----------- + +:program:`llvm-exegesis` is a benchmarking tool that uses information available +in LLVM to measure host machine instruction characteristics like latency or port +decomposition. + +Given an LLVM opcode name and a benchmarking mode, :program:`llvm-exegesis` +generates a code snippet that makes execution as serial (resp. as parallel) as +possible so that we can measure the latency (resp. uop decomposition) of the +instruction. +The code snippet is jitted and executed on the host subtarget. The time taken +(resp. resource usage) is measured using hardware performance counters. The +result is printed out as YAML to the standard output. + +The main goal of this tool is to automatically (in)validate the LLVM's TableDef +scheduling models. To that end, we also provide analysis of the results. + +EXAMPLES: benchmarking +---------------------- + +Assume you have an X86-64 machine. To measure the latency of a single +instruction, run: + +.. code-block:: bash + + $ llvm-exegesis -mode=latency -opcode-name=ADD64rr + +Measuring the uop decomposition of an instruction works similarly: + +.. code-block:: bash + + $ llvm-exegesis -mode=uops -opcode-name=ADD64rr + +The output is a YAML document (the default is to write to stdout, but you can +redirect the output to a file using `-benchmarks-file`): + +.. code-block:: none + + --- + key: + opcode_name: ADD64rr + mode: latency + config: '' + cpu_name: haswell + llvm_triple: x86_64-unknown-linux-gnu + num_repetitions: 10000 + measurements: + - { key: latency, value: 1.0058, debug_string: '' } + error: '' + info: 'explicit self cycles, selecting one aliasing configuration. + Snippet: + ADD64rr R8, R8, R10 + ' + ... + +To measure the latency of all instructions for the host architecture, run: + +.. code-block:: bash + + #!/bin/bash + readonly INSTRUCTIONS=$(($(grep INSTRUCTION_LIST_END build/lib/Target/X86/X86GenInstrInfo.inc | cut -f2 -d=) - 1)) + for INSTRUCTION in $(seq 1 ${INSTRUCTIONS}); + do + ./build/bin/llvm-exegesis -mode=latency -opcode-index=${INSTRUCTION} | sed -n '/---/,$p' + done + +FIXME: Provide an :program:`llvm-exegesis` option to test all instructions. + +EXAMPLES: analysis +---------------------- + +Assuming you have a set of benchmarked instructions (either latency or uops) as +YAML in file `/tmp/benchmarks.yaml`, you can analyze the results using the +following command: + +.. code-block:: bash + + $ llvm-exegesis -mode=analysis \ + -benchmarks-file=/tmp/benchmarks.yaml \ + -analysis-clusters-output-file=/tmp/clusters.csv \ + -analysis-inconsistencies-output-file=/tmp/inconsistencies.txt + +This will group the instructions into clusters with the same performance +characteristics. The clusters will be written out to `/tmp/clusters.csv` in the +following format: + +.. code-block:: none + + cluster_id,opcode_name,config,sched_class + ... + 2,ADD32ri8_DB,,WriteALU,1.00 + 2,ADD32ri_DB,,WriteALU,1.01 + 2,ADD32rr,,WriteALU,1.01 + 2,ADD32rr_DB,,WriteALU,1.00 + 2,ADD32rr_REV,,WriteALU,1.00 + 2,ADD64i32,,WriteALU,1.01 + 2,ADD64ri32,,WriteALU,1.01 + 2,MOVSX64rr32,,BSWAP32r_BSWAP64r_MOVSX64rr32,1.00 + 2,VPADDQYrr,,VPADDBYrr_VPADDDYrr_VPADDQYrr_VPADDWYrr_VPSUBBYrr_VPSUBDYrr_VPSUBQYrr_VPSUBWYrr,1.02 + 2,VPSUBQYrr,,VPADDBYrr_VPADDDYrr_VPADDQYrr_VPADDWYrr_VPSUBBYrr_VPSUBDYrr_VPSUBQYrr_VPSUBWYrr,1.01 + 2,ADD64ri8,,WriteALU,1.00 + 2,SETBr,,WriteSETCC,1.01 + ... + +:program:`llvm-exegesis` will also analyze the clusters to point out +inconsistencies in the scheduling information. The output is an html file. For +example, `/tmp/inconsistencies.html` will contain messages like the following : + +.. image:: llvm-exegesis-analysis.png + :align: center + +Note that the scheduling class names will be resolved only when +:program:`llvm-exegesis` is compiled in debug mode, else only the class id will +be shown. This does not invalidate any of the analysis results though. + + +OPTIONS +------- + +.. option:: -help + + Print a summary of command line options. + +.. option:: -opcode-index= + + Specify the opcode to measure, by index. + Either `opcode-index` or `opcode-name` must be set. + +.. option:: -opcode-name= + + Specify the opcode to measure, by name. + Either `opcode-index` or `opcode-name` must be set. + +.. option:: -mode=[latency|uops|analysis] + + Specify the run mode. + +.. option:: -num-repetitions= + + Specify the number of repetitions of the asm snippet. + Higher values lead to more accurate measurements but lengthen the benchmark. + + .. option:: -benchmarks-file= + + File to read (`analysis` mode) or write (`latency`/`uops` modes) benchmark + results. "-" uses stdin/stdout. + +.. option:: -analysis-clusters-output-file= + + If provided, write the analysis clusters as CSV to this file. "-" prints to + stdout. + +.. option:: -analysis-inconsistencies-output-file= + + If non-empty, write inconsistencies found during analysis to this file. `-` + prints to stdout. + +.. option:: -analysis-numpoints= + + Specify the numPoints parameters to be used for DBSCAN clustering + (`analysis` mode). + +.. option:: -analysis-espilon= + + Specify the numPoints parameters to be used for DBSCAN clustering + (`analysis` mode). + + +EXIT STATUS +----------- + +:program:`llvm-exegesis` returns 0 on success. Otherwise, an error message is +printed to standard error, and the tool returns a non 0 value. diff --git a/docs/CommandGuide/llvm-mca.rst b/docs/CommandGuide/llvm-mca.rst index 97a27f043c6f447434a1fb1db054294ec6c647f1..b921f35830b0e26c688fc946b00b09ffa2686b51 100644 --- a/docs/CommandGuide/llvm-mca.rst +++ b/docs/CommandGuide/llvm-mca.rst @@ -25,6 +25,50 @@ Given an assembly code sequence, llvm-mca estimates the IPC (Instructions Per Cycle), as well as hardware resource pressure. The analysis and reporting style were inspired by the IACA tool from Intel. +:program:`llvm-mca` allows the usage of special code comments to mark regions of +the assembly code to be analyzed. A comment starting with substring +``LLVM-MCA-BEGIN`` marks the beginning of a code region. A comment starting with +substring ``LLVM-MCA-END`` marks the end of a code region. For example: + +.. code-block:: none + + # LLVM-MCA-BEGIN My Code Region + ... + # LLVM-MCA-END + +Multiple regions can be specified provided that they do not overlap. A code +region can have an optional description. If no user-defined region is specified, +then :program:`llvm-mca` assumes a default region which contains every +instruction in the input file. Every region is analyzed in isolation, and the +final performance report is the union of all the reports generated for every +code region. + +Inline assembly directives may be used from source code to annotate the +assembly text: + +.. code-block:: c++ + + int foo(int a, int b) { + __asm volatile("# LLVM-MCA-BEGIN foo"); + a += 42; + __asm volatile("# LLVM-MCA-END"); + a *= b; + return a; + } + +So for example, you can compile code with clang, output assembly, and pipe it +directly into llvm-mca for analysis: + +.. code-block:: bash + + $ clang foo.c -O2 -target x86_64-unknown-unknown -S -o - | llvm-mca -mcpu=btver2 + +Or for Intel syntax: + +.. code-block:: bash + + $ clang foo.c -O2 -target x86_64-unknown-unknown -mllvm -x86-asm-syntax=intel -S -o - | llvm-mca -mcpu=btver2 + OPTIONS ------- @@ -51,9 +95,8 @@ option specifies "``-``", then the output will also be sent to standard output. .. option:: -mcpu= - Specify the processor for whic to run the analysis. - By default this defaults to a "generic" processor. It is not autodetected to - the current architecture. + Specify the processor for which to analyze the code. By default, the cpu name + is autodetected from the host. .. option:: -output-asm-variant= @@ -65,25 +108,19 @@ option specifies "``-``", then the output will also be sent to standard output. .. option:: -dispatch= Specify a different dispatch width for the processor. The dispatch width - defaults to the 'IssueWidth' specified by the processor scheduling model. - If width is zero, then the default dispatch width is used. - -.. option:: -max-retire-per-cycle= - - Specify the retire throughput (i.e. how many instructions can be retired by the - retire control unit every cycle). + defaults to field 'IssueWidth' in the processor scheduling model. If width is + zero, then the default dispatch width is used. .. option:: -register-file-size= - Specify the size of the register file. When specified, this flag limits - how many temporary registers are available for register renaming purposes. By - default, the number of temporary registers is unlimited. A value of zero for - this flag means "unlimited number of temporary registers". + Specify the size of the register file. When specified, this flag limits how + many temporary registers are available for register renaming purposes. A value + of zero for this flag means "unlimited number of temporary registers". .. option:: -iterations= Specify the number of iterations to run. If this flag is set to 0, then the - tool sets the number of iterations to a default value (i.e. 70). + tool sets the number of iterations to a default value (i.e. 100). .. option:: -noalias= @@ -104,12 +141,6 @@ option specifies "``-``", then the output will also be sent to standard output. queue. A value of zero for this flag is ignored, and the default store queue size is used instead. -.. option:: -verbose - - Enable verbose output. In particular, this flag enables a number of extra - statistics and performance counters for the dispatch logic, the reorder - buffer, the retire control unit and the register file. - .. option:: -timeline Enable the timeline view. @@ -128,10 +159,39 @@ option specifies "``-``", then the output will also be sent to standard output. Enable the resource pressure view. This is enabled by default. +.. option:: -register-file-stats + + Enable register file usage statistics. + +.. option:: -dispatch-stats + + Enable extra dispatch statistics. This view collects and analyzes instruction + dispatch events, as well as static/dynamic dispatch stall events. This view + is disabled by default. + +.. option:: -scheduler-stats + + Enable extra scheduler statistics. This view collects and analyzes instruction + issue events. This view is disabled by default. + +.. option:: -retire-stats + + Enable extra retire control unit statistics. This view is disabled by default. + .. option:: -instruction-info Enable the instruction info view. This is enabled by default. +.. option:: -all-stats + + Print all hardware statistics. This enables extra statistics related to the + dispatch logic, the hardware schedulers, the register file(s), and the retire + control unit. This option is disabled by default. + +.. option:: -all-views + + Enable all the view. + .. option:: -instruction-tables Prints resource pressure information based on the static information diff --git a/docs/CommandGuide/opt.rst b/docs/CommandGuide/opt.rst index 7b9255d26423189f608c68f405d890ebb6415df5..2b2fffa063a0f73020d16551e273fe62bcffd29d 100644 --- a/docs/CommandGuide/opt.rst +++ b/docs/CommandGuide/opt.rst @@ -96,7 +96,7 @@ OPTIONS .. option:: -debug If this is a debug build, this option will enable debug printouts from passes - which use the ``DEBUG()`` macro. See the `LLVM Programmer's Manual + which use the ``LLVM_DEBUG()`` macro. See the `LLVM Programmer's Manual <../ProgrammersManual.html>`_, section ``#DEBUG`` for more information. .. option:: -load= diff --git a/docs/CommandLine.rst b/docs/CommandLine.rst index 5d2a39d45a17065f2acb87ae9507d64af535079d..9a6a196b431c152f8d881858e873f0bf212fe749 100644 --- a/docs/CommandLine.rst +++ b/docs/CommandLine.rst @@ -886,12 +886,12 @@ To do this, set up your .h file with your option, like this for example: // debug build, then the code specified as the option to the macro will be // executed. Otherwise it will not be. #ifdef NDEBUG - #define DEBUG(X) + #define LLVM_DEBUG(X) #else - #define DEBUG(X) do { if (DebugFlag) { X; } } while (0) + #define LLVM_DEBUG(X) do { if (DebugFlag) { X; } } while (0) #endif -This allows clients to blissfully use the ``DEBUG()`` macro, or the +This allows clients to blissfully use the ``LLVM_DEBUG()`` macro, or the ``DebugFlag`` explicitly if they want to. Now we just need to be able to set the ``DebugFlag`` boolean when the option is set. To do this, we pass an additional argument to our command line argument processor, and we specify where @@ -1716,7 +1716,7 @@ line option outside of the library. In these cases the library does or should provide an external storage location that is accessible to users of the library. Examples of this include the ``llvm::DebugFlag`` exported by the ``lib/Support/Debug.cpp`` file and the ``llvm::TimePassesIsEnabled`` flag -exported by the ``lib/VMCore/PassManager.cpp`` file. +exported by the ``lib/IR/PassManager.cpp`` file. .. todo:: diff --git a/docs/Coroutines.rst b/docs/Coroutines.rst index 1bea04ebdd2ac8905ca7cb6082041820808d028f..f3667585c6c26213f8e043161b81e20602ce3e80 100644 --- a/docs/Coroutines.rst +++ b/docs/Coroutines.rst @@ -880,6 +880,32 @@ Example: %phi = phi i8* [ null, %entry ], [ %alloc, %coro.alloc ] %frame = call i8* @llvm.coro.begin(token %id, i8* %phi) +.. _coro.noop: + +'llvm.coro.noop' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i8* @llvm.coro.noop() + +Overview: +""""""""" + +The '``llvm.coro.noop``' intrinsic returns an address of the coroutine frame of +a coroutine that does nothing when resumed or destroyed. + +Arguments: +"""""""""" + +None + +Semantics: +"""""""""" + +This intrinsic is lowered to refer to a private constant coroutine frame. The +resume and destroy handlers for this frame are empty functions that do nothing. +Note that in different translation units llvm.coro.noop may return different pointers. + .. _coro.frame: 'llvm.coro.frame' Intrinsic diff --git a/docs/ExceptionHandling.rst b/docs/ExceptionHandling.rst index e65c1bede0433e6276a77e90154dc5a7e8952eec..18ff53cd3b6f0c77cbf31a247e1f5744aae08598 100644 --- a/docs/ExceptionHandling.rst +++ b/docs/ExceptionHandling.rst @@ -365,7 +365,7 @@ abstract interface. When used in the native Windows C++ exception handling implementation, this intrinsic serves as a placeholder to delimit code before a catch handler is -outlined. When the handler is is outlined, this intrinsic will be replaced +outlined. When the handler is outlined, this intrinsic will be replaced by instructions that retrieve the exception object pointer from the frame allocation block. diff --git a/docs/Extensions.rst b/docs/Extensions.rst index fd67906a9ac10b8323940eccf21e1d555889e292..6f99006adc9522786270411a6f04a3b6675820f0 100644 --- a/docs/Extensions.rst +++ b/docs/Extensions.rst @@ -285,6 +285,50 @@ The following directives are specified: The paramter identifies an additional library search path to be considered when looking up libraries after the inclusion of this option. +``SHT_LLVM_CALL_GRAPH_PROFILE`` Section (Call Graph Profile) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section is used to pass a call graph profile to the linker which can be +used to optimize the placement of sections. It contains a sequence of +(from symbol, to symbol, weight) tuples. + +It shall have a type of ``SHT_LLVM_CALL_GRAPH_PROFILE`` (0x6fff4c02), shall +have the ``SHF_EXCLUDE`` flag set, the ``sh_link`` member shall hold the section +header index of the associated symbol table, and shall have a ``sh_entsize`` of +16. It should be named ``.llvm.call-graph-profile``. + +The contents of the section shall be a sequence of ``Elf_CGProfile`` entries. + +.. code-block:: c + + typedef struct { + Elf_Word cgp_from; + Elf_Word cgp_to; + Elf_Xword cgp_weight; + } Elf_CGProfile; + +cgp_from + The symbol index of the source of the edge. + +cgp_to + The symbol index of the destination of the edge. + +cgp_weight + The weight of the edge. + +This is represented in assembly as: + +.. code-block:: gas + + .cg_profile from, to, 42 + +``.cg_profile`` directives are processed at the end of the file. It is an error +if either ``from`` or ``to`` are undefined temporary symbols. If either symbol +is a temporary symbol, then the section symbol is used instead. If either +symbol is undefined, then that symbol is defined as if ``.weak symbol`` has been +written at the end of the file. This forces the symbol to show up in the symbol +table. + Target Specific Behaviour ========================= diff --git a/docs/GarbageCollection.rst b/docs/GarbageCollection.rst index 4ef174410b788f5906ceab509b2b046a3a1708cc..e4f5802f887949058b6c3cd476ad42c0a2603122 100644 --- a/docs/GarbageCollection.rst +++ b/docs/GarbageCollection.rst @@ -433,7 +433,7 @@ data structure, but there are only 20 lines of meaningful code.) .. code-block:: c++ - /// @brief The map for a single function's stack frame. One of these is + /// The map for a single function's stack frame. One of these is /// compiled as constant data into the executable for each function. /// /// Storage of metadata values is elided if the %metadata parameter to @@ -444,7 +444,7 @@ data structure, but there are only 20 lines of meaningful code.) const void *Meta[0]; //< Metadata for each root. }; - /// @brief A link in the dynamic shadow stack. One of these is embedded in + /// A link in the dynamic shadow stack. One of these is embedded in /// the stack frame of each function on the call stack. struct StackEntry { StackEntry *Next; //< Link to next stack entry (the caller's). @@ -452,13 +452,13 @@ data structure, but there are only 20 lines of meaningful code.) void *Roots[0]; //< Stack roots (in-place array). }; - /// @brief The head of the singly-linked list of StackEntries. Functions push + /// The head of the singly-linked list of StackEntries. Functions push /// and pop onto this in their prologue and epilogue. /// /// Since there is only a global list, this technique is not threadsafe. StackEntry *llvm_gc_root_chain; - /// @brief Calls Visitor(root, meta) for each GC root on the stack. + /// Calls Visitor(root, meta) for each GC root on the stack. /// root and meta are exactly the values passed to /// @llvm.gcroot. /// @@ -1032,7 +1032,7 @@ a realistic example: // Emit PointCount. OS.AddComment("safe point count"); - AP.EmitInt32(MD.size()); + AP.emitInt32(MD.size()); // And each safe point... for (GCFunctionInfo::iterator PI = MD.begin(), @@ -1049,18 +1049,18 @@ a realistic example: // Emit the stack frame size. OS.AddComment("stack frame size (in words)"); - AP.EmitInt32(MD.getFrameSize() / IntPtrSize); + AP.emitInt32(MD.getFrameSize() / IntPtrSize); // Emit stack arity, i.e. the number of stacked arguments. unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6; unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ? MD.getFunction().arg_size() - RegisteredArgs : 0; OS.AddComment("stack arity"); - AP.EmitInt32(StackArity); + AP.emitInt32(StackArity); // Emit the number of live roots in the function. OS.AddComment("live root count"); - AP.EmitInt32(MD.live_size(PI)); + AP.emitInt32(MD.live_size(PI)); // And for each live root... for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI), @@ -1068,7 +1068,7 @@ a realistic example: LI != LE; ++LI) { // Emit live root's offset within the stack frame. OS.AddComment("stack index (offset / wordsize)"); - AP.EmitInt32(LI->StackOffset); + AP.emitInt32(LI->StackOffset); } } } diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 035019499c12c4959f4d8d9bf0d10c59d63c8156..0c08de6107cb1b838cbe52ad7cb86c3d0fbaa9eb 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -80,7 +80,7 @@ identifiers, for different purposes: characters may be escaped using ``"\xx"`` where ``xx`` is the ASCII code for the character in hexadecimal. In this way, any character can be used in a name value, even quotes themselves. The ``"\01"`` prefix - can be used on global variables to suppress mangling. + can be used on global values to suppress mangling. #. Unnamed values are represented as an unsigned numeric value with their prefix. For example, ``%12``, ``@2``, ``%44``. #. Constants, which are described in the section Constants_ below. @@ -1708,6 +1708,11 @@ example: entity to fine grain the HW control flow protection mechanism. The flag is target independant and currently appertains to a function or function pointer. +``shadowcallstack`` + This attribute indicates that the ShadowCallStack checks are enabled for + the function. The instrumentation checks that the return address for the + function has not changed between the function prolog and eiplog. It is + currently x86_64-specific. .. _glattrs: @@ -4737,7 +4742,7 @@ As a concrete example, the type descriptor graph for the following program void f(struct Outer* outer, struct Inner* inner, float* f, int* i, char* c) { outer->f = 0; // tag0: (OuterStructTy, FloatScalarTy, 0) outer->inner_a.i = 0; // tag1: (OuterStructTy, IntScalarTy, 12) - outer->inner_a.f = 0.0; // tag2: (OuterStructTy, IntScalarTy, 16) + outer->inner_a.f = 0.0; // tag2: (OuterStructTy, FloatScalarTy, 16) *f = 0.0; // tag3: (FloatScalarTy, FloatScalarTy, 0) } @@ -5308,11 +5313,12 @@ Irreducible loop header weights are typically based on profile data. '``invariant.group``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The ``invariant.group`` metadata may be attached to ``load``/``store`` instructions. +The experimental ``invariant.group`` metadata may be attached to +``load``/``store`` instructions referencing a single metadata with no entries. The existence of the ``invariant.group`` metadata on the instruction tells the optimizer that every ``load`` and ``store`` to the same pointer operand -within the same invariant group can be assumed to load or store the same -value (but see the ``llvm.invariant.group.barrier`` intrinsic which affects +can be assumed to load or store the same +value (but see the ``llvm.launder.invariant.group`` intrinsic which affects when two pointers are considered the same). Pointers returned by bitcast or getelementptr with only zero indices are considered the same. @@ -5328,7 +5334,6 @@ Examples: %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change call void @foo(i8* %ptr) - %b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed %newPtr = call i8* @getPointer(i8* %ptr) %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr @@ -5337,16 +5342,15 @@ Examples: store i8 %unknownValue, i8* %ptr, !invariant.group !0 ; Can assume that %unknownValue == 42 call void @foo(i8* %ptr) - %newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr) - %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through invariant.group.barrier to get value of %ptr + %newPtr2 = call i8* @llvm.launder.invariant.group(i8* %ptr) + %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through launder.invariant.group to get value of %ptr ... declare void @foo(i8*) declare i8* @getPointer(i8*) - declare i8* @llvm.invariant.group.barrier(i8*) + declare i8* @llvm.launder.invariant.group(i8*) - !0 = !{!"magic ptr"} - !1 = !{!"other ptr"} + !0 = !{} The invariant.group metadata must be dropped when replacing one pointer by another based on aliasing information. This is because invariant.group is tied @@ -5358,6 +5362,8 @@ to the SSA value of the pointer operand. ; if %x mustalias %y then we can replace the above instruction with %v = load i8, i8* %y +Note that this is an experimental feature, which means that its semantics might +change in the future. '``type``' Metadata ^^^^^^^^^^^^^^^^^^^ @@ -5694,6 +5700,310 @@ Each individual option is required to be either a valid option for the target's linker, or an option that is reserved by the target specific assembly writer or object file emitter. No other aspect of these options is defined by the IR. +.. _summary: + +ThinLTO Summary +=============== + +Compiling with `ThinLTO `_ +causes the building of a compact summary of the module that is emitted into +the bitcode. The summary is emitted into the LLVM assembly and identified +in syntax by a caret ('``^``'). + +*Note that temporarily the summary entries are skipped when parsing the +assembly, although the parsing support is actively being implemented. The +following describes when the summary entries will be parsed once implemented.* +The summary will be parsed into a ModuleSummaryIndex object under the +same conditions where summary index is currently built from bitcode. +Specifically, tools that test the Thin Link portion of a ThinLTO compile +(i.e. llvm-lto and llvm-lto2), or when parsing a combined index +for a distributed ThinLTO backend via clang's "``-fthinlto-index=<>``" flag. +Additionally, it will be parsed into a bitcode output, along with the Module +IR, via the "``llvm-as``" tool. Tools that parse the Module IR for the purposes +of optimization (e.g. "``clang -x ir``" and "``opt``"), will ignore the +summary entries (just as they currently ignore summary entries in a bitcode +input file). + +There are currently 3 types of summary entries in the LLVM assembly: +:ref:`module paths`, +:ref:`global values`, and +:ref:`type identifiers`. + +.. _module_path_summary: + +Module Path Summary Entry +------------------------- + +Each module path summary entry lists a module containing global values included +in the summary. For a single IR module there will be one such entry, but +in a combined summary index produced during the thin link, there will be +one module path entry per linked module with summary. + +Example: + +.. code-block:: llvm + + ^0 = module: (path: "/path/to/file.o", hash: (2468601609, 1329373163, 1565878005, 638838075, 3148790418)) + +The ``path`` field is a string path to the bitcode file, and the ``hash`` +field is the 160-bit SHA-1 hash of the IR bitcode contents, used for +incremental builds and caching. + +.. _gv_summary: + +Global Value Summary Entry +-------------------------- + +Each global value summary entry corresponds to a global value defined or +referenced by a summarized module. + +Example: + +.. code-block:: llvm + + ^4 = gv: (name: "f"[, summaries: (Summary)[, (Summary)]*]?) ; guid = 14740650423002898831 + +For declarations, there will not be a summary list. For definitions, a +global value will contain a list of summaries, one per module containing +a definition. There can be multiple entries in a combined summary index +for symbols with weak linkage. + +Each ``Summary`` format will depend on whether the global value is a +:ref:`function`, :ref:`variable`, or +:ref:`alias`. + +.. _function_summary: + +Function Summary +^^^^^^^^^^^^^^^^ + +If the global value is a function, the ``Summary`` entry will look like: + +.. code-block:: llvm + + function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 2[, FuncFlags]?[, Calls]?[, TypeIdInfo]?[, Refs]? + +The ``module`` field includes the summary entry id for the module containing +this definition, and the ``flags`` field contains information such as +the linkage type, a flag indicating whether it is legal to import the +definition, whether it is globally live and whether the linker resolved it +to a local definition (the latter two are populated during the thin link). +The ``insts`` field contains the number of IR instructions in the function. +Finally, there are several optional fields: :ref:`FuncFlags`, +:ref:`Calls`, :ref:`TypeIdInfo`, +:ref:`Refs`. + +.. _variable_summary: + +Global Variable Summary +^^^^^^^^^^^^^^^^^^^^^^^ + +If the global value is a variable, the ``Summary`` entry will look like: + +.. code-block:: llvm + + variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0)[, Refs]? + +The variable entry contains a subset of the fields in a +:ref:`function summary `, see the descriptions there. + +.. _alias_summary: + +Alias Summary +^^^^^^^^^^^^^ + +If the global value is an alias, the ``Summary`` entry will look like: + +.. code-block:: llvm + + alias: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), aliasee: ^2) + +The ``module`` and ``flags`` fields are as described for a +:ref:`function summary `. The ``aliasee`` field +contains a reference to the global value summary entry of the aliasee. + +.. _funcflags_summary: + +Function Flags +^^^^^^^^^^^^^^ + +The optional ``FuncFlags`` field looks like: + +.. code-block:: llvm + + funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0) + +If unspecified, flags are assumed to hold the conservative ``false`` value of +``0``. + +.. _calls_summary: + +Calls +^^^^^ + +The optional ``Calls`` field looks like: + +.. code-block:: llvm + + calls: ((Callee)[, (Callee)]*) + +where each ``Callee`` looks like: + +.. code-block:: llvm + + callee: ^1[, hotness: None]?[, relbf: 0]? + +The ``callee`` refers to the summary entry id of the callee. At most one +of ``hotness`` (which can take the values ``Unknown``, ``Cold``, ``None``, +``Hot``, and ``Critical``), and ``relbf`` (which holds the integer +branch frequency relative to the entry frequency, scaled down by 2^8) +may be specified. The defaults are ``Unknown`` and ``0``, respectively. + +.. _refs_summary: + +Refs +^^^^ + +The optional ``Refs`` field looks like: + +.. code-block:: llvm + + refs: ((Ref)[, (Ref)]*) + +where each ``Ref`` contains a reference to the summary id of the referenced +value (e.g. ``^1``). + +.. _typeidinfo_summary: + +TypeIdInfo +^^^^^^^^^^ + +The optional ``TypeIdInfo`` field, used for +`Control Flow Integrity `_, +looks like: + +.. code-block:: llvm + + typeIdInfo: [(TypeTests)]?[, (TypeTestAssumeVCalls)]?[, (TypeCheckedLoadVCalls)]?[, (TypeTestAssumeConstVCalls)]?[, (TypeCheckedLoadConstVCalls)]? + +These optional fields have the following forms: + +TypeTests +""""""""" + +.. code-block:: llvm + + typeTests: (TypeIdRef[, TypeIdRef]*) + +Where each ``TypeIdRef`` refers to a :ref:`type id` +by summary id or ``GUID``. + +TypeTestAssumeVCalls +"""""""""""""""""""" + +.. code-block:: llvm + + typeTestAssumeVCalls: (VFuncId[, VFuncId]*) + +Where each VFuncId has the format: + +.. code-block:: llvm + + vFuncId: (TypeIdRef, offset: 16) + +Where each ``TypeIdRef`` refers to a :ref:`type id` +by summary id or ``GUID`` preceeded by a ``guid:`` tag. + +TypeCheckedLoadVCalls +""""""""""""""""""""" + +.. code-block:: llvm + + typeCheckedLoadVCalls: (VFuncId[, VFuncId]*) + +Where each VFuncId has the format described for ``TypeTestAssumeVCalls``. + +TypeTestAssumeConstVCalls +""""""""""""""""""""""""" + +.. code-block:: llvm + + typeTestAssumeConstVCalls: (ConstVCall[, ConstVCall]*) + +Where each ConstVCall has the format: + +.. code-block:: llvm + + VFuncId, args: (Arg[, Arg]*) + +and where each VFuncId has the format described for ``TypeTestAssumeVCalls``, +and each Arg is an integer argument number. + +TypeCheckedLoadConstVCalls +"""""""""""""""""""""""""" + +.. code-block:: llvm + + typeCheckedLoadConstVCalls: (ConstVCall[, ConstVCall]*) + +Where each ConstVCall has the format described for +``TypeTestAssumeConstVCalls``. + +.. _typeid_summary: + +Type ID Summary Entry +--------------------- + +Each type id summary entry corresponds to a type identifier resolution +which is generated during the LTO link portion of the compile when building +with `Control Flow Integrity `_, +so these are only present in a combined summary index. + +Example: + +.. code-block:: llvm + + ^4 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7[, alignLog2: 0]?[, sizeM1: 0]?[, bitMask: 0]?[, inlineBits: 0]?)[, WpdResolutions]?)) ; guid = 7004155349499253778 + +The ``typeTestRes`` gives the type test resolution ``kind`` (which may +be ``unsat``, ``byteArray``, ``inline``, ``single``, or ``allOnes``), and +the ``size-1`` bit width. It is followed by optional flags, which default to 0, +and an optional WpdResolutions (whole program devirtualization resolution) +field that looks like: + +.. code-block:: llvm + + wpdResolutions: ((offset: 0, WpdRes)[, (offset: 1, WpdRes)]* + +where each entry is a mapping from the given byte offset to the whole-program +devirtualization resolution WpdRes, that has one of the following formats: + +.. code-block:: llvm + + wpdRes: (kind: branchFunnel) + wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi") + wpdRes: (kind: indir) + +Additionally, each wpdRes has an optional ``resByArg`` field, which +describes the resolutions for calls with all constant integer arguments: + +.. code-block:: llvm + + resByArg: (ResByArg[, ResByArg]*) + +where ResByArg is: + +.. code-block:: llvm + + args: (Arg[, Arg]*), byArg: (kind: UniformRetVal[, info: 0][, byte: 0][, bit: 0]) + +Where the ``kind`` can be ``Indir``, ``UniformRetVal``, ``UniqueRetVal`` +or ``VirtualConstProp``. The ``info`` field is only used if the kind +is ``UniformRetVal`` (indicates the uniform return value), or +``UniqueRetVal`` (holds the return value associated with the unique vtable +(0 or 1)). The ``byte`` and ``bit`` fields are only used if the target does +not support the use of absolute symbols to store constants. + .. _intrinsicglobalvariables: Intrinsic Global Variables @@ -6983,7 +7293,7 @@ by the corresponding shift amount in ``op2``. If the ``nuw`` keyword is present, then the shift produces a poison value if it shifts out any non-zero bits. If the ``nsw`` keyword is present, then the shift produces a poison -value it shifts out any bits that disagree with the resultant sign bit. +value if it shifts out any bits that disagree with the resultant sign bit. Example: """""""" @@ -7629,7 +7939,8 @@ referenced by the load contains the same value at all points in the program where the memory location is known to be dereferenceable. The optional ``!invariant.group`` metadata must reference a single metadata name - ```` corresponding to a metadata node. See ``invariant.group`` metadata. + ```` corresponding to a metadata node with no entries. + See ``invariant.group`` metadata. The optional ``!nonnull`` metadata must reference a single metadata name ```` corresponding to a metadata node with no @@ -8371,18 +8682,17 @@ Semantics: The '``fptrunc``' instruction casts a ``value`` from a larger :ref:`floating-point ` type to a smaller :ref:`floating-point -` type. If the value cannot fit (i.e. overflows) within the -destination type, ``ty2``, then the results are undefined. If the cast produces -an inexact result, how rounding is performed (e.g. truncation, also known as -round to zero) is undefined. +` type. +This instruction is assumed to execute in the default :ref:`floating-point +environment `. Example: """""""" .. code-block:: llvm - %X = fptrunc double 123.0 to float ; yields float:123.0 - %Y = fptrunc double 1.0E+300 to float ; yields undefined + %X = fptrunc double 16777217.0 to float ; yields float:16777216.0 + %Y = fptrunc double 1.0E+300 to half ; yields half:+infinity '``fpext .. to``' Instruction ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12901,7 +13211,7 @@ Semantics: This intrinsic indicates that the memory is mutable again. -'``llvm.invariant.group.barrier``' Intrinsic +'``llvm.launder.invariant.group``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Syntax: @@ -12912,20 +13222,21 @@ argument. :: - declare i8* @llvm.invariant.group.barrier.p0i8(i8* ) + declare i8* @llvm.launder.invariant.group.p0i8(i8* ) Overview: """"""""" -The '``llvm.invariant.group.barrier``' intrinsic can be used when an invariant +The '``llvm.launder.invariant.group``' intrinsic can be used when an invariant established by invariant.group metadata no longer holds, to obtain a new pointer -value that does not carry the invariant information. +value that does not carry the invariant information. It is an experimental +intrinsic, which means that its semantics might change in the future. Arguments: """""""""" -The ``llvm.invariant.group.barrier`` takes only one argument, which is +The ``llvm.launder.invariant.group`` takes only one argument, which is the pointer to the memory for which the ``invariant.group`` no longer holds. Semantics: @@ -12933,6 +13244,7 @@ Semantics: Returns another pointer that aliases its argument but which is considered different for the purposes of ``load``/``store`` ``invariant.group`` metadata. +It does not read any accessible memory and the execution can be speculated. .. _constrainedfp: diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst index 0021bf8e00b19d7bda079c07f7aeea31c3117347..981aaea961a4ab12434deb638d9ba0303a2e0c08 100644 --- a/docs/Lexicon.rst +++ b/docs/Lexicon.rst @@ -133,6 +133,12 @@ H I - +**ICE** + Internal Compiler Error. This abbreviation is used to describe errors + that occur in LLVM or Clang as they are compiling source code. For example, + if a valid C++ source program were to trigger an assert in Clang when + compiled, that could be referred to as an "ICE". + **IPA** Inter-Procedural Analysis. Refers to any variety of code analysis that occurs between procedures, functions or compilation units (modules). diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 07048a52319e1f32c9a7ad4342ab51687a1c43ec..9ce64ab58657869be2ab9e653e2d772d0a9e1f4e 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -1020,8 +1020,8 @@ be passed by value. .. _DEBUG: -The ``DEBUG()`` macro and ``-debug`` option -------------------------------------------- +The ``LLVM_DEBUG()`` macro and ``-debug`` option +------------------------------------------------ Often when working on your pass you will put a bunch of debugging printouts and other code into your pass. After you get it working, you want to remove it, but @@ -1033,14 +1033,14 @@ them out, allowing you to enable them if you need them in the future. The ``llvm/Support/Debug.h`` (`doxygen `__) file provides a macro named -``DEBUG()`` that is a much nicer solution to this problem. Basically, you can -put arbitrary code into the argument of the ``DEBUG`` macro, and it is only +``LLVM_DEBUG()`` that is a much nicer solution to this problem. Basically, you can +put arbitrary code into the argument of the ``LLVM_DEBUG`` macro, and it is only executed if '``opt``' (or any other tool) is run with the '``-debug``' command line argument: .. code-block:: c++ - DEBUG(dbgs() << "I am here!\n"); + LLVM_DEBUG(dbgs() << "I am here!\n"); Then you can run your pass like this: @@ -1051,13 +1051,13 @@ Then you can run your pass like this: $ opt < a.bc > /dev/null -mypass -debug I am here! -Using the ``DEBUG()`` macro instead of a home-brewed solution allows you to not +Using the ``LLVM_DEBUG()`` macro instead of a home-brewed solution allows you to not have to create "yet another" command line option for the debug output for your -pass. Note that ``DEBUG()`` macros are disabled for non-asserts builds, so they +pass. Note that ``LLVM_DEBUG()`` macros are disabled for non-asserts builds, so they do not cause a performance impact at all (for the same reason, they should also not contain side-effects!). -One additional nice thing about the ``DEBUG()`` macro is that you can enable or +One additional nice thing about the ``LLVM_DEBUG()`` macro is that you can enable or disable it directly in gdb. Just use "``set DebugFlag=0``" or "``set DebugFlag=1``" from the gdb if the program is running. If the program hasn't been started yet, you can always just run it with ``-debug``. @@ -1076,10 +1076,10 @@ follows: .. code-block:: c++ #define DEBUG_TYPE "foo" - DEBUG(dbgs() << "'foo' debug type\n"); + LLVM_DEBUG(dbgs() << "'foo' debug type\n"); #undef DEBUG_TYPE #define DEBUG_TYPE "bar" - DEBUG(dbgs() << "'bar' debug type\n"); + LLVM_DEBUG(dbgs() << "'bar' debug type\n"); #undef DEBUG_TYPE Then you can run your pass like this: @@ -1832,7 +1832,7 @@ A sorted 'vector' ^^^^^^^^^^^^^^^^^ If you intend to insert a lot of elements, then do a lot of queries, a great -approach is to use a vector (or other sequential container) with +approach is to use an std::vector (or other sequential container) with std::sort+std::unique to remove duplicates. This approach works really well if your usage pattern has these two distinct phases (insert then query), and can be coupled with a good choice of :ref:`sequential container `. @@ -2984,7 +2984,7 @@ Conceptually, ``LLVMContext`` provides isolation. Every LLVM entity in-memory IR belongs to an ``LLVMContext``. Entities in different contexts *cannot* interact with each other: ``Module``\ s in different contexts cannot be linked together, ``Function``\ s cannot be added to ``Module``\ s in different -contexts, etc. What this means is that is is safe to compile on multiple +contexts, etc. What this means is that is safe to compile on multiple threads simultaneously, as long as no two threads operate on entities within the same context. diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 7bd8223af46938fb08c6d64070e8f8b94d828a31..3341d4ba3feb57479ca33a5d5d05463d61aabf34 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -48,11 +48,46 @@ Non-comprehensive list of changes in this release * Symbols starting with ``?`` are no longer mangled by LLVM when using the Windows ``x`` or ``w`` IR mangling schemes. +* A new tool named :doc:`llvm-exegesis ` has been + added. :program:`llvm-exegesis` automatically measures instruction scheduling + properties (latency/uops) and provides a principled way to edit scheduling + models. + * A new tool named :doc:`llvm-mca ` has been added. :program:`llvm-mca` is a static performance analysis tool that uses information available in LLVM to statically predict the performance of machine code for a specific CPU. +* The optimization flag to merge constants (-fmerge-all-constants) is no longer + applied by default. + +* Optimization of floating-point casts is improved. This may cause surprising + results for code that is relying on the undefined behavior of overflowing + casts. The optimization can be disabled by specifying a function attribute: + "strict-float-cast-overflow"="false". This attribute may be created by the + clang option :option:`-fno-strict-float-cast-overflow`. + Code sanitizers can be used to detect affected patterns. The option for + detecting this problem alone is "-fsanitize=float-cast-overflow": + +.. code-block:: c + + int main() { + float x = 4294967296.0f; + x = (float)((int)x); + printf("junk in the ftrunc: %f\n", x); + return 0; + } + +.. code-block:: bash + + clang -O1 ftrunc.c -fsanitize=float-cast-overflow ; ./a.out + ftrunc.c:5:15: runtime error: 4.29497e+09 is outside the range of representable values of type 'int' + junk in the ftrunc: 0.000000 + +* ``LLVM_ON_WIN32`` is no longer set by ``llvm/Config/config.h`` and + ``llvm/Config/llvm-config.h``. If you used this macro, use the compiler-set + ``_WIN32`` instead which is set exactly when ``LLVM_ON_WIN32`` used to be set. + * Note.. .. NOTE @@ -72,6 +107,10 @@ Changes to the LLVM IR have changed. Alignment is no longer an argument, and are instead conveyed as parameter attributes. +* invariant.group.barrier has been renamed to launder.invariant.group. + +* invariant.group metadata can now refer only empty metadata nodes. + Changes to the ARM Backend -------------------------- @@ -107,14 +146,22 @@ Changes to the AVR Target Changes to the OCaml bindings ----------------------------- - During this release ... +* Remove ``add_bb_vectorize``. Changes to the C API -------------------- - During this release ... +* Remove ``LLVMAddBBVectorizePass``. The implementation was removed and the C + interface was made a deprecated no-op in LLVM 5. Use + ``LLVMAddSLPVectorizePass`` instead to get the supported SLP vectorizer. +Changes to the DAG infrastructure +--------------------------------- +* ADDC/ADDE/SUBC/SUBE are now deprecated and will default to expand. Backends + that wish to continue to use these opcodes should explicitely request so + using ``setOperationAction`` in their ``TargetLowering``. New backends + should use UADDO/ADDCARRY/USUBO/SUBCARRY instead of the deprecated opcodes. External Open Source Projects Using LLVM 7 ========================================== diff --git a/docs/ScudoHardenedAllocator.rst b/docs/ScudoHardenedAllocator.rst index c493f0eadacbb6fd59cc51aa42ae31245f5624ed..fcd5cefdac6d10ff0ea5ad373358c11aa71fb7c7 100644 --- a/docs/ScudoHardenedAllocator.rst +++ b/docs/ScudoHardenedAllocator.rst @@ -18,7 +18,8 @@ Currently, the allocator supports (was tested on) the following architectures: - i386 (& i686) (32-bit); - x86_64 (64-bit); - armhf (32-bit); -- AArch64 (64-bit). +- AArch64 (64-bit); +- MIPS (32-bit & 64-bit). The name "Scudo" has been retained from the initial implementation (Escudo meaning Shield in Spanish and Portuguese). @@ -87,7 +88,7 @@ Randomness ---------- It is important for the allocator to not make use of fixed addresses. We use the dynamic base option for the SizeClassAllocator, allowing us to benefit -from the randomness of mmap. +from the randomness of the system memory mapping functions. Usage ===== @@ -111,14 +112,14 @@ You may also build Scudo like this: cd $LLVM/projects/compiler-rt/lib clang++ -fPIC -std=c++11 -msse4.2 -O2 -I. scudo/*.cpp \ - $(\ls sanitizer_common/*.{cc,S} | grep -v "sanitizer_termination\|sanitizer_common_nolibc") \ - -shared -o scudo-allocator.so -pthread + $(\ls sanitizer_common/*.{cc,S} | grep -v "sanitizer_termination\|sanitizer_common_nolibc\|sancov_\|sanitizer_unwind\|sanitizer_symbol") \ + -shared -o libscudo.so -pthread and then use it with existing binaries as follows: .. code:: - LD_PRELOAD=`pwd`/scudo-allocator.so ./a.out + LD_PRELOAD=`pwd`/libscudo.so ./a.out Clang ----- @@ -130,15 +131,20 @@ Scudo will also enforce PIE for the output binary. Options ------- -Several aspects of the allocator can be configured through the following ways: +Several aspects of the allocator can be configured on a per process basis +through the following ways: + +- at compile time, by defining ``SCUDO_DEFAULT_OPTIONS`` to the options string + you want set by default; - by defining a ``__scudo_default_options`` function in one's program that returns the options string to be parsed. Said function must have the following - prototype: ``extern "C" const char* __scudo_default_options(void)``. + prototype: ``extern "C" const char* __scudo_default_options(void)``, with a + default visibility. This will override the compile time define; - through the environment variable SCUDO_OPTIONS, containing the options string to be parsed. Options defined this way will override any definition made - through ``__scudo_default_options``; + through ``__scudo_default_options``. The options string follows a syntax similar to ASan, where distinct options can be assigned in the same string, separated by colons. @@ -167,7 +173,9 @@ The following options are available: | | | | the actual deallocation of chunks. Lower value | | | | | may reduce memory usage but decrease the | | | | | effectiveness of the mitigation; a negative | -| | | | value will fallback to the defaults. | +| | | | value will fallback to the defaults. Setting | +| | | | *both* this and ThreadLocalQuarantineSizeKb to | +| | | | zero will disable the quarantine entirely. | +-----------------------------+----------------+----------------+------------------------------------------------+ | QuarantineChunksUpToSize | 2048 | 512 | Size (in bytes) up to which chunks can be | | | | | quarantined. | @@ -175,7 +183,9 @@ The following options are available: | ThreadLocalQuarantineSizeKb | 1024 | 256 | The size (in Kb) of per-thread cache use to | | | | | offload the global quarantine. Lower value may | | | | | reduce memory usage but might increase | -| | | | contention on the global quarantine. | +| | | | contention on the global quarantine. Setting | +| | | | *both* this and QuarantineSizeKb to zero will | +| | | | disable the quarantine entirely. | +-----------------------------+----------------+----------------+------------------------------------------------+ | DeallocationTypeMismatch | true | true | Whether or not we report errors on | | | | | malloc/delete, new/free, new/delete[], etc. | @@ -188,7 +198,6 @@ The following options are available: +-----------------------------+----------------+----------------+------------------------------------------------+ Allocator related common Sanitizer options can also be passed through Scudo -options, such as ``allocator_may_return_null``. A detailed list including those -can be found here: +options, such as ``allocator_may_return_null`` or ``abort_on_error``. A detailed +list including those can be found here: https://github.com/google/sanitizers/wiki/SanitizerCommonFlags. - diff --git a/docs/SystemLibrary.rst b/docs/SystemLibrary.rst index 0d0f4fa994822d99c0cde1bf49f6512e32c7b8ef..dba446b476da1387494535110e767369f141efca 100644 --- a/docs/SystemLibrary.rst +++ b/docs/SystemLibrary.rst @@ -209,10 +209,9 @@ Implementations of the System Library interface are separated by their general class of operating system. Currently only Unix and Win32 classes are defined but more could be added for other operating system classifications. To distinguish which implementation to compile, the code in ``lib/System`` uses -the ``LLVM_ON_UNIX`` and ``LLVM_ON_WIN32`` ``#defines`` provided via configure -through the ``llvm/Config/config.h`` file. Each source file in ``lib/System``, -after implementing the generic (operating system independent) functionality -needs to include the correct implementation using a set of +the ``LLVM_ON_UNIX`` and ``_WIN32`` ``#defines``. Each source file in +``lib/System``, after implementing the generic (operating system independent) +functionality needs to include the correct implementation using a set of ``#if defined(LLVM_ON_XYZ)`` directives. For example, if we had ``lib/System/File.cpp``, we'd expect to see in that file: @@ -221,7 +220,7 @@ needs to include the correct implementation using a set of #if defined(LLVM_ON_UNIX) #include "Unix/File.cpp" #endif - #if defined(LLVM_ON_WIN32) + #if defined(_WIN32) #include "Win32/File.cpp" #endif diff --git a/docs/TableGen/LangRef.rst b/docs/TableGen/LangRef.rst index 534cac25d02e637d537b8d07e901aa3c631facc2..9e492410b1623436f69d83dfe75ad632c2410d79 100644 --- a/docs/TableGen/LangRef.rst +++ b/docs/TableGen/LangRef.rst @@ -294,7 +294,7 @@ given values. leave it out. .. productionlist:: - SimpleValue: "(" `DagArg` `DagArgList` ")" + SimpleValue: "(" `DagArg` [`DagArgList`] ")" DagArgList: `DagArg` ("," `DagArg`)* DagArg: `Value` [":" `TokVarName`] | `TokVarName` @@ -325,7 +325,7 @@ It is after parsing the base class list that the "let stack" is applied. Body: ";" | "{" BodyList "}" BodyList: BodyItem* BodyItem: `Declaration` ";" - :| "let" `TokIdentifier` [`RangeList`] "=" `Value` ";" + :| "let" `TokIdentifier` [ "{" `RangeList` "}" ] "=" `Value` ";" The ``let`` form allows overriding the value of an inherited field. @@ -353,7 +353,7 @@ a ``foreach``. -------- .. productionlist:: - Defm: "defm" `TokIdentifier` ":" `BaseClassListNE` ";" + Defm: "defm" [`TokIdentifier`] ":" `BaseClassListNE` ";" Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must precede any ``class``'s that appear. diff --git a/docs/TableGen/index.rst b/docs/TableGen/index.rst index 5ba555ac2d2344b87fd65d07901ac77484e70ab6..e6800fac64e93663a5ba87c4bc738afdbbc8cd6c 100644 --- a/docs/TableGen/index.rst +++ b/docs/TableGen/index.rst @@ -224,7 +224,7 @@ definitions of a particular class, such as "Instruction". class ProcNoItin Features> : Processor; - + Here, the class ProcNoItin, receiving parameters `Name` of type `string` and a list of target features is specializing the class Processor by passing the arguments down as well as hard-coding NoItineraries. diff --git a/docs/XRay.rst b/docs/XRay.rst index 314d7787e9108252f216581036739de33f355099..9d77aab67d685dabb7752bef78cfb9a4d5ea989c 100644 --- a/docs/XRay.rst +++ b/docs/XRay.rst @@ -117,6 +117,27 @@ it gets instrumented. ; ... } +Special Case File +----------------- + +Attributes can be imbued through the use of special case files instead of +adding them to the original source files. You can use this to mark certain +functions and classes to be never, always, or instrumented with first-argument +logging from a file. The file's format is described below: + +.. code-block:: bash + + # Comments are supported + [always] + fun:always_instrument + fun:log_arg1=arg1 # Log the first argument for the function + + [never] + fun:never_instrument + +These files can be provided through the ``-fxray-attr-list=`` flag to clang. +You may have multiple files loaded through multiple instances of the flag. + XRay Runtime Library -------------------- @@ -150,20 +171,6 @@ variable, where we list down the options and their defaults below. | xray_logfile_base | ``const char*`` | ``xray-log.`` | Filename base for the | | | | | XRay logfile. | +-------------------+-----------------+---------------+------------------------+ -| xray_naive_log | ``bool`` | ``false`` | **DEPRECATED:** Use | -| | | | xray_mode=xray-basic | -| | | | instead. Whether to | -| | | | install the basic log | -| | | | the naive log | -| | | | implementation. | -+-------------------+-----------------+---------------+------------------------+ -| xray_fdr_log | ``bool`` | ``false`` | **DEPRECATED:** Use | -| | | | xray_mode=xray-fdr | -| | | | instead. Whether to | -| | | | install the Flight | -| | | | Data Recorder | -| | | | (FDR) mode. | -+-------------------+-----------------+---------------+------------------------+ | verbosity | ``int`` | ``0`` | Runtime verbosity | | | | | level. | +-------------------+-----------------+---------------+------------------------+ @@ -172,30 +179,45 @@ variable, where we list down the options and their defaults below. If you choose to not use the default logging implementation that comes with the XRay runtime and/or control when/how the XRay instrumentation runs, you may use the XRay APIs directly for doing so. To do this, you'll need to include the -``xray_interface.h`` from the compiler-rt ``xray`` directory. The important API +``xray_log_interface.h`` from the compiler-rt ``xray`` directory. The important API functions we list below: -- ``__xray_set_handler(void (*entry)(int32_t, XRayEntryType))``: Install your - own logging handler for when an event is encountered. See - ``xray/xray_interface.h`` for more details. -- ``__xray_remove_handler()``: Removes whatever the installed handler is. -- ``__xray_patch()``: Patch all the instrumentation points defined in the - binary. -- ``__xray_unpatch()``: Unpatch the instrumentation points defined in the - binary. - -There are some requirements on the logging handler to be installed for the -thread-safety of operations to be performed by the XRay runtime library: - -- The function should be thread-safe, as multiple threads may be invoking the - function at the same time. If the logging function needs to do - synchronisation, it must do so internally as XRay does not provide any - synchronisation guarantees outside from the atomicity of updates to the - pointer. -- The pointer provided to ``__xray_set_handler(...)`` must be live even after - calls to ``__xray_remove_handler()`` and ``__xray_unpatch()`` have succeeded. - XRay cannot guarantee that all threads that have ever gotten a copy of the - pointer will not invoke the function. +- ``__xray_log_register_mode(...)``: Register a logging implementation against + a string Mode identifier. The implementation is an instance of + ``XRayLogImpl`` defined in ``xray/xray_log_interface.h``. +- ``__xray_log_select_mode(...)``: Select the mode to install, associated with + a string Mode identifier. Only implementations registered with + ``__xray_log_register_mode(...)`` can be chosen with this function. +- ``__xray_log_init_mode(...)``: This function allows for initializing and + re-initializing an installed logging implementation. See + ``xray/xray_log_interface.h`` for details, part of the XRay compiler-rt + installation. + +Once a logging implementation has been initialized, it can be "stopped" by +finalizing the implementation through the ``__xray_log_finalize()`` function. +The finalization routine is the opposite of the initialization. When finalized, +an implementation's data can be cleared out through the +``__xray_log_flushLog()`` function. For implementations that support in-memory +processing, these should register an iterator function to provide access to the +data via the ``__xray_log_set_buffer_iterator(...)`` which allows code calling +the ``__xray_log_process_buffers(...)`` function to deal with the data in +memory. + +All of this is better explained in the ``xray/xray_log_interface.h`` header. + +Basic Mode +---------- + +XRay supports a basic logging mode which will trace the application's +execution, and periodically append to a single log. This mode can be +installed/enabled by setting ``xray_mode=xray-basic`` in the ``XRAY_OPTIONS`` +environment variable. Combined with ``patch_premain=true`` this can allow for +tracing applications from start to end. + +Like all the other modes installed through ``__xray_log_select_mode(...)``, the +implementation can be configured through the ``__xray_log_init_mode(...)`` +function, providing the mode string and the flag options. Basic-mode specific +defaults can be provided in the ``XRAY_BASIC_OPTIONS`` environment variable. Flight Data Recorder Mode ------------------------- @@ -205,9 +227,12 @@ fixed amount of memory's worth of events. Flight Data Recorder (FDR) mode works very much like a plane's "black box" which keeps recording data to memory in a fixed-size circular queue of buffers, and have the data available programmatically until the buffers are finalized and flushed. To use FDR mode -on your application, you may set the ``xray_fdr_log`` option to ``true`` in the -``XRAY_OPTIONS`` environment variable (while also optionally setting the -``xray_naive_log`` to ``false``). +on your application, you may set the ``xray_mode`` variable to ``xray-fdr`` in +the ``XRAY_OPTIONS`` environment variable. Additional options to the FDR mode +implementation can be provided in the ``XRAY_FDR_OPTIONS`` environment +variable. Programmatic configuration can be done by calling +``__xray_log_init_mode("xray-fdr", )`` once it has been +selected/installed. When the buffers are flushed to disk, the result is a binary trace format described by `XRay FDR format `_ @@ -239,34 +264,15 @@ provided below: } The default settings for the FDR mode implementation will create logs named -similarly to the naive log implementation, but will have a different log +similarly to the basic log implementation, but will have a different log format. All the trace analysis tools (and the trace reading library) will support all versions of the FDR mode format as we add more functionality and record types in the future. - **NOTE:** We do not however promise perpetual support for when we update the - log versions we support going forward. Deprecation of the formats will be + **NOTE:** We do not promise perpetual support for when we update the log + versions we support going forward. Deprecation of the formats will be announced and discussed on the developers mailing list. -XRay allows for replacing the default FDR mode logging implementation using the -following API: - -- ``__xray_set_log_impl(...)``: This function takes a struct of type - ``XRayLogImpl``, which is defined in ``xray/xray_log_interface.h``, part of - the XRay compiler-rt installation. -- ``__xray_log_register_mode(...)``: Register a logging implementation against - a string Mode. The implementation is an instance of ``XRayLogImpl`` defined - in ``xray/xray_log_interface.h``. -- ``__xray_log_select_mode(...)``: Select the mode to install, associated with - a string Mode. Only implementations registered with - ``__xray_log_register_mode(...)`` can be chosen with this function. When - successful, has the same effects as calling ``__xray_set_log_impl(...)`` with - the registered logging implementation. -- ``__xray_log_init(...)``: This function allows for initializing and - re-initializing an installed logging implementation. See - ``xray/xray_log_interface.h`` for details, part of the XRay compiler-rt - installation. - Trace Analysis Tools -------------------- @@ -280,7 +286,7 @@ supports the following subcommands: options for sorting, and output formats (supports CSV, YAML, and console-friendly TEXT). - ``convert``: Converts an XRay log file from one format to another. We can - convert from binary XRay traces (both naive and FDR mode) to YAML, + convert from binary XRay traces (both basic and FDR mode) to YAML, `flame-graph `_ friendly text formats, as well as `Chrome Trace Viewer (catapult) ` formats. diff --git a/docs/XRayExample.rst b/docs/XRayExample.rst index f8e7d943fedd5b8ec57784bed337880345148e05..e1b8c9b69d5fe12c67406a79f26274662419d9f8 100644 --- a/docs/XRayExample.rst +++ b/docs/XRayExample.rst @@ -48,11 +48,11 @@ Getting Traces -------------- By default, XRay does not write out the trace files or patch the application -before main starts. If we just run ``llc`` it should just work like a normally -built binary. However, if we want to get a full trace of the application's -operations (of the functions we do end up instrumenting with XRay) then we need -to enable XRay at application start. To do this, XRay checks the -``XRAY_OPTIONS`` environment variable. +before main starts. If we run ``llc`` it should work like a normally built +binary. If we want to get a full trace of the application's operations (of the +functions we do end up instrumenting with XRay) then we need to enable XRay +at application start. To do this, XRay checks the ``XRAY_OPTIONS`` environment +variable. :: @@ -73,9 +73,8 @@ instrumented, and how much time we're spending in parts of the code. To make sense of this data, we use the ``llvm-xray`` tool which has a few subcommands to help us understand our trace. -One of the simplest things we can do is to get an accounting of the functions -that have been instrumented. We can see an example accounting with ``llvm-xray -account``: +One of the things we can do is to get an accounting of the functions that have +been instrumented. We can see an example accounting with ``llvm-xray account``: :: @@ -178,22 +177,22 @@ add the attribute to the source. To use this feature, you can define one file for the functions to always instrument, and another for functions to never instrument. The format of these files are exactly the same as the SanitizerLists files that control similar -things for the sanitizer implementations. For example, we can have two -different files like below: +things for the sanitizer implementations. For example: :: - # always-instrument.txt + # xray-attr-list.txt # always instrument functions that match the following filters: + [always] fun:main - # never-instrument.txt # never instrument functions that match the following filters: + [never] fun:__cxx_* -Given the above two files we can re-build by providing those two files as -arguments to clang as ``-fxray-always-instrument=always-instrument.txt`` or -``-fxray-never-instrument=never-instrument.txt``. +Given the file above we can re-build by providing it to the +``-fxray-attr-list=`` flag to clang. You can have multiple files, each defining +different sets of attribute sets, to be combined into a single list by clang. The XRay stack tool ------------------- @@ -202,8 +201,7 @@ Given a trace, and optionally an instrumentation map, the ``llvm-xray stack`` command can be used to analyze a call stack graph constructed from the function call timeline. -The simplest way to use the command is simply to output the top stacks by call -count and time spent. +The way to use the command is to output the top stacks by call count and time spent. :: @@ -245,7 +243,7 @@ FlameGraph tool, currently available on `github To generate output for a flamegraph, a few more options are necessary. -- ``-all-stacks`` - Emits all of the stacks instead of just the top stacks. +- ``-all-stacks`` - Emits all of the stacks. - ``-stack-format`` - Choose the flamegraph output format 'flame'. - ``-aggregation-type`` - Choose the metric to graph. diff --git a/docs/XRayFDRFormat.rst b/docs/XRayFDRFormat.rst index f7942bc212df40d892224f894f8b2d3d85adefd5..46f72c54228b6a02b385013de4b54e5b59421510 100644 --- a/docs/XRayFDRFormat.rst +++ b/docs/XRayFDRFormat.rst @@ -15,7 +15,7 @@ When gathering XRay traces in Flight Data Recorder mode, each thread of an application will claim buffers to fill with trace data, which at some point is finalized and flushed. -A goal of the profiler is to minimize overhead, so the flushed data directly +A goal of the profiler is to minimize overhead, the flushed data directly corresponds to the buffer. This document describes the format of a trace file. @@ -106,11 +106,11 @@ There are a few categories of data in the sequence. - ``Function Arguments``: The arguments to some functions are included in the trace. These are either pointer addresses or primitives that are read and logged independently of their types in a high level language. To the tracer, - they are all simply numbers. Function Records that have attached arguments - will indicate their presence on the function entry record. We only support - logging contiguous function argument sequences starting with argument zero, - which will be the "this" pointer for member function invocations. For example, - we don't support logging the first and third argument. + they are all numbers. Function Records that have attached arguments will + indicate their presence on the function entry record. We only support logging + contiguous function argument sequences starting with argument zero, which will + be the "this" pointer for member function invocations. For example, we don't + support logging the first and third argument. A reader of the memory format must maintain a state machine. The format makes no attempt to pad for alignment, and it is not seekable. diff --git a/docs/tutorial/BuildingAJIT2.rst b/docs/tutorial/BuildingAJIT2.rst index 95d0c1a6dd57d7633ad2f4026e017e7a6c853803..15c9c3586bc37c8f0c0e8e659b0add5b10b9816a 100644 --- a/docs/tutorial/BuildingAJIT2.rst +++ b/docs/tutorial/BuildingAJIT2.rst @@ -224,7 +224,7 @@ layer interface. The interface consists of one typedef and five methods: | | emitAndFinalize. | +------------------+-----------------------------------------------------------+ | | Takes a given set of Modules and makes them "available | -| | for execution. This means that symbols in those modules | +| | for execution". This means that symbols in those modules | | | should be searchable via findSymbol and findSymbolIn, and | | | the address of the symbols should be read/writable (for | | | data symbols), or executable (for function symbols) after | diff --git a/docs/tutorial/LangImpl04.rst b/docs/tutorial/LangImpl04.rst index 15644818389a8ea499fea26d2ce94e53f13bfab8..8927a912cc20e4d069990a21749bc2d90869d455 100644 --- a/docs/tutorial/LangImpl04.rst +++ b/docs/tutorial/LangImpl04.rst @@ -597,7 +597,7 @@ if we add: .. code-block:: c++ - #ifdef LLVM_ON_WIN32 + #ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h index a7eb1db86258581eccea323b45320d8beb89f7de..0b8bb381d08a76c5167de8a2cb174a56ad32f670 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h @@ -38,7 +38,6 @@ namespace orc { class KaleidoscopeJIT { private: - SymbolStringPool SSP; ExecutionSession ES; std::shared_ptr Resolver; std::unique_ptr TM; @@ -48,8 +47,8 @@ private: public: KaleidoscopeJIT() - : ES(SSP), - Resolver(createLegacyLookupResolver( + : Resolver(createLegacyLookupResolver( + ES, [this](const std::string &Name) -> JITSymbol { if (auto Sym = CompileLayer.findSymbol(Name, false)) return Sym; diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h index 679d72e205025179523bb0750984f9adfe4a5a99..9ea84d1a8581bc744069bae9b0308b562afb676e 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h @@ -17,19 +17,20 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Mangler.h" #include "llvm/Support/DynamicLibrary.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include @@ -42,7 +43,6 @@ namespace orc { class KaleidoscopeJIT { private: - SymbolStringPool SSP; ExecutionSession ES; std::shared_ptr Resolver; std::unique_ptr TM; @@ -57,8 +57,8 @@ private: public: KaleidoscopeJIT() - : ES(SSP), - Resolver(createLegacyLookupResolver( + : Resolver(createLegacyLookupResolver( + ES, [this](const std::string &Name) -> JITSymbol { if (auto Sym = OptimizeLayer.findSymbol(Name, false)) return Sym; diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h index cca822930185ce42c1a665f95d21fe7861683d3d..0db97866ceffc7554d5bd9ea93882c56314c8ecb 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h @@ -32,6 +32,7 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include @@ -46,7 +47,6 @@ namespace orc { class KaleidoscopeJIT { private: - SymbolStringPool SSP; ExecutionSession ES; std::map> Resolvers; std::unique_ptr TM; @@ -64,7 +64,7 @@ private: public: KaleidoscopeJIT() - : ES(SSP), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), + : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), ObjectLayer(ES, [this](VModuleKey K) { return RTDyldObjectLinkingLayer::Resources{ @@ -76,8 +76,8 @@ public: [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }), - CompileCallbackManager( - orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)), + CompileCallbackManager(orc::createLocalCompileCallbackManager( + TM->getTargetTriple(), ES, 0)), CODLayer(ES, OptimizeLayer, [&](orc::VModuleKey K) { return Resolvers[K]; }, [&](orc::VModuleKey K, std::shared_ptr R) { @@ -98,6 +98,7 @@ public: // Build a resolver and associate it with the new key. Resolvers[K] = createLegacyLookupResolver( + ES, [this](const std::string &Name) -> JITSymbol { if (auto Sym = CompileLayer.findSymbol(Name, false)) return Sym; diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h index 6378dd61e2954ea950a4b8efb7ebb8f5ef05a90f..ddd469b9ae26aedefb9a32afe1073d9e4f713f65 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h @@ -32,6 +32,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include @@ -72,7 +73,6 @@ namespace orc { class KaleidoscopeJIT { private: - SymbolStringPool SSP; ExecutionSession ES; std::shared_ptr Resolver; std::unique_ptr TM; @@ -90,8 +90,8 @@ private: public: KaleidoscopeJIT() - : ES(SSP), - Resolver(createLegacyLookupResolver( + : Resolver(createLegacyLookupResolver( + ES, [this](const std::string &Name) -> JITSymbol { if (auto Sym = IndirectStubsMgr->findStub(Name, false)) return Sym; @@ -116,8 +116,8 @@ public: [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }), - CompileCallbackMgr( - orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)) { + CompileCallbackMgr(orc::createLocalCompileCallbackManager( + TM->getTargetTriple(), ES, 0)) { auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(TM->getTargetTriple()); IndirectStubsMgr = IndirectStubsMgrBuilder(); @@ -134,22 +134,6 @@ public: } Error addFunctionAST(std::unique_ptr FnAST) { - // Create a CompileCallback - this is the re-entry point into the compiler - // for functions that haven't been compiled yet. - auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback()); - - // Create an indirect stub. This serves as the functions "canonical - // definition" - an unchanging (constant address) entry point to the - // function implementation. - // Initially we point the stub's function-pointer at the compile callback - // that we just created. In the compile action for the callback (see below) - // we will update the stub's function pointer to point at the function - // implementation that we just implemented. - if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()), - CCInfo.getAddress(), - JITSymbolFlags::Exported)) - return Err; - // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support // capture-by-move, which is be required for unique_ptr. auto SharedFnAST = std::shared_ptr(std::move(FnAST)); @@ -170,23 +154,37 @@ public: // The JIT runtime (the resolver block) will use the return address of // this function as the address to continue at once it has reset the // CPU state to what it was immediately before the call. - CCInfo.setCompileAction( - [this, SharedFnAST]() { - auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl"); - addModule(std::move(M)); - auto Sym = findSymbol(SharedFnAST->getName() + "$impl"); - assert(Sym && "Couldn't find compiled function?"); - JITTargetAddress SymAddr = cantFail(Sym.getAddress()); - if (auto Err = - IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()), - SymAddr)) { - logAllUnhandledErrors(std::move(Err), errs(), - "Error updating function pointer: "); - exit(1); - } - - return SymAddr; - }); + auto CompileAction = [this, SharedFnAST]() { + auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl"); + addModule(std::move(M)); + auto Sym = findSymbol(SharedFnAST->getName() + "$impl"); + assert(Sym && "Couldn't find compiled function?"); + JITTargetAddress SymAddr = cantFail(Sym.getAddress()); + if (auto Err = IndirectStubsMgr->updatePointer( + mangle(SharedFnAST->getName()), SymAddr)) { + logAllUnhandledErrors(std::move(Err), errs(), + "Error updating function pointer: "); + exit(1); + } + + return SymAddr; + }; + + // Create a CompileCallback using the CompileAction - this is the re-entry + // point into the compiler for functions that haven't been compiled yet. + auto CCAddr = cantFail( + CompileCallbackMgr->getCompileCallback(std::move(CompileAction))); + + // Create an indirect stub. This serves as the functions "canonical + // definition" - an unchanging (constant address) entry point to the + // function implementation. + // Initially we point the stub's function-pointer at the compile callback + // that we just created. When the compile action for the callback is run we + // will update the stub's function pointer to point at the function + // implementation that we just implemented. + if (auto Err = IndirectStubsMgr->createStub( + mangle(SharedFnAST->getName()), CCAddr, JITSymbolFlags::Exported)) + return Err; return Error::success(); } diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h index acb4090b5eb46083ce3eae1420e79c8264d2cd13..010f54363778b201d6e56b35732801fa6e29d0fd 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h @@ -34,6 +34,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include @@ -77,8 +78,7 @@ using MyRemote = remote::OrcRemoteTargetClient; class KaleidoscopeJIT { private: - SymbolStringPool SSP; - ExecutionSession ES; + ExecutionSession &ES; std::shared_ptr Resolver; std::unique_ptr TM; const DataLayout DL; @@ -95,9 +95,10 @@ private: MyRemote &Remote; public: - KaleidoscopeJIT(MyRemote &Remote) - : ES(SSP), + KaleidoscopeJIT(ExecutionSession &ES, MyRemote &Remote) + : ES(ES), Resolver(createLegacyLookupResolver( + ES, [this](const std::string &Name) -> JITSymbol { if (auto Sym = IndirectStubsMgr->findStub(Name, false)) return Sym; @@ -146,22 +147,6 @@ public: } Error addFunctionAST(std::unique_ptr FnAST) { - // Create a CompileCallback - this is the re-entry point into the compiler - // for functions that haven't been compiled yet. - auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback()); - - // Create an indirect stub. This serves as the functions "canonical - // definition" - an unchanging (constant address) entry point to the - // function implementation. - // Initially we point the stub's function-pointer at the compile callback - // that we just created. In the compile action for the callback (see below) - // we will update the stub's function pointer to point at the function - // implementation that we just implemented. - if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()), - CCInfo.getAddress(), - JITSymbolFlags::Exported)) - return Err; - // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support // capture-by-move, which is be required for unique_ptr. auto SharedFnAST = std::shared_ptr(std::move(FnAST)); @@ -182,23 +167,37 @@ public: // The JIT runtime (the resolver block) will use the return address of // this function as the address to continue at once it has reset the // CPU state to what it was immediately before the call. - CCInfo.setCompileAction( - [this, SharedFnAST]() { - auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl"); - addModule(std::move(M)); - auto Sym = findSymbol(SharedFnAST->getName() + "$impl"); - assert(Sym && "Couldn't find compiled function?"); - JITTargetAddress SymAddr = cantFail(Sym.getAddress()); - if (auto Err = - IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()), - SymAddr)) { - logAllUnhandledErrors(std::move(Err), errs(), - "Error updating function pointer: "); - exit(1); - } - - return SymAddr; - }); + auto CompileAction = [this, SharedFnAST]() { + auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl"); + addModule(std::move(M)); + auto Sym = findSymbol(SharedFnAST->getName() + "$impl"); + assert(Sym && "Couldn't find compiled function?"); + JITTargetAddress SymAddr = cantFail(Sym.getAddress()); + if (auto Err = IndirectStubsMgr->updatePointer( + mangle(SharedFnAST->getName()), SymAddr)) { + logAllUnhandledErrors(std::move(Err), errs(), + "Error updating function pointer: "); + exit(1); + } + + return SymAddr; + }; + + // Create a CompileCallback suing the CompileAction - this is the re-entry + // point into the compiler for functions that haven't been compiled yet. + auto CCAddr = cantFail( + CompileCallbackMgr->getCompileCallback(std::move(CompileAction))); + + // Create an indirect stub. This serves as the functions "canonical + // definition" - an unchanging (constant address) entry point to the + // function implementation. + // Initially we point the stub's function-pointer at the compile callback + // that we just created. In the compile action for the callback we will + // update the stub's function pointer to point at the function + // implementation that we just implemented. + if (auto Err = IndirectStubsMgr->createStub( + mangle(SharedFnAST->getName()), CCAddr, JITSymbolFlags::Exported)) + return Err; return Error::success(); } diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp index 10b60bd12d1cb33781403bdde306974308c536e3..415cc7512779f7598fab108eda9e9ac1de9cc47a 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp @@ -1243,7 +1243,9 @@ std::unique_ptr connect() { sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = PF_INET; - memcpy(&servAddr.sin_addr.s_addr, server->h_addr, server->h_length); + char *src; + memcpy(&src, &server->h_addr, sizeof(char *)); + memcpy(&servAddr.sin_addr.s_addr, src, server->h_length); servAddr.sin_port = htons(Port); if (connect(sockfd, reinterpret_cast(&servAddr), sizeof(servAddr)) < 0) { @@ -1276,9 +1278,10 @@ int main(int argc, char *argv[]) { BinopPrecedence['-'] = 20; BinopPrecedence['*'] = 40; // highest. + ExecutionSession ES; auto TCPChannel = connect(); - auto Remote = ExitOnErr(MyRemote::Create(*TCPChannel, ExitOnErr)); - TheJIT = llvm::make_unique(*Remote); + auto Remote = ExitOnErr(MyRemote::Create(*TCPChannel, ES)); + TheJIT = llvm::make_unique(ES, *Remote); // Automatically inject a definition for 'printExprResult'. FunctionProtos["printExprResult"] = diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp index 921fa8908040f96fb6980a70701f155baadef2fd..f8000c41a6fc1241385bfdd9551f6faa8a570537 100644 --- a/examples/Kaleidoscope/Chapter4/toy.cpp +++ b/examples/Kaleidoscope/Chapter4/toy.cpp @@ -1,3 +1,4 @@ +#include "../include/KaleidoscopeJIT.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/BasicBlock.h" @@ -12,9 +13,9 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" -#include "../include/KaleidoscopeJIT.h" #include #include #include @@ -650,7 +651,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp index 2d23bdb26c21e7441d99cc2f6c089cec68641670..534c8e529e4ebc36a284130739492021a6d43281 100644 --- a/examples/Kaleidoscope/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/Chapter5/toy.cpp @@ -1,11 +1,12 @@ +#include "../include/KaleidoscopeJIT.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Instructions.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -13,9 +14,9 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" -#include "../include/KaleidoscopeJIT.h" #include #include #include @@ -924,7 +925,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp index b5e4495539fc1be91958eb1825a8028dd3a8f71f..4b58117bd4a6ecb55a1f805e38c6e09e624119e1 100644 --- a/examples/Kaleidoscope/Chapter6/toy.cpp +++ b/examples/Kaleidoscope/Chapter6/toy.cpp @@ -1,11 +1,12 @@ +#include "../include/KaleidoscopeJIT.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Instructions.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -13,9 +14,9 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" -#include "../include/KaleidoscopeJIT.h" #include #include #include @@ -1043,7 +1044,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp index 7d45552bed8f32848359eb49e26408735fcd08eb..41c27d06d477050bbd97a77345f09d63fbc5d4bb 100644 --- a/examples/Kaleidoscope/Chapter7/toy.cpp +++ b/examples/Kaleidoscope/Chapter7/toy.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Utils.h" @@ -1213,7 +1214,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp index 3ed98fcfdb5cd31b829315ebefad76bf1fc652ef..9f17d51993a2ce31693f347cf225f46ef9495822 100644 --- a/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/examples/Kaleidoscope/Chapter8/toy.cpp @@ -1173,7 +1173,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT @@ -1255,7 +1255,7 @@ int main() { legacy::PassManager pass; auto FileType = TargetMachine::CGFT_ObjectFile; - if (TheTargetMachine->addPassesToEmitFile(pass, dest, FileType)) { + if (TheTargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) { errs() << "TheTargetMachine can't emit a file of this type"; return 1; } diff --git a/examples/Kaleidoscope/Chapter9/toy.cpp b/examples/Kaleidoscope/Chapter9/toy.cpp index 821cf4d25a65d18afad95814aba910bacdc9e69e..7a12b5a80cc848ca970b827fede7223875b8226c 100644 --- a/examples/Kaleidoscope/Chapter9/toy.cpp +++ b/examples/Kaleidoscope/Chapter9/toy.cpp @@ -1379,7 +1379,7 @@ static void MainLoop() { // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT diff --git a/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp b/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp index 3caeab4c745a368d422051dcc359aa0bc38f6b59..a271c2047e33fe6870f7b559232ae6b96e12c0ae 100644 --- a/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp +++ b/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp @@ -33,14 +33,14 @@ enum Token { // primary tok_identifier = -4, tok_number = -5, - + // control tok_if = -6, tok_then = -7, tok_else = -8, tok_for = -9, tok_in = -10, - + // operators tok_binary = -11, tok_unary = -12, - + // var definition tok_var = -13 }; diff --git a/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/examples/Kaleidoscope/include/KaleidoscopeJIT.h index 3e2fe42a5d8900979f7d9a9a23ae69b07d454e7c..7239aea7ba1bcf6e2424ba267a65abd85998bc72 100644 --- a/examples/Kaleidoscope/include/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/include/KaleidoscopeJIT.h @@ -44,8 +44,8 @@ public: using CompileLayerT = IRCompileLayer; KaleidoscopeJIT() - : ES(SSP), - Resolver(createLegacyLookupResolver( + : Resolver(createLegacyLookupResolver( + ES, [this](const std::string &Name) { return ObjectLayer.findSymbol(Name, true); }, @@ -89,7 +89,7 @@ private: } JITSymbol findMangledSymbol(const std::string &Name) { -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 // The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported // flag to decide whether a symbol will be visible or not, when we call // IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true. @@ -113,7 +113,7 @@ private: if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) return JITSymbol(SymAddr, JITSymbolFlags::Exported); -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 // For Windows retry without "_" at beginning, as RTDyldMemoryManager uses // GetProcAddress and standard libraries like msvcrt.dll use names // with and without "_" (for example "_itoa" but "sin"). @@ -126,7 +126,6 @@ private: return nullptr; } - SymbolStringPool SSP; ExecutionSession ES; std::shared_ptr Resolver; std::unique_ptr TM; diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index ddc7fe793844135f2ed43c718eba0c1cd27f6104..6792219f87306183c9f24f0fb1e33f6bd2d3eaba 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -199,13 +199,48 @@ typedef enum { } LLVMDLLStorageClass; typedef enum { - LLVMCCallConv = 0, - LLVMFastCallConv = 8, - LLVMColdCallConv = 9, - LLVMWebKitJSCallConv = 12, - LLVMAnyRegCallConv = 13, - LLVMX86StdcallCallConv = 64, - LLVMX86FastcallCallConv = 65 + LLVMCCallConv = 0, + LLVMFastCallConv = 8, + LLVMColdCallConv = 9, + LLVMGHCCallConv = 10, + LLVMHiPECallConv = 11, + LLVMWebKitJSCallConv = 12, + LLVMAnyRegCallConv = 13, + LLVMPreserveMostCallConv = 14, + LLVMPreserveAllCallConv = 15, + LLVMSwiftCallConv = 16, + LLVMCXXFASTTLSCallConv = 17, + LLVMX86StdcallCallConv = 64, + LLVMX86FastcallCallConv = 65, + LLVMARMAPCSCallConv = 66, + LLVMARMAAPCSCallConv = 67, + LLVMARMAAPCSVFPCallConv = 68, + LLVMMSP430INTRCallConv = 69, + LLVMX86ThisCallCallConv = 70, + LLVMPTXKernelCallConv = 71, + LLVMPTXDeviceCallConv = 72, + LLVMSPIRFUNCCallConv = 75, + LLVMSPIRKERNELCallConv = 76, + LLVMIntelOCLBICallConv = 77, + LLVMX8664SysVCallConv = 78, + LLVMWin64CallConv = 79, + LLVMX86VectorCallCallConv = 80, + LLVMHHVMCallConv = 81, + LLVMHHVMCCallConv = 82, + LLVMX86INTRCallConv = 83, + LLVMAVRINTRCallConv = 84, + LLVMAVRSIGNALCallConv = 85, + LLVMAVRBUILTINCallConv = 86, + LLVMAMDGPUVSCallConv = 87, + LLVMAMDGPUGSCallConv = 88, + LLVMAMDGPUPSCallConv = 89, + LLVMAMDGPUCSCallConv = 90, + LLVMAMDGPUKERNELCallConv = 91, + LLVMX86RegCallCallConv = 92, + LLVMAMDGPUHSCallConv = 93, + LLVMMSP430BUILTINCallConv = 94, + LLVMAMDGPULSCallConv = 95, + LLVMAMDGPUESCallConv = 96 } LLVMCallConv; typedef enum { @@ -341,6 +376,62 @@ typedef enum { LLVMDSNote } LLVMDiagnosticSeverity; +typedef enum { + LLVMInlineAsmDialectATT, + LLVMInlineAsmDialectIntel +} LLVMInlineAsmDialect; + +typedef enum { + /** + * Emits an error if two values disagree, otherwise the resulting value is + * that of the operands. + * + * @see Module::ModFlagBehavior::Error + */ + LLVMModuleFlagBehaviorError, + /** + * Emits a warning if two values disagree. The result value will be the + * operand for the flag from the first module being linked. + * + * @see Module::ModFlagBehavior::Warning + */ + LLVMModuleFlagBehaviorWarning, + /** + * Adds a requirement that another module flag be present and have a + * specified value after linking is performed. The value must be a metadata + * pair, where the first element of the pair is the ID of the module flag + * to be restricted, and the second element of the pair is the value the + * module flag should be restricted to. This behavior can be used to + * restrict the allowable results (via triggering of an error) of linking + * IDs with the **Override** behavior. + * + * @see Module::ModFlagBehavior::Require + */ + LLVMModuleFlagBehaviorRequire, + /** + * Uses the specified value, regardless of the behavior or value of the + * other module. If both modules specify **Override**, but the values + * differ, an error will be emitted. + * + * @see Module::ModFlagBehavior::Override + */ + LLVMModuleFlagBehaviorOverride, + /** + * Appends the two values, which are required to be metadata nodes. + * + * @see Module::ModFlagBehavior::Append + */ + LLVMModuleFlagBehaviorAppend, + /** + * Appends the two values, which are required to be metadata + * nodes. However, duplicate entries in the second list are dropped + * during the append operation. + * + * @see Module::ModFlagBehavior::AppendUnique + */ + LLVMModuleFlagBehaviorAppendUnique, +} LLVMModuleFlagBehavior; + /** * Attribute index are either LLVMAttributeReturnIndex, * LLVMAttributeFunctionIndex or a parameter number from 1 to N. @@ -625,6 +716,64 @@ const char *LLVMGetTarget(LLVMModuleRef M); */ void LLVMSetTarget(LLVMModuleRef M, const char *Triple); +/** + * Returns the module flags as an array of flag-key-value triples. The caller + * is responsible for freeing this array by calling + * \c LLVMDisposeModuleFlagsMetadata. + * + * @see Module::getModuleFlagsMetadata() + */ +LLVMModuleFlagEntry *LLVMCopyModuleFlagsMetadata(LLVMModuleRef M, size_t *Len); + +/** + * Destroys module flags metadata entries. + */ +void LLVMDisposeModuleFlagsMetadata(LLVMModuleFlagEntry *Entries); + +/** + * Returns the flag behavior for a module flag entry at a specific index. + * + * @see Module::ModuleFlagEntry::Behavior + */ +LLVMModuleFlagBehavior +LLVMModuleFlagEntriesGetFlagBehavior(LLVMModuleFlagEntry *Entries, + unsigned Index); + +/** + * Returns the key for a module flag entry at a specific index. + * + * @see Module::ModuleFlagEntry::Key + */ +const char *LLVMModuleFlagEntriesGetKey(LLVMModuleFlagEntry *Entries, + unsigned Index, size_t *Len); + +/** + * Returns the metadata for a module flag entry at a specific index. + * + * @see Module::ModuleFlagEntry::Val + */ +LLVMMetadataRef LLVMModuleFlagEntriesGetMetadata(LLVMModuleFlagEntry *Entries, + unsigned Index); + +/** + * Add a module-level flag to the module-level flags metadata if it doesn't + * already exist. + * + * @see Module::getModuleFlag() + */ +LLVMMetadataRef LLVMGetModuleFlag(LLVMModuleRef M, + const char *Key, size_t KeyLen); + +/** + * Add a module-level flag to the module-level flags metadata if it doesn't + * already exist. + * + * @see Module::addModuleFlag() + */ +void LLVMAddModuleFlag(LLVMModuleRef M, LLVMModuleFlagBehavior Behavior, + const char *Key, size_t KeyLen, + LLVMMetadataRef Val); + /** * Dump a representation of a module to stderr. * @@ -649,12 +798,37 @@ LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, */ char *LLVMPrintModuleToString(LLVMModuleRef M); +/** + * Get inline assembly for a module. + * + * @see Module::getModuleInlineAsm() + */ +const char *LLVMGetModuleInlineAsm(LLVMModuleRef M, size_t *Len); + /** * Set inline assembly for a module. * * @see Module::setModuleInlineAsm() */ -void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm); +void LLVMSetModuleInlineAsm2(LLVMModuleRef M, const char *Asm, size_t Len); + +/** + * Append inline assembly to a module. + * + * @see Module::appendModuleInlineAsm() + */ +void LLVMAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm, size_t Len); + +/** + * Create the specified uniqued inline asm string. + * + * @see InlineAsm::get() + */ +LLVMValueRef LLVMGetInlineAsm(LLVMTypeRef Ty, + char *AsmString, size_t AsmStringSize, + char *Constraints, size_t ConstraintsSize, + LLVMBool HasSideEffects, LLVMBool IsAlignStack, + LLVMInlineAsmDialect Dialect); /** * Obtain the context to which this module is associated. @@ -745,6 +919,9 @@ LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn); */ LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn); +/** Deprecated: Use LLVMSetModuleInlineAsm2 instead. */ +void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm); + /** * @} */ @@ -1319,14 +1496,14 @@ LLVMValueKind LLVMGetValueKind(LLVMValueRef Val); * * @see llvm::Value::getName() */ -const char *LLVMGetValueName(LLVMValueRef Val); +const char *LLVMGetValueName2(LLVMValueRef Val, size_t *Length); /** * Set the string name of a value. * * @see llvm::Value::setName() */ -void LLVMSetValueName(LLVMValueRef Val, const char *Name); +void LLVMSetValueName2(LLVMValueRef Val, const char *Name, size_t NameLen); /** * Dump a representation of a value to stderr. @@ -1378,6 +1555,11 @@ LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST) LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val); LLVMValueRef LLVMIsAMDString(LLVMValueRef Val); +/** Deprecated: Use LLVMGetValueName2 instead. */ +const char *LLVMGetValueName(LLVMValueRef Val); +/** Deprecated: Use LLVMSetValueName2 instead. */ +void LLVMSetValueName(LLVMValueRef Val, const char *Name); + /** * @} */ @@ -1820,10 +2002,12 @@ LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx); +LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB); + +/** Deprecated: Use LLVMGetInlineAsm instead. */ LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, const char *Constraints, LLVMBool HasSideEffects, LLVMBool IsAlignStack); -LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB); /** * @} @@ -1933,6 +2117,56 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit); LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name); +/** + * Obtain a GlobalAlias value from a Module by its name. + * + * The returned value corresponds to a llvm::GlobalAlias value. + * + * @see llvm::Module::getNamedAlias() + */ +LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M, + const char *Name, size_t NameLen); + +/** + * Obtain an iterator to the first GlobalAlias in a Module. + * + * @see llvm::Module::alias_begin() + */ +LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M); + +/** + * Obtain an iterator to the last GlobalAlias in a Module. + * + * @see llvm::Module::alias_end() + */ +LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M); + +/** + * Advance a GlobalAlias iterator to the next GlobalAlias. + * + * Returns NULL if the iterator was already at the end and there are no more + * global aliases. + */ +LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA); + +/** + * Decrement a GlobalAlias iterator to the previous GlobalAlias. + * + * Returns NULL if the iterator was already at the beginning and there are + * no previous global aliases. + */ +LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA); + +/** + * Retrieve the target value of an alias. + */ +LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias); + +/** + * Set the target value of an alias. + */ +void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee); + /** * @} */ diff --git a/include/llvm-c/DataTypes.h.cmake b/include/llvm-c/DataTypes.h similarity index 76% rename from include/llvm-c/DataTypes.h.cmake rename to include/llvm-c/DataTypes.h index 19799ef93ffe39ef5dd209055010250c7f7b6f92..7081c83ffc2b60b11e0358e10e2b86568246ad92 100644 --- a/include/llvm-c/DataTypes.h.cmake +++ b/include/llvm-c/DataTypes.h @@ -24,34 +24,14 @@ #ifndef LLVM_C_DATATYPES_H #define LLVM_C_DATATYPES_H -#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} -#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} -#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T} -#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T} - #ifdef __cplusplus #include #else #include #endif -#ifdef __cplusplus -#include -#else -#ifdef HAVE_INTTYPES_H #include -#endif -#endif - -#ifdef __cplusplus -#include -#else -#ifdef HAVE_STDINT_H #include -#else -#error "Compiler must provide an implementation of stdint.h" -#endif -#endif #ifndef _MSC_VER @@ -74,15 +54,6 @@ #undef INT64_MIN #endif -/* Handle incorrect definition of uint64_t as u_int64_t */ -#ifndef HAVE_UINT64_T -#ifdef HAVE_U_INT64_T -typedef u_int64_t uint64_t; -#else -# error "Don't have a definition for uint64_t on this platform" -#endif -#endif - #else /* _MSC_VER */ #ifdef __cplusplus #include @@ -99,22 +70,6 @@ typedef signed __int64 ssize_t; typedef signed int ssize_t; #endif /* _WIN64 */ -#ifndef HAVE_INTTYPES_H -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" - -#define PRId32 "d" -#define PRIi32 "i" -#define PRIo32 "o" -#define PRIu32 "u" -#define PRIx32 "x" -#define PRIX32 "X" -#endif /* HAVE_INTTYPES_H */ - #endif /* _MSC_VER */ /* Set defaults for constants which we cannot find. */ diff --git a/include/llvm-c/DebugInfo.h b/include/llvm-c/DebugInfo.h index a5e5653630c17a8ff9c58f2772e9b327f0b03da1..dc1578f48627137b37f0b84637c81ed0716254b4 100644 --- a/include/llvm-c/DebugInfo.h +++ b/include/llvm-c/DebugInfo.h @@ -121,6 +121,11 @@ typedef enum { LLVMDWARFEmissionLineTablesOnly } LLVMDWARFEmissionKind; +/** + * An LLVM DWARF type encoding. + */ +typedef unsigned LLVMDWARFTypeEncoding; + /** * The current debug metadata version number. */ @@ -212,6 +217,158 @@ LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen); +/** + * Creates a new descriptor for a module with the specified parent scope. + * \param Builder The \c DIBuilder. + * \param ParentScope The parent scope containing this module declaration. + * \param Name Module name. + * \param NameLen The length of the C string passed to \c Name. + * \param ConfigMacros A space-separated shell-quoted list of -D macro + definitions as they would appear on a command line. + * \param ConfigMacrosLen The length of the C string passed to \c ConfigMacros. + * \param IncludePath The path to the module map file. + * \param IncludePathLen The length of the C string passed to \c IncludePath. + * \param ISysRoot The Clang system root (value of -isysroot). + * \param ISysRootLen The length of the C string passed to \c ISysRoot. + */ +LLVMMetadataRef +LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope, + const char *Name, size_t NameLen, + const char *ConfigMacros, size_t ConfigMacrosLen, + const char *IncludePath, size_t IncludePathLen, + const char *ISysRoot, size_t ISysRootLen); + +/** + * Creates a new descriptor for a namespace with the specified parent scope. + * \param Builder The \c DIBuilder. + * \param ParentScope The parent scope containing this module declaration. + * \param Name NameSpace name. + * \param NameLen The length of the C string passed to \c Name. + * \param ExportSymbols Whether or not the namespace exports symbols, e.g. + * this is true of C++ inline namespaces. + */ +LLVMMetadataRef +LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder, + LLVMMetadataRef ParentScope, + const char *Name, size_t NameLen, + LLVMBool ExportSymbols); + +/** + * Create a new descriptor for the specified subprogram. + * \param Builder The \c DIBuilder. + * \param Scope Function scope. + * \param Name Function name. + * \param NameLen Length of enumeration name. + * \param LinkageName Mangled function name. + * \param LinkageNameLen Length of linkage name. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Function type. + * \param IsLocalToUnit True if this function is not externally visible. + * \param IsDefinition True if this is a function definition. + * \param ScopeLine Set to the beginning of the scope this starts + * \param Flags E.g.: \c LLVMDIFlagLValueReference. These flags are + * used to emit dwarf attributes. + * \param IsOptimized True if optimization is ON. + */ +LLVMMetadataRef LLVMDIBuilderCreateFunction( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, const char *LinkageName, size_t LinkageNameLen, + LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, + LLVMBool IsLocalToUnit, LLVMBool IsDefinition, + unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized); + +/** + * Create a descriptor for a lexical block with the specified parent context. + * \param Builder The \c DIBuilder. + * \param Scope Parent lexical block. + * \param File Source file. + * \param Line The line in the source file. + * \param Column The column in the source file. + */ +LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, + LLVMMetadataRef File, unsigned Line, unsigned Column); + +/** + * Create a descriptor for a lexical block with a new file attached. + * \param Builder The \c DIBuilder. + * \param Scope Lexical block. + * \param File Source file. + * \param Discriminator DWARF path discriminator value. + */ +LLVMMetadataRef +LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + LLVMMetadataRef File, + unsigned Discriminator); + +/** + * Create a descriptor for an imported namespace. Suitable for e.g. C++ + * using declarations. + * \param Builder The \c DIBuilder. + * \param Scope The scope this module is imported into + * \param File File where the declaration is located. + * \param Line Line number of the declaration. + */ +LLVMMetadataRef +LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + LLVMMetadataRef NS, + LLVMMetadataRef File, + unsigned Line); + +/** + * Create a descriptor for an imported module that aliases another + * imported entity descriptor. + * \param Builder The \c DIBuilder. + * \param Scope The scope this module is imported into + * \param ImportedEntity Previous imported entity to alias. + * \param File File where the declaration is located. + * \param Line Line number of the declaration. + */ +LLVMMetadataRef +LLVMDIBuilderCreateImportedModuleFromAlias(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + LLVMMetadataRef ImportedEntity, + LLVMMetadataRef File, + unsigned Line); + +/** + * Create a descriptor for an imported module. + * \param Builder The \c DIBuilder. + * \param Scope The scope this module is imported into + * \param M The module being imported here + * \param File File where the declaration is located. + * \param Line Line number of the declaration. + */ +LLVMMetadataRef +LLVMDIBuilderCreateImportedModuleFromModule(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + LLVMMetadataRef M, + LLVMMetadataRef File, + unsigned Line); + +/** + * Create a descriptor for an imported function, type, or variable. Suitable + * for e.g. FORTRAN-style USE declarations. + * \param Builder The DIBuilder. + * \param Scope The scope this module is imported into. + * \param Decl The declaration (or definition) of a function, type, + or variable. + * \param File File where the declaration is located. + * \param Line Line number of the declaration. + * \param Name A name that uniquely identifies this imported declaration. + * \param NameLen The length of the C string passed to \c Name. + */ +LLVMMetadataRef +LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + LLVMMetadataRef Decl, + LLVMMetadataRef File, + unsigned Line, + const char *Name, size_t NameLen); + /** * Creates a new DebugLocation that describes a source location. * \param Line The line in the source file. @@ -227,6 +384,768 @@ LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line, unsigned Column, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt); +/** + * Get the line number of this debug location. + * \param Location The debug location. + * + * @see DILocation::getLine() + */ +unsigned LLVMDILocationGetLine(LLVMMetadataRef Location); + +/** + * Get the column number of this debug location. + * \param Location The debug location. + * + * @see DILocation::getColumn() + */ +unsigned LLVMDILocationGetColumn(LLVMMetadataRef Location); + +/** + * Get the local scope associated with this debug location. + * \param Location The debug location. + * + * @see DILocation::getScope() + */ +LLVMMetadataRef LLVMDILocationGetScope(LLVMMetadataRef Location); + +/** + * Create a type array. + * \param Builder The DIBuilder. + * \param Data The type elements. + * \param NumElements Number of type elements. + */ +LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder, + LLVMMetadataRef *Data, + size_t NumElements); + +/** + * Create subroutine type. + * \param Builder The DIBuilder. + * \param File The file in which the subroutine resides. + * \param ParameterTypes An array of subroutine parameter types. This + * includes return type at 0th index. + * \param NumParameterTypes The number of parameter types in \c ParameterTypes + * \param Flags E.g.: \c LLVMDIFlagLValueReference. + * These flags are used to emit dwarf attributes. + */ +LLVMMetadataRef +LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, + LLVMMetadataRef File, + LLVMMetadataRef *ParameterTypes, + unsigned NumParameterTypes, + LLVMDIFlags Flags); + +/** + * Create debugging information entry for an enumeration. + * \param Builder The DIBuilder. + * \param Scope Scope in which this enumeration is defined. + * \param Name Enumeration name. + * \param NameLen Length of enumeration name. + * \param File File where this member is defined. + * \param LineNumber Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param Elements Enumeration elements. + * \param NumElements Number of enumeration elements. + * \param ClassTy Underlying type of a C++11/ObjC fixed enum. + */ +LLVMMetadataRef LLVMDIBuilderCreateEnumerationType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef *Elements, + unsigned NumElements, LLVMMetadataRef ClassTy); + +/** + * Create debugging information entry for a union. + * \param Builder The DIBuilder. + * \param Scope Scope in which this union is defined. + * \param Name Union name. + * \param NameLen Length of union name. + * \param File File where this member is defined. + * \param LineNumber Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param Flags Flags to encode member attribute, e.g. private + * \param Elements Union elements. + * \param NumElements Number of union elements. + * \param RunTimeLang Optional parameter, Objective-C runtime version. + * \param UniqueId A unique identifier for the union. + * \param UniqueIdLen Length of unique identifier. + */ +LLVMMetadataRef LLVMDIBuilderCreateUnionType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, + LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang, + const char *UniqueId, size_t UniqueIdLen); + + +/** + * Create debugging information entry for an array. + * \param Builder The DIBuilder. + * \param Size Array size. + * \param AlignInBits Alignment. + * \param Ty Element type. + * \param Subscripts Subscripts. + * \param NumSubscripts Number of subscripts. + */ +LLVMMetadataRef +LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, + uint32_t AlignInBits, LLVMMetadataRef Ty, + LLVMMetadataRef *Subscripts, + unsigned NumSubscripts); + +/** + * Create debugging information entry for a vector type. + * \param Builder The DIBuilder. + * \param Size Vector size. + * \param AlignInBits Alignment. + * \param Ty Element type. + * \param Subscripts Subscripts. + * \param NumSubscripts Number of subscripts. + */ +LLVMMetadataRef +LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size, + uint32_t AlignInBits, LLVMMetadataRef Ty, + LLVMMetadataRef *Subscripts, + unsigned NumSubscripts); + +/** + * Create a DWARF unspecified type. + * \param Builder The DIBuilder. + * \param Name The unspecified type's name. + * \param NameLen Length of type name. + */ +LLVMMetadataRef +LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name, + size_t NameLen); + +/** + * Create debugging information entry for a basic + * type. + * \param Builder The DIBuilder. + * \param Name Type name. + * \param NameLen Length of type name. + * \param SizeInBits Size of the type. + * \param Encoding DWARF encoding code, e.g. \c LLVMDWARFTypeEncoding_float. + */ +LLVMMetadataRef +LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, + size_t NameLen, uint64_t SizeInBits, + LLVMDWARFTypeEncoding Encoding); + +/** + * Create debugging information entry for a pointer. + * \param Builder The DIBuilder. + * \param PointeeTy Type pointed by this pointer. + * \param SizeInBits Size. + * \param AlignInBits Alignment. (optional, pass 0 to ignore) + * \param AddressSpace DWARF address space. (optional, pass 0 to ignore) + * \param Name Pointer type name. (optional) + * \param NameLen Length of pointer type name. (optional) + */ +LLVMMetadataRef LLVMDIBuilderCreatePointerType( + LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, + uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, + const char *Name, size_t NameLen); + +/** + * Create debugging information entry for a struct. + * \param Builder The DIBuilder. + * \param Scope Scope in which this struct is defined. + * \param Name Struct name. + * \param NameLen Struct name length. + * \param File File where this member is defined. + * \param LineNumber Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param Flags Flags to encode member attribute, e.g. private + * \param Elements Struct elements. + * \param NumElements Number of struct elements. + * \param RunTimeLang Optional parameter, Objective-C runtime version. + * \param VTableHolder The object containing the vtable for the struct. + * \param UniqueId A unique identifier for the struct. + * \param UniqueIdLen Length of the unique identifier for the struct. + */ +LLVMMetadataRef LLVMDIBuilderCreateStructType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, + LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements, + unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder, + const char *UniqueId, size_t UniqueIdLen); + +/** + * Create debugging information entry for a member. + * \param Builder The DIBuilder. + * \param Scope Member scope. + * \param Name Member name. + * \param NameLen Length of member name. + * \param File File where this member is defined. + * \param LineNo Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param OffsetInBits Member offset. + * \param Flags Flags to encode member attribute, e.g. private + * \param Ty Parent type. + */ +LLVMMetadataRef LLVMDIBuilderCreateMemberType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNo, + uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + LLVMDIFlags Flags, LLVMMetadataRef Ty); + +/** + * Create debugging information entry for a + * C++ static data member. + * \param Builder The DIBuilder. + * \param Scope Member scope. + * \param Name Member name. + * \param NameLen Length of member name. + * \param File File where this member is declared. + * \param LineNumber Line number. + * \param Type Type of the static member. + * \param Flags Flags to encode member attribute, e.g. private. + * \param ConstantVal Const initializer of the member. + * \param AlignInBits Member alignment. + */ +LLVMMetadataRef +LLVMDIBuilderCreateStaticMemberType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, + uint32_t AlignInBits); + +/** + * Create debugging information entry for a pointer to member. + * \param Builder The DIBuilder. + * \param PointeeType Type pointed to by this pointer. + * \param ClassType Type for which this pointer points to members of. + * \param SizeInBits Size. + * \param AlignInBits Alignment. + * \param Flags Flags. + */ +LLVMMetadataRef +LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder, + LLVMMetadataRef PointeeType, + LLVMMetadataRef ClassType, + uint64_t SizeInBits, + uint32_t AlignInBits, + LLVMDIFlags Flags); +/** + * Create debugging information entry for Objective-C instance variable. + * \param Builder The DIBuilder. + * \param Name Member name. + * \param NameLen The length of the C string passed to \c Name. + * \param File File where this member is defined. + * \param LineNo Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param OffsetInBits Member offset. + * \param Flags Flags to encode member attribute, e.g. private + * \param Ty Parent type. + * \param PropertyNode Property associated with this ivar. + */ +LLVMMetadataRef +LLVMDIBuilderCreateObjCIVar(LLVMDIBuilderRef Builder, + const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNo, + uint64_t SizeInBits, uint32_t AlignInBits, + uint64_t OffsetInBits, LLVMDIFlags Flags, + LLVMMetadataRef Ty, LLVMMetadataRef PropertyNode); + +/** + * Create debugging information entry for Objective-C property. + * \param Builder The DIBuilder. + * \param Name Property name. + * \param NameLen The length of the C string passed to \c Name. + * \param File File where this property is defined. + * \param LineNo Line number. + * \param GetterName Name of the Objective C property getter selector. + * \param GetterNameLen The length of the C string passed to \c GetterName. + * \param SetterName Name of the Objective C property setter selector. + * \param SetterNameLen The length of the C string passed to \c SetterName. + * \param PropertyAttributes Objective C property attributes. + * \param Ty Type. + */ +LLVMMetadataRef +LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder, + const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNo, + const char *GetterName, size_t GetterNameLen, + const char *SetterName, size_t SetterNameLen, + unsigned PropertyAttributes, + LLVMMetadataRef Ty); + +/** + * Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set. + * \param Builder The DIBuilder. + * \param Type The underlying type to which this pointer points. + */ +LLVMMetadataRef +LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder, + LLVMMetadataRef Type); + +/** + * Create debugging information entry for a qualified + * type, e.g. 'const int'. + * \param Builder The DIBuilder. + * \param Tag Tag identifying type, + * e.g. LLVMDWARFTypeQualifier_volatile_type + * \param Type Base Type. + */ +LLVMMetadataRef +LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, + LLVMMetadataRef Type); + +/** + * Create debugging information entry for a c++ + * style reference or rvalue reference type. + * \param Builder The DIBuilder. + * \param Tag Tag identifying type, + * \param Type Base Type. + */ +LLVMMetadataRef +LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag, + LLVMMetadataRef Type); + +/** + * Create C++11 nullptr type. + * \param Builder The DIBuilder. + */ +LLVMMetadataRef +LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder); + +/** + * Create debugging information entry for a typedef. + * \param Builder The DIBuilder. + * \param Type Original type. + * \param Name Typedef name. + * \param File File where this type is defined. + * \param LineNo Line number. + * \param Scope The surrounding context for the typedef. + */ +LLVMMetadataRef +LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, + const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Scope); + +/** + * Create debugging information entry to establish inheritance relationship + * between two types. + * \param Builder The DIBuilder. + * \param Ty Original type. + * \param BaseTy Base type. Ty is inherits from base. + * \param BaseOffset Base offset. + * \param VBPtrOffset Virtual base pointer offset. + * \param Flags Flags to describe inheritance attribute, e.g. private + */ +LLVMMetadataRef +LLVMDIBuilderCreateInheritance(LLVMDIBuilderRef Builder, + LLVMMetadataRef Ty, LLVMMetadataRef BaseTy, + uint64_t BaseOffset, uint32_t VBPtrOffset, + LLVMDIFlags Flags); + +/** + * Create a permanent forward-declared type. + * \param Builder The DIBuilder. + * \param Tag A unique tag for this type. + * \param Name Type name. + * \param NameLen Length of type name. + * \param Scope Type scope. + * \param File File where this type is defined. + * \param Line Line number where this type is defined. + * \param RuntimeLang Indicates runtime version for languages like + * Objective-C. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param UniqueIdentifier A unique identifier for the type. + * \param UniqueIdentifierLen Length of the unique identifier. + */ +LLVMMetadataRef LLVMDIBuilderCreateForwardDecl( + LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, + size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, + unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, + const char *UniqueIdentifier, size_t UniqueIdentifierLen); + +/** + * Create a temporary forward-declared type. + * \param Builder The DIBuilder. + * \param Tag A unique tag for this type. + * \param Name Type name. + * \param NameLen Length of type name. + * \param Scope Type scope. + * \param File File where this type is defined. + * \param Line Line number where this type is defined. + * \param RuntimeLang Indicates runtime version for languages like + * Objective-C. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param Flags Flags. + * \param UniqueIdentifier A unique identifier for the type. + * \param UniqueIdentifierLen Length of the unique identifier. + */ +LLVMMetadataRef +LLVMDIBuilderCreateReplaceableCompositeType( + LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, + size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, + unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, + LLVMDIFlags Flags, const char *UniqueIdentifier, + size_t UniqueIdentifierLen); + +/** + * Create debugging information entry for a bit field member. + * \param Builder The DIBuilder. + * \param Scope Member scope. + * \param Name Member name. + * \param NameLen Length of member name. + * \param File File where this member is defined. + * \param LineNumber Line number. + * \param SizeInBits Member size. + * \param OffsetInBits Member offset. + * \param StorageOffsetInBits Member storage offset. + * \param Flags Flags to encode member attribute. + * \param Type Parent type. + */ +LLVMMetadataRef +LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, + uint64_t OffsetInBits, + uint64_t StorageOffsetInBits, + LLVMDIFlags Flags, LLVMMetadataRef Type); + +/** + * Create debugging information entry for a class. + * \param Scope Scope in which this class is defined. + * \param Name Class name. + * \param NameLen The length of the C string passed to \c Name. + * \param File File where this member is defined. + * \param LineNumber Line number. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param OffsetInBits Member offset. + * \param Flags Flags to encode member attribute, e.g. private. + * \param DerivedFrom Debug info of the base class of this type. + * \param Elements Class members. + * \param NumElements Number of class elements. + * \param VTableHolder Debug info of the base class that contains vtable + * for this type. This is used in + * DW_AT_containing_type. See DWARF documentation + * for more info. + * \param TemplateParamsNode Template type parameters. + * \param UniqueIdentifier A unique identifier for the type. + * \param UniqueIdentifierLen Length of the unique identifier. + */ +LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, const char *Name, size_t NameLen, + LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, + LLVMMetadataRef DerivedFrom, + LLVMMetadataRef *Elements, unsigned NumElements, + LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode, + const char *UniqueIdentifier, size_t UniqueIdentifierLen); + +/** + * Create a uniqued DIType* clone with FlagArtificial set. + * \param Builder The DIBuilder. + * \param Type The underlying type. + */ +LLVMMetadataRef +LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder, + LLVMMetadataRef Type); + +/** + * Get the name of this DIType. + * \param DType The DIType. + * \param Length The length of the returned string. + * + * @see DIType::getName() + */ +const char *LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length); + +/** + * Get the size of this DIType in bits. + * \param DType The DIType. + * + * @see DIType::getSizeInBits() + */ +uint64_t LLVMDITypeGetSizeInBits(LLVMMetadataRef DType); + +/** + * Get the offset of this DIType in bits. + * \param DType The DIType. + * + * @see DIType::getOffsetInBits() + */ +uint64_t LLVMDITypeGetOffsetInBits(LLVMMetadataRef DType); + +/** + * Get the alignment of this DIType in bits. + * \param DType The DIType. + * + * @see DIType::getAlignInBits() + */ +uint32_t LLVMDITypeGetAlignInBits(LLVMMetadataRef DType); + +/** + * Get the source line where this DIType is declared. + * \param DType The DIType. + * + * @see DIType::getLine() + */ +unsigned LLVMDITypeGetLine(LLVMMetadataRef DType); + +/** + * Get the flags associated with this DIType. + * \param DType The DIType. + * + * @see DIType::getFlags() + */ +LLVMDIFlags LLVMDITypeGetFlags(LLVMMetadataRef DType); + +/** + * Create a descriptor for a value range. + * \param Builder The DIBuilder. + * \param LowerBound Lower bound of the subrange, e.g. 0 for C, 1 for Fortran. + * \param Count Count of elements in the subrange. + */ +LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, + int64_t LowerBound, + int64_t Count); + +/** + * Create an array of DI Nodes. + * \param Builder The DIBuilder. + * \param Data The DI Node elements. + * \param NumElements Number of DI Node elements. + */ +LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder, + LLVMMetadataRef *Data, + size_t NumElements); + +/** + * Create a new descriptor for the specified variable which has a complex + * address expression for its address. + * \param Builder The DIBuilder. + * \param Addr An array of complex address operations. + * \param Length Length of the address operation array. + */ +LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder, + int64_t *Addr, size_t Length); + +/** + * Create a new descriptor for the specified variable that does not have an + * address, but does have a constant value. + * \param Builder The DIBuilder. + * \param Value The constant value. + */ +LLVMMetadataRef +LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder, + int64_t Value); + +/** + * Create a new descriptor for the specified variable. + * \param Scope Variable scope. + * \param Name Name of the variable. + * \param NameLen The length of the C string passed to \c Name. + * \param Linkage Mangled name of the variable. + * \param LinkLen The length of the C string passed to \c Linkage. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Variable Type. + * \param LocalToUnit Boolean flag indicate whether this variable is + * externally visible or not. + * \param Expr The location of the global relative to the attached + * GlobalVariable. + * \param Decl Reference to the corresponding declaration. + * \param AlignInBits Variable alignment(or 0 if no alignment attr was + * specified) + */ +LLVMMetadataRef +LLVMDIBuilderCreateGlobalVariableExpression(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + const char *Name, size_t NameLen, + const char *Linkage, size_t LinkLen, + LLVMMetadataRef File, + unsigned LineNo, + LLVMMetadataRef Ty, + LLVMBool LocalToUnit, + LLVMMetadataRef Expr, + LLVMMetadataRef Decl, + uint32_t AlignInBits); +/** + * Create a new temporary \c MDNode. Suitable for use in constructing cyclic + * \c MDNode structures. A temporary \c MDNode is not uniqued, may be RAUW'd, + * and must be manually deleted with \c LLVMDisposeTemporaryMDNode. + * \param Ctx The context in which to construct the temporary node. + * \param Data The metadata elements. + * \param NumElements Number of metadata elements. + */ +LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data, + size_t NumElements); + +/** + * Deallocate a temporary node. + * + * Calls \c replaceAllUsesWith(nullptr) before deleting, so any remaining + * references will be reset. + * \param TempNode The temporary metadata node. + */ +void LLVMDisposeTemporaryMDNode(LLVMMetadataRef TempNode); + +/** + * Replace all uses of temporary metadata. + * \param TempTargetMetadata The temporary metadata node. + * \param Replacement The replacement metadata node. + */ +void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TempTargetMetadata, + LLVMMetadataRef Replacement); + +/** + * Create a new descriptor for the specified global variable that is temporary + * and meant to be RAUWed. + * \param Scope Variable scope. + * \param Name Name of the variable. + * \param NameLen The length of the C string passed to \c Name. + * \param Linkage Mangled name of the variable. + * \param LnkLen The length of the C string passed to \c Linkage. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Variable Type. + * \param LocalToUnit Boolean flag indicate whether this variable is + * externally visible or not. + * \param Decl Reference to the corresponding declaration. + * \param AlignInBits Variable alignment(or 0 if no alignment attr was + * specified) + */ +LLVMMetadataRef +LLVMDIBuilderCreateTempGlobalVariableFwdDecl(LLVMDIBuilderRef Builder, + LLVMMetadataRef Scope, + const char *Name, size_t NameLen, + const char *Linkage, size_t LnkLen, + LLVMMetadataRef File, + unsigned LineNo, + LLVMMetadataRef Ty, + LLVMBool LocalToUnit, + LLVMMetadataRef Decl, + uint32_t AlignInBits); + +/** + * Insert a new llvm.dbg.declare intrinsic call before the given instruction. + * \param Builder The DIBuilder. + * \param Storage The storage of the variable to declare. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Instr Instruction acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDeclareBefore( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr); + +/** + * Insert a new llvm.dbg.declare intrinsic call at the end of the given basic + * block. If the basic block has a terminator instruction, the intrinsic is + * inserted before that terminator instruction. + * \param Builder The DIBuilder. + * \param Storage The storage of the variable to declare. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Block Basic block acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block); + +/** + * Insert a new llvm.dbg.value intrinsic call before the given instruction. + * \param Builder The DIBuilder. + * \param Val The value of the variable. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Instr Instruction acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDbgValueBefore(LLVMDIBuilderRef Builder, + LLVMValueRef Val, + LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, + LLVMMetadataRef DebugLoc, + LLVMValueRef Instr); + +/** + * Insert a new llvm.dbg.value intrinsic call at the end of the given basic + * block. If the basic block has a terminator instruction, the intrinsic is + * inserted before that terminator instruction. + * \param Builder The DIBuilder. + * \param Val The value of the variable. + * \param VarInfo The variable's debug info descriptor. + * \param Expr A complex location expression for the variable. + * \param DebugLoc Debug info location. + * \param Block Basic block acting as a location for the new intrinsic. + */ +LLVMValueRef LLVMDIBuilderInsertDbgValueAtEnd(LLVMDIBuilderRef Builder, + LLVMValueRef Val, + LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, + LLVMMetadataRef DebugLoc, + LLVMBasicBlockRef Block); + +/** + * Create a new descriptor for a local auto variable. + * \param Builder The DIBuilder. + * \param Scope The local scope the variable is declared in. + * \param Name Variable name. + * \param NameLen Length of variable name. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Metadata describing the type of the variable. + * \param AlwaysPreserve If true, this descriptor will survive optimizations. + * \param Flags Flags. + * \param AlignInBits Variable alignment. + */ +LLVMMetadataRef LLVMDIBuilderCreateAutoVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, + LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits); + +/** + * Create a new descriptor for a function parameter variable. + * \param Builder The DIBuilder. + * \param Scope The local scope the variable is declared in. + * \param Name Variable name. + * \param NameLen Length of variable name. + * \param ArgNo Unique argument number for this variable; starts at 1. + * \param File File where this variable is defined. + * \param LineNo Line number. + * \param Ty Metadata describing the type of the variable. + * \param AlwaysPreserve If true, this descriptor will survive optimizations. + * \param Flags Flags. + */ +LLVMMetadataRef LLVMDIBuilderCreateParameterVariable( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, + LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags); + +/** + * Get the metadata of the subprogram attached to a function. + * + * @see llvm::Function::getSubprogram() + */ +LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func); + +/** + * Set the subprogram attached to a function. + * + * @see llvm::Function::setSubprogram() + */ +void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP); + #ifdef __cplusplus } /* end extern "C" */ #endif diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h index 51830fe139c6e844ade2bdb9c182fec277144cd0..f109a9879ea98ac7ba15ac64a2aad9ba2e00f8c5 100644 --- a/include/llvm-c/ExecutionEngine.h +++ b/include/llvm-c/ExecutionEngine.h @@ -182,6 +182,12 @@ LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager( void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM); +/*===-- JIT Event Listener functions -------------------------------------===*/ + +LLVMJITEventListenerRef LLVMCreateGDBRegistrationListener(void); +LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void); +LLVMJITEventListenerRef LLVMCreateOprofileJITEventListener(void); + /** * @} */ diff --git a/include/llvm-c/Initialization.h b/include/llvm-c/Initialization.h index 90c8396f7ad3b80df5b6e76a6ab11bb1ea0ccb11..e45eafb139f2c00ac4e98d2d52fbcabba7622b0c 100644 --- a/include/llvm-c/Initialization.h +++ b/include/llvm-c/Initialization.h @@ -37,6 +37,7 @@ void LLVMInitializeScalarOpts(LLVMPassRegistryRef R); void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R); void LLVMInitializeVectorization(LLVMPassRegistryRef R); void LLVMInitializeInstCombine(LLVMPassRegistryRef R); +void LLVMInitializeAggressiveInstCombiner(LLVMPassRegistryRef R); void LLVMInitializeIPO(LLVMPassRegistryRef R); void LLVMInitializeInstrumentation(LLVMPassRegistryRef R); void LLVMInitializeAnalysis(LLVMPassRegistryRef R); diff --git a/include/llvm-c/OrcBindings.h b/include/llvm-c/OrcBindings.h index d2e2e7de4d3c8223f5dcba548b9b4f0d022fea8b..9497f0d40776fbe9dca96d5f77bdf8fe3b9da0d1 100644 --- a/include/llvm-c/OrcBindings.h +++ b/include/llvm-c/OrcBindings.h @@ -140,11 +140,34 @@ LLVMOrcErrorCode LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack, LLVMOrcTargetAddress *RetAddr, const char *SymbolName); +/** + * Get symbol address from JIT instance, searching only the specified + * handle. + */ +LLVMOrcErrorCode LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, + LLVMOrcTargetAddress *RetAddr, + LLVMOrcModuleHandle H, + const char *SymbolName); + /** * Dispose of an ORC JIT stack. */ LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack); +/** + * Register a JIT Event Listener. + * + * A NULL listener is ignored. + */ +void LLVMOrcRegisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L); + +/** + * Unegister a JIT Event Listener. + * + * A NULL listener is ignored. + */ +void LLVMOrcUnregisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L); + #ifdef __cplusplus } #endif /* extern "C" */ diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h index f4f7f7698c45bc7b1fe4c57771bf518c82479686..fb0862c226a6d99ea52943b2e2a4c6ad35e86ed6 100644 --- a/include/llvm-c/TargetMachine.h +++ b/include/llvm-c/TargetMachine.h @@ -137,6 +137,14 @@ LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleR disposed with LLVMDisposeMessage. */ char* LLVMGetDefaultTargetTriple(void); +/** Get the host CPU as a string. The result needs to be disposed with + LLVMDisposeMessage. */ +char* LLVMGetHostCPUName(void); + +/** Get the host CPU's features as a string. The result needs to be disposed + with LLVMDisposeMessage. */ +char* LLVMGetHostCPUFeatures(void); + /** Adds the target-specific analysis passes to the pass manager. */ void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM); diff --git a/include/llvm-c/Transforms/InstCombine.h b/include/llvm-c/Transforms/InstCombine.h new file mode 100644 index 0000000000000000000000000000000000000000..e1c1572d53dcfa62894bf4e97c631c0ed5808fe4 --- /dev/null +++ b/include/llvm-c/Transforms/InstCombine.h @@ -0,0 +1,43 @@ +/*===-- Scalar.h - Scalar Transformation Library C Interface ----*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header declares the C interface to libLLVMInstCombine.a, which *| +|* combines instructions to form fewer, simple IR instructions. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_TRANSFORMS_INSTCOMBINE_H +#define LLVM_C_TRANSFORMS_INSTCOMBINE_H + +#include "llvm-c/Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LLVMCTransformsInstCombine Instruction Combining transformations + * @ingroup LLVMCTransforms + * + * @{ + */ + +/** See llvm::createInstructionCombiningPass function. */ +void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + +#endif + diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h index c828813cbffbff0a7f84e3d7dbae2ada07c6cd24..88fff2a8ad4e32c0de303e4dad38d55aa1bf1538 100644 --- a/include/llvm-c/Transforms/Scalar.h +++ b/include/llvm-c/Transforms/Scalar.h @@ -35,6 +35,9 @@ extern "C" { /** See llvm::createAggressiveDCEPass function. */ void LLVMAddAggressiveDCEPass(LLVMPassManagerRef PM); +/** See llvm::createAggressiveInstCombinerPass function. */ +void LLVMAddAggressiveInstCombinerPass(LLVMPassManagerRef PM); + /** See llvm::createBitTrackingDCEPass function. */ void LLVMAddBitTrackingDCEPass(LLVMPassManagerRef PM); diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h index cf8306aee762f560401870b7df037b7a3c284294..e3f9961acfb12a3eb4793e0fafd27d443e4daf6a 100644 --- a/include/llvm-c/Transforms/Vectorize.h +++ b/include/llvm-c/Transforms/Vectorize.h @@ -33,9 +33,6 @@ extern "C" { * @{ */ -/** DEPRECATED - Use LLVMAddSLPVectorizePass */ -void LLVMAddBBVectorizePass(LLVMPassManagerRef PM); - /** See llvm::createLoopVectorizePass function. */ void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM); diff --git a/include/llvm-c/Types.h b/include/llvm-c/Types.h index 1793400513940217e64cbd00e58cefa5838c1115..4a33542e86cc0b2ec45a557e1726b004f76fe831 100644 --- a/include/llvm-c/Types.h +++ b/include/llvm-c/Types.h @@ -139,6 +139,16 @@ typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef; */ typedef struct LLVMComdat *LLVMComdatRef; +/** + * @see llvm::Module::ModuleFlagEntry + */ +typedef struct LLVMOpaqueModuleFlagEntry LLVMModuleFlagEntry; + +/** + * @see llvm::JITEventListener + */ +typedef struct LLVMOpaqueJITEventListener *LLVMJITEventListenerRef; + /** * @} */ diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 65d172dea182841e2f3f58ef8df2a0c0019000fb..1acd610f70ac663e70df31b251a50cb8305d1583 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -190,7 +190,7 @@ lto_module_create_from_memory_with_path(const void* mem, size_t length, const char *path); /** - * \brief Loads an object file in its own context. + * Loads an object file in its own context. * * Loads an object file in its own LLVMContext. This function call is * thread-safe. However, modules created this way should not be merged into an @@ -205,7 +205,7 @@ lto_module_create_in_local_context(const void *mem, size_t length, const char *path); /** - * \brief Loads an object file in the codegen context. + * Loads an object file in the codegen context. * * Loads an object file into the same context as \c cg. The module is safe to * add using \a lto_codegen_add_module(). @@ -345,7 +345,7 @@ extern lto_code_gen_t lto_codegen_create(void); /** - * \brief Instantiate a code generator in its own context. + * Instantiate a code generator in its own context. * * Instantiates a code generator in its own context. Modules added via \a * lto_codegen_add_module() must have all been created in the same context, @@ -539,7 +539,7 @@ lto_codegen_set_should_internalize(lto_code_gen_t cg, lto_bool_t ShouldInternalize); /** - * \brief Set whether to embed uselists in bitcode. + * Set whether to embed uselists in bitcode. * * Sets whether \a lto_codegen_write_merged_modules() should embed uselists in * output bitcode. This should be turned on for all -save-temps output. diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 6c0b6ae78ae3279676dea008629c243607a671da..5c59af4c04ba6a22737cc4109a95c9a875d26ab2 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -1215,7 +1215,7 @@ inline APFloat abs(APFloat X) { return X; } -/// \brief Returns the negated value of the argument. +/// Returns the negated value of the argument. inline APFloat neg(APFloat X) { X.changeSign(); return X; diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 118c62eec87c21f63afdd04d1a25a496d095efb7..1f3f7f5f592ad3f9ec03b23d76adf0d864c125fe 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file implements a class to represent arbitrary precision +/// This file implements a class to represent arbitrary precision /// integral constant values and operations on them. /// //===----------------------------------------------------------------------===// @@ -40,7 +40,7 @@ inline APInt operator-(APInt); // APInt Class //===----------------------------------------------------------------------===// -/// \brief Class for arbitrary precision integers. +/// Class for arbitrary precision integers. /// /// APInt is a functional replacement for common case unsigned integer type like /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width @@ -94,7 +94,7 @@ private: friend class APSInt; - /// \brief Fast internal constructor + /// Fast internal constructor /// /// This constructor is used only internally for speed of construction of /// temporaries. It is unsafe for general use so it is not public. @@ -102,19 +102,19 @@ private: U.pVal = val; } - /// \brief Determine if this APInt just has one word to store value. + /// Determine if this APInt just has one word to store value. /// /// \returns true if the number of bits <= 64, false otherwise. bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; } - /// \brief Determine which word a bit is in. + /// Determine which word a bit is in. /// /// \returns the word position for the specified bit position. static unsigned whichWord(unsigned bitPosition) { return bitPosition / APINT_BITS_PER_WORD; } - /// \brief Determine which bit in a word a bit is in. + /// Determine which bit in a word a bit is in. /// /// \returns the bit position in a word for the specified bit position /// in the APInt. @@ -122,7 +122,7 @@ private: return bitPosition % APINT_BITS_PER_WORD; } - /// \brief Get a single bit mask. + /// Get a single bit mask. /// /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set /// This method generates and returns a uint64_t (word) mask for a single @@ -132,7 +132,7 @@ private: return 1ULL << whichBit(bitPosition); } - /// \brief Clear unused high order bits + /// Clear unused high order bits /// /// This method is used internally to clear the top "N" bits in the high order /// word that are not used by the APInt. This is needed after the most @@ -151,7 +151,7 @@ private: return *this; } - /// \brief Get the word corresponding to a bit position + /// Get the word corresponding to a bit position /// \returns the corresponding word for the specified bit position. uint64_t getWord(unsigned bitPosition) const { return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)]; @@ -162,7 +162,7 @@ private: /// value of any bits upon return. Caller should populate the bits after. void reallocate(unsigned NewBitWidth); - /// \brief Convert a char array into an APInt + /// Convert a char array into an APInt /// /// \param radix 2, 8, 10, 16, or 36 /// Converts a string into a number. The string must be non-empty @@ -176,7 +176,7 @@ private: /// result to hold the input. void fromString(unsigned numBits, StringRef str, uint8_t radix); - /// \brief An internal division function for dividing APInts. + /// An internal division function for dividing APInts. /// /// This is used by the toString method to divide by the radix. It simply /// provides a more convenient form of divide for internal use since KnuthDiv @@ -258,7 +258,7 @@ public: /// \name Constructors /// @{ - /// \brief Create a new APInt of numBits width, initialized as val. + /// Create a new APInt of numBits width, initialized as val. /// /// If isSigned is true then val is treated as if it were a signed value /// (i.e. as an int64_t) and the appropriate sign extension to the bit width @@ -279,7 +279,7 @@ public: } } - /// \brief Construct an APInt of numBits width, initialized as bigVal[]. + /// Construct an APInt of numBits width, initialized as bigVal[]. /// /// Note that bigVal.size() can be smaller or larger than the corresponding /// bit width but any extraneous bits will be dropped. @@ -297,7 +297,7 @@ public: /// constructor. APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]); - /// \brief Construct an APInt from a string representation. + /// Construct an APInt from a string representation. /// /// This constructor interprets the string \p str in the given radix. The /// interpretation stops when the first character that is not suitable for the @@ -311,7 +311,7 @@ public: APInt(unsigned numBits, StringRef str, uint8_t radix); /// Simply makes *this a copy of that. - /// @brief Copy Constructor. + /// Copy Constructor. APInt(const APInt &that) : BitWidth(that.BitWidth) { if (isSingleWord()) U.VAL = that.U.VAL; @@ -319,26 +319,26 @@ public: initSlowCase(that); } - /// \brief Move Constructor. + /// Move Constructor. APInt(APInt &&that) : BitWidth(that.BitWidth) { memcpy(&U, &that.U, sizeof(U)); that.BitWidth = 0; } - /// \brief Destructor. + /// Destructor. ~APInt() { if (needsCleanup()) delete[] U.pVal; } - /// \brief Default constructor that creates an uninteresting APInt + /// Default constructor that creates an uninteresting APInt /// representing a 1-bit zero value. /// /// This is useful for object deserialization (pair this with the static /// method Read). explicit APInt() : BitWidth(1) { U.VAL = 0; } - /// \brief Returns whether this instance allocated memory. + /// Returns whether this instance allocated memory. bool needsCleanup() const { return !isSingleWord(); } /// Used to insert APInt objects, or objects that contain APInt objects, into @@ -349,33 +349,33 @@ public: /// \name Value Tests /// @{ - /// \brief Determine sign of this APInt. + /// Determine sign of this APInt. /// /// This tests the high bit of this APInt to determine if it is set. /// /// \returns true if this APInt is negative, false otherwise bool isNegative() const { return (*this)[BitWidth - 1]; } - /// \brief Determine if this APInt Value is non-negative (>= 0) + /// Determine if this APInt Value is non-negative (>= 0) /// /// This tests the high bit of the APInt to determine if it is unset. bool isNonNegative() const { return !isNegative(); } - /// \brief Determine if sign bit of this APInt is set. + /// Determine if sign bit of this APInt is set. /// /// This tests the high bit of this APInt to determine if it is set. /// /// \returns true if this APInt has its sign bit set, false otherwise. bool isSignBitSet() const { return (*this)[BitWidth-1]; } - /// \brief Determine if sign bit of this APInt is clear. + /// Determine if sign bit of this APInt is clear. /// /// This tests the high bit of this APInt to determine if it is clear. /// /// \returns true if this APInt has its sign bit clear, false otherwise. bool isSignBitClear() const { return !isSignBitSet(); } - /// \brief Determine if this APInt Value is positive. + /// Determine if this APInt Value is positive. /// /// This tests if the value of this APInt is positive (> 0). Note /// that 0 is not a positive value. @@ -383,7 +383,7 @@ public: /// \returns true if this APInt is positive. bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); } - /// \brief Determine if all bits are set + /// Determine if all bits are set /// /// This checks to see if the value has all bits of the APInt are set or not. bool isAllOnesValue() const { @@ -392,13 +392,13 @@ public: return countTrailingOnesSlowCase() == BitWidth; } - /// \brief Determine if all bits are clear + /// Determine if all bits are clear /// /// This checks to see if the value has all bits of the APInt are clear or /// not. bool isNullValue() const { return !*this; } - /// \brief Determine if this is a value of 1. + /// Determine if this is a value of 1. /// /// This checks to see if the value of this APInt is one. bool isOneValue() const { @@ -407,13 +407,13 @@ public: return countLeadingZerosSlowCase() == BitWidth - 1; } - /// \brief Determine if this is the largest unsigned value. + /// Determine if this is the largest unsigned value. /// /// This checks to see if the value of this APInt is the maximum unsigned /// value for the APInt's bit width. bool isMaxValue() const { return isAllOnesValue(); } - /// \brief Determine if this is the largest signed value. + /// Determine if this is the largest signed value. /// /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. @@ -423,13 +423,13 @@ public: return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1; } - /// \brief Determine if this is the smallest unsigned value. + /// Determine if this is the smallest unsigned value. /// /// This checks to see if the value of this APInt is the minimum unsigned /// value for the APInt's bit width. bool isMinValue() const { return isNullValue(); } - /// \brief Determine if this is the smallest signed value. + /// Determine if this is the smallest signed value. /// /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. @@ -439,19 +439,19 @@ public: return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1; } - /// \brief Check if this APInt has an N-bits unsigned integer value. + /// Check if this APInt has an N-bits unsigned integer value. bool isIntN(unsigned N) const { assert(N && "N == 0 ???"); return getActiveBits() <= N; } - /// \brief Check if this APInt has an N-bits signed integer value. + /// Check if this APInt has an N-bits signed integer value. bool isSignedIntN(unsigned N) const { assert(N && "N == 0 ???"); return getMinSignedBits() <= N; } - /// \brief Check if this APInt's value is a power of two greater than zero. + /// Check if this APInt's value is a power of two greater than zero. /// /// \returns true if the argument APInt value is a power of two > 0. bool isPowerOf2() const { @@ -460,12 +460,12 @@ public: return countPopulationSlowCase() == 1; } - /// \brief Check if the APInt's value is returned by getSignMask. + /// Check if the APInt's value is returned by getSignMask. /// /// \returns true if this is the value returned by getSignMask. bool isSignMask() const { return isMinSignedValue(); } - /// \brief Convert APInt to a boolean value. + /// Convert APInt to a boolean value. /// /// This converts the APInt to a boolean value as a test against zero. bool getBoolValue() const { return !!*this; } @@ -476,7 +476,7 @@ public: return ugt(Limit) ? Limit : getZExtValue(); } - /// \brief Check if the APInt consists of a repeated bit pattern. + /// Check if the APInt consists of a repeated bit pattern. /// /// e.g. 0x01010101 satisfies isSplat(8). /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit @@ -505,7 +505,7 @@ public: return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth); } - /// \brief Return true if this APInt value contains a sequence of ones with + /// Return true if this APInt value contains a sequence of ones with /// the remainder zero. bool isShiftedMask() const { if (isSingleWord()) @@ -519,29 +519,29 @@ public: /// \name Value Generators /// @{ - /// \brief Gets maximum unsigned value of APInt for specific bit width. + /// Gets maximum unsigned value of APInt for specific bit width. static APInt getMaxValue(unsigned numBits) { return getAllOnesValue(numBits); } - /// \brief Gets maximum signed value of APInt for a specific bit width. + /// Gets maximum signed value of APInt for a specific bit width. static APInt getSignedMaxValue(unsigned numBits) { APInt API = getAllOnesValue(numBits); API.clearBit(numBits - 1); return API; } - /// \brief Gets minimum unsigned value of APInt for a specific bit width. + /// Gets minimum unsigned value of APInt for a specific bit width. static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); } - /// \brief Gets minimum signed value of APInt for a specific bit width. + /// Gets minimum signed value of APInt for a specific bit width. static APInt getSignedMinValue(unsigned numBits) { APInt API(numBits, 0); API.setBit(numBits - 1); return API; } - /// \brief Get the SignMask for a specific bit width. + /// Get the SignMask for a specific bit width. /// /// This is just a wrapper function of getSignedMinValue(), and it helps code /// readability when we want to get a SignMask. @@ -549,19 +549,19 @@ public: return getSignedMinValue(BitWidth); } - /// \brief Get the all-ones value. + /// Get the all-ones value. /// /// \returns the all-ones value for an APInt of the specified bit-width. static APInt getAllOnesValue(unsigned numBits) { return APInt(numBits, WORD_MAX, true); } - /// \brief Get the '0' value. + /// Get the '0' value. /// /// \returns the '0' value for an APInt of the specified bit-width. static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); } - /// \brief Compute an APInt containing numBits highbits from this APInt. + /// Compute an APInt containing numBits highbits from this APInt. /// /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the low bits and right shift to the least significant bit. @@ -569,7 +569,7 @@ public: /// \returns the high "numBits" bits of this APInt. APInt getHiBits(unsigned numBits) const; - /// \brief Compute an APInt containing numBits lowbits from this APInt. + /// Compute an APInt containing numBits lowbits from this APInt. /// /// Get an APInt with the same BitWidth as this APInt, just zero mask /// the high bits. @@ -577,14 +577,14 @@ public: /// \returns the low "numBits" bits of this APInt. APInt getLoBits(unsigned numBits) const; - /// \brief Return an APInt with exactly one bit set in the result. + /// Return an APInt with exactly one bit set in the result. static APInt getOneBitSet(unsigned numBits, unsigned BitNo) { APInt Res(numBits, 0); Res.setBit(BitNo); return Res; } - /// \brief Get a value with a block of bits set. + /// Get a value with a block of bits set. /// /// Constructs an APInt value that has a contiguous range of bits set. The /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other @@ -603,7 +603,7 @@ public: return Res; } - /// \brief Get a value with upper bits starting at loBit set. + /// Get a value with upper bits starting at loBit set. /// /// Constructs an APInt value that has a contiguous range of bits set. The /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other @@ -620,7 +620,7 @@ public: return Res; } - /// \brief Get a value with high bits set + /// Get a value with high bits set /// /// Constructs an APInt value that has the top hiBitsSet bits set. /// @@ -632,7 +632,7 @@ public: return Res; } - /// \brief Get a value with low bits set + /// Get a value with low bits set /// /// Constructs an APInt value that has the bottom loBitsSet bits set. /// @@ -644,10 +644,10 @@ public: return Res; } - /// \brief Return a value containing V broadcasted over NewLen bits. + /// Return a value containing V broadcasted over NewLen bits. static APInt getSplat(unsigned NewLen, const APInt &V); - /// \brief Determine if two APInts have the same value, after zero-extending + /// Determine if two APInts have the same value, after zero-extending /// one of them (if needed!) to ensure that the bit-widths match. static bool isSameValue(const APInt &I1, const APInt &I2) { if (I1.getBitWidth() == I2.getBitWidth()) @@ -659,7 +659,7 @@ public: return I1.zext(I2.getBitWidth()) == I2; } - /// \brief Overload to compute a hash_code for an APInt value. + /// Overload to compute a hash_code for an APInt value. friend hash_code hash_value(const APInt &Arg); /// This function returns a pointer to the internal storage of the APInt. @@ -675,7 +675,7 @@ public: /// \name Unary Operators /// @{ - /// \brief Postfix increment operator. + /// Postfix increment operator. /// /// Increments *this by 1. /// @@ -686,12 +686,12 @@ public: return API; } - /// \brief Prefix increment operator. + /// Prefix increment operator. /// /// \returns *this incremented by one APInt &operator++(); - /// \brief Postfix decrement operator. + /// Postfix decrement operator. /// /// Decrements *this by 1. /// @@ -702,12 +702,12 @@ public: return API; } - /// \brief Prefix decrement operator. + /// Prefix decrement operator. /// /// \returns *this decremented by one. APInt &operator--(); - /// \brief Logical negation operator. + /// Logical negation operator. /// /// Performs logical negation operation on this APInt. /// @@ -722,7 +722,7 @@ public: /// \name Assignment Operators /// @{ - /// \brief Copy assignment operator. + /// Copy assignment operator. /// /// \returns *this after assignment of RHS. APInt &operator=(const APInt &RHS) { @@ -737,8 +737,13 @@ public: return *this; } - /// @brief Move assignment operator. + /// Move assignment operator. APInt &operator=(APInt &&that) { +#ifdef _MSC_VER + // The MSVC std::shuffle implementation still does self-assignment. + if (this == &that) + return *this; +#endif assert(this != &that && "Self-move not supported"); if (!isSingleWord()) delete[] U.pVal; @@ -753,7 +758,7 @@ public: return *this; } - /// \brief Assignment operator. + /// Assignment operator. /// /// The RHS value is assigned to *this. If the significant bits in RHS exceed /// the bit width, the excess bits are truncated. If the bit width is larger @@ -771,7 +776,7 @@ public: return *this; } - /// \brief Bitwise AND assignment operator. + /// Bitwise AND assignment operator. /// /// Performs a bitwise AND operation on this APInt and RHS. The result is /// assigned to *this. @@ -786,7 +791,7 @@ public: return *this; } - /// \brief Bitwise AND assignment operator. + /// Bitwise AND assignment operator. /// /// Performs a bitwise AND operation on this APInt and RHS. RHS is /// logically zero-extended or truncated to match the bit-width of @@ -801,7 +806,7 @@ public: return *this; } - /// \brief Bitwise OR assignment operator. + /// Bitwise OR assignment operator. /// /// Performs a bitwise OR operation on this APInt and RHS. The result is /// assigned *this; @@ -816,7 +821,7 @@ public: return *this; } - /// \brief Bitwise OR assignment operator. + /// Bitwise OR assignment operator. /// /// Performs a bitwise OR operation on this APInt and RHS. RHS is /// logically zero-extended or truncated to match the bit-width of @@ -831,7 +836,7 @@ public: return *this; } - /// \brief Bitwise XOR assignment operator. + /// Bitwise XOR assignment operator. /// /// Performs a bitwise XOR operation on this APInt and RHS. The result is /// assigned to *this. @@ -846,7 +851,7 @@ public: return *this; } - /// \brief Bitwise XOR assignment operator. + /// Bitwise XOR assignment operator. /// /// Performs a bitwise XOR operation on this APInt and RHS. RHS is /// logically zero-extended or truncated to match the bit-width of @@ -861,7 +866,7 @@ public: return *this; } - /// \brief Multiplication assignment operator. + /// Multiplication assignment operator. /// /// Multiplies this APInt by RHS and assigns the result to *this. /// @@ -869,7 +874,7 @@ public: APInt &operator*=(const APInt &RHS); APInt &operator*=(uint64_t RHS); - /// \brief Addition assignment operator. + /// Addition assignment operator. /// /// Adds RHS to *this and assigns the result to *this. /// @@ -877,7 +882,7 @@ public: APInt &operator+=(const APInt &RHS); APInt &operator+=(uint64_t RHS); - /// \brief Subtraction assignment operator. + /// Subtraction assignment operator. /// /// Subtracts RHS from *this and assigns the result to *this. /// @@ -885,7 +890,7 @@ public: APInt &operator-=(const APInt &RHS); APInt &operator-=(uint64_t RHS); - /// \brief Left-shift assignment function. + /// Left-shift assignment function. /// /// Shifts *this left by shiftAmt and assigns the result to *this. /// @@ -903,7 +908,7 @@ public: return *this; } - /// \brief Left-shift assignment function. + /// Left-shift assignment function. /// /// Shifts *this left by shiftAmt and assigns the result to *this. /// @@ -914,22 +919,22 @@ public: /// \name Binary Operators /// @{ - /// \brief Multiplication operator. + /// Multiplication operator. /// /// Multiplies this APInt by RHS and returns the result. APInt operator*(const APInt &RHS) const; - /// \brief Left logical shift operator. + /// Left logical shift operator. /// /// Shifts this APInt left by \p Bits and returns the result. APInt operator<<(unsigned Bits) const { return shl(Bits); } - /// \brief Left logical shift operator. + /// Left logical shift operator. /// /// Shifts this APInt left by \p Bits and returns the result. APInt operator<<(const APInt &Bits) const { return shl(Bits); } - /// \brief Arithmetic right-shift function. + /// Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. APInt ashr(unsigned ShiftAmt) const { @@ -953,7 +958,7 @@ public: ashrSlowCase(ShiftAmt); } - /// \brief Logical right-shift function. + /// Logical right-shift function. /// /// Logical right-shift this APInt by shiftAmt. APInt lshr(unsigned shiftAmt) const { @@ -975,7 +980,7 @@ public: lshrSlowCase(ShiftAmt); } - /// \brief Left-shift function. + /// Left-shift function. /// /// Left-shift this APInt by shiftAmt. APInt shl(unsigned shiftAmt) const { @@ -984,13 +989,13 @@ public: return R; } - /// \brief Rotate left by rotateAmt. + /// Rotate left by rotateAmt. APInt rotl(unsigned rotateAmt) const; - /// \brief Rotate right by rotateAmt. + /// Rotate right by rotateAmt. APInt rotr(unsigned rotateAmt) const; - /// \brief Arithmetic right-shift function. + /// Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. APInt ashr(const APInt &ShiftAmt) const { @@ -1002,7 +1007,7 @@ public: /// Arithmetic right-shift this APInt by shiftAmt in place. void ashrInPlace(const APInt &shiftAmt); - /// \brief Logical right-shift function. + /// Logical right-shift function. /// /// Logical right-shift this APInt by shiftAmt. APInt lshr(const APInt &ShiftAmt) const { @@ -1014,7 +1019,7 @@ public: /// Logical right-shift this APInt by ShiftAmt in place. void lshrInPlace(const APInt &ShiftAmt); - /// \brief Left-shift function. + /// Left-shift function. /// /// Left-shift this APInt by shiftAmt. APInt shl(const APInt &ShiftAmt) const { @@ -1023,13 +1028,13 @@ public: return R; } - /// \brief Rotate left by rotateAmt. + /// Rotate left by rotateAmt. APInt rotl(const APInt &rotateAmt) const; - /// \brief Rotate right by rotateAmt. + /// Rotate right by rotateAmt. APInt rotr(const APInt &rotateAmt) const; - /// \brief Unsigned division operation. + /// Unsigned division operation. /// /// Perform an unsigned divide operation on this APInt by RHS. Both this and /// RHS are treated as unsigned quantities for purposes of this division. @@ -1038,13 +1043,13 @@ public: APInt udiv(const APInt &RHS) const; APInt udiv(uint64_t RHS) const; - /// \brief Signed division function for APInt. + /// Signed division function for APInt. /// /// Signed divide this APInt by APInt RHS. APInt sdiv(const APInt &RHS) const; APInt sdiv(int64_t RHS) const; - /// \brief Unsigned remainder operation. + /// Unsigned remainder operation. /// /// Perform an unsigned remainder operation on this APInt with RHS being the /// divisor. Both this and RHS are treated as unsigned quantities for purposes @@ -1056,13 +1061,13 @@ public: APInt urem(const APInt &RHS) const; uint64_t urem(uint64_t RHS) const; - /// \brief Function for signed remainder operation. + /// Function for signed remainder operation. /// /// Signed remainder operation on APInt. APInt srem(const APInt &RHS) const; int64_t srem(int64_t RHS) const; - /// \brief Dual division/remainder interface. + /// Dual division/remainder interface. /// /// Sometimes it is convenient to divide two APInt values and obtain both the /// quotient and remainder. This function does both operations in the same @@ -1090,7 +1095,7 @@ public: APInt sshl_ov(const APInt &Amt, bool &Overflow) const; APInt ushl_ov(const APInt &Amt, bool &Overflow) const; - /// \brief Array-indexing support. + /// Array-indexing support. /// /// \returns the bit value at bitPosition bool operator[](unsigned bitPosition) const { @@ -1102,7 +1107,7 @@ public: /// \name Comparison Operators /// @{ - /// \brief Equality operator. + /// Equality operator. /// /// Compares this APInt with RHS for the validity of the equality /// relationship. @@ -1113,7 +1118,7 @@ public: return EqualSlowCase(RHS); } - /// \brief Equality operator. + /// Equality operator. /// /// Compares this APInt with a uint64_t for the validity of the equality /// relationship. @@ -1123,7 +1128,7 @@ public: return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val; } - /// \brief Equality comparison. + /// Equality comparison. /// /// Compares this APInt with RHS for the validity of the equality /// relationship. @@ -1131,7 +1136,7 @@ public: /// \returns true if *this == Val bool eq(const APInt &RHS) const { return (*this) == RHS; } - /// \brief Inequality operator. + /// Inequality operator. /// /// Compares this APInt with RHS for the validity of the inequality /// relationship. @@ -1139,7 +1144,7 @@ public: /// \returns true if *this != Val bool operator!=(const APInt &RHS) const { return !((*this) == RHS); } - /// \brief Inequality operator. + /// Inequality operator. /// /// Compares this APInt with a uint64_t for the validity of the inequality /// relationship. @@ -1147,7 +1152,7 @@ public: /// \returns true if *this != Val bool operator!=(uint64_t Val) const { return !((*this) == Val); } - /// \brief Inequality comparison + /// Inequality comparison /// /// Compares this APInt with RHS for the validity of the inequality /// relationship. @@ -1155,7 +1160,7 @@ public: /// \returns true if *this != Val bool ne(const APInt &RHS) const { return !((*this) == RHS); } - /// \brief Unsigned less than comparison + /// Unsigned less than comparison /// /// Regards both *this and RHS as unsigned quantities and compares them for /// the validity of the less-than relationship. @@ -1163,7 +1168,7 @@ public: /// \returns true if *this < RHS when both are considered unsigned. bool ult(const APInt &RHS) const { return compare(RHS) < 0; } - /// \brief Unsigned less than comparison + /// Unsigned less than comparison /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the less-than relationship. @@ -1174,7 +1179,7 @@ public: return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS; } - /// \brief Signed less than comparison + /// Signed less than comparison /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-than relationship. @@ -1182,7 +1187,7 @@ public: /// \returns true if *this < RHS when both are considered signed. bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; } - /// \brief Signed less than comparison + /// Signed less than comparison /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the less-than relationship. @@ -1193,7 +1198,7 @@ public: : getSExtValue() < RHS; } - /// \brief Unsigned less or equal comparison + /// Unsigned less or equal comparison /// /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the less-or-equal relationship. @@ -1201,7 +1206,7 @@ public: /// \returns true if *this <= RHS when both are considered unsigned. bool ule(const APInt &RHS) const { return compare(RHS) <= 0; } - /// \brief Unsigned less or equal comparison + /// Unsigned less or equal comparison /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the less-or-equal relationship. @@ -1209,7 +1214,7 @@ public: /// \returns true if *this <= RHS when considered unsigned. bool ule(uint64_t RHS) const { return !ugt(RHS); } - /// \brief Signed less or equal comparison + /// Signed less or equal comparison /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the less-or-equal relationship. @@ -1217,7 +1222,7 @@ public: /// \returns true if *this <= RHS when both are considered signed. bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; } - /// \brief Signed less or equal comparison + /// Signed less or equal comparison /// /// Regards both *this as a signed quantity and compares it with RHS for the /// validity of the less-or-equal relationship. @@ -1225,7 +1230,7 @@ public: /// \returns true if *this <= RHS when considered signed. bool sle(uint64_t RHS) const { return !sgt(RHS); } - /// \brief Unsigned greather than comparison + /// Unsigned greather than comparison /// /// Regards both *this and RHS as unsigned quantities and compares them for /// the validity of the greater-than relationship. @@ -1233,7 +1238,7 @@ public: /// \returns true if *this > RHS when both are considered unsigned. bool ugt(const APInt &RHS) const { return !ule(RHS); } - /// \brief Unsigned greater than comparison + /// Unsigned greater than comparison /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the greater-than relationship. @@ -1244,7 +1249,7 @@ public: return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS; } - /// \brief Signed greather than comparison + /// Signed greather than comparison /// /// Regards both *this and RHS as signed quantities and compares them for the /// validity of the greater-than relationship. @@ -1252,7 +1257,7 @@ public: /// \returns true if *this > RHS when both are considered signed. bool sgt(const APInt &RHS) const { return !sle(RHS); } - /// \brief Signed greater than comparison + /// Signed greater than comparison /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the greater-than relationship. @@ -1263,7 +1268,7 @@ public: : getSExtValue() > RHS; } - /// \brief Unsigned greater or equal comparison + /// Unsigned greater or equal comparison /// /// Regards both *this and RHS as unsigned quantities and compares them for /// validity of the greater-or-equal relationship. @@ -1271,7 +1276,7 @@ public: /// \returns true if *this >= RHS when both are considered unsigned. bool uge(const APInt &RHS) const { return !ult(RHS); } - /// \brief Unsigned greater or equal comparison + /// Unsigned greater or equal comparison /// /// Regards both *this as an unsigned quantity and compares it with RHS for /// the validity of the greater-or-equal relationship. @@ -1279,7 +1284,7 @@ public: /// \returns true if *this >= RHS when considered unsigned. bool uge(uint64_t RHS) const { return !ult(RHS); } - /// \brief Signed greater or equal comparison + /// Signed greater or equal comparison /// /// Regards both *this and RHS as signed quantities and compares them for /// validity of the greater-or-equal relationship. @@ -1287,7 +1292,7 @@ public: /// \returns true if *this >= RHS when both are considered signed. bool sge(const APInt &RHS) const { return !slt(RHS); } - /// \brief Signed greater or equal comparison + /// Signed greater or equal comparison /// /// Regards both *this as a signed quantity and compares it with RHS for /// the validity of the greater-or-equal relationship. @@ -1316,13 +1321,13 @@ public: /// \name Resizing Operators /// @{ - /// \brief Truncate to new width. + /// Truncate to new width. /// /// Truncate the APInt to a specified width. It is an error to specify a width /// that is greater than or equal to the current width. APInt trunc(unsigned width) const; - /// \brief Sign extend to a new width. + /// Sign extend to a new width. /// /// This operation sign extends the APInt to a new width. If the high order /// bit is set, the fill on the left will be done with 1 bits, otherwise zero. @@ -1330,32 +1335,32 @@ public: /// current width. APInt sext(unsigned width) const; - /// \brief Zero extend to a new width. + /// Zero extend to a new width. /// /// This operation zero extends the APInt to a new width. The high order bits /// are filled with 0 bits. It is an error to specify a width that is less /// than or equal to the current width. APInt zext(unsigned width) const; - /// \brief Sign extend or truncate to width + /// Sign extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, truncated, or left alone to make it that width. APInt sextOrTrunc(unsigned width) const; - /// \brief Zero extend or truncate to width + /// Zero extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, truncated, or left alone to make it that width. APInt zextOrTrunc(unsigned width) const; - /// \brief Sign extend or truncate to width + /// Sign extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, or left alone to make it that width. APInt sextOrSelf(unsigned width) const; - /// \brief Zero extend or truncate to width + /// Zero extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, or left alone to make it that width. @@ -1365,7 +1370,7 @@ public: /// \name Bit Manipulation Operators /// @{ - /// \brief Set every bit to 1. + /// Set every bit to 1. void setAllBits() { if (isSingleWord()) U.VAL = WORD_MAX; @@ -1376,7 +1381,7 @@ public: clearUnusedBits(); } - /// \brief Set a given bit to 1. + /// Set a given bit to 1. /// /// Set the given bit to 1 whose position is given as "bitPosition". void setBit(unsigned BitPosition) { @@ -1427,7 +1432,7 @@ public: return setBits(BitWidth - hiBits, BitWidth); } - /// \brief Set every bit to 0. + /// Set every bit to 0. void clearAllBits() { if (isSingleWord()) U.VAL = 0; @@ -1435,7 +1440,7 @@ public: memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE); } - /// \brief Set a given bit to 0. + /// Set a given bit to 0. /// /// Set the given bit to 0 whose position is given as "bitPosition". void clearBit(unsigned BitPosition) { @@ -1452,7 +1457,7 @@ public: clearBit(BitWidth - 1); } - /// \brief Toggle every bit to its opposite value. + /// Toggle every bit to its opposite value. void flipAllBits() { if (isSingleWord()) { U.VAL ^= WORD_MAX; @@ -1462,7 +1467,7 @@ public: } } - /// \brief Toggles a given bit to its opposite value. + /// Toggles a given bit to its opposite value. /// /// Toggle a given bit to its opposite value whose position is given /// as "bitPosition". @@ -1484,17 +1489,17 @@ public: /// \name Value Characterization Functions /// @{ - /// \brief Return the number of bits in the APInt. + /// Return the number of bits in the APInt. unsigned getBitWidth() const { return BitWidth; } - /// \brief Get the number of words. + /// Get the number of words. /// /// Here one word's bitwidth equals to that of uint64_t. /// /// \returns the number of words to hold the integer value of this APInt. unsigned getNumWords() const { return getNumWords(BitWidth); } - /// \brief Get the number of words. + /// Get the number of words. /// /// *NOTE* Here one word's bitwidth equals to that of uint64_t. /// @@ -1504,14 +1509,14 @@ public: return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; } - /// \brief Compute the number of active bits in the value + /// Compute the number of active bits in the value /// /// This function returns the number of active bits which is defined as the /// bit width minus the number of leading zeros. This is used in several /// computations to see how "wide" the value is. unsigned getActiveBits() const { return BitWidth - countLeadingZeros(); } - /// \brief Compute the number of active words in the value of this APInt. + /// Compute the number of active words in the value of this APInt. /// /// This is used in conjunction with getActiveData to extract the raw value of /// the APInt. @@ -1520,7 +1525,7 @@ public: return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1; } - /// \brief Get the minimum bit size for this signed APInt + /// Get the minimum bit size for this signed APInt /// /// Computes the minimum bit width for this APInt while considering it to be a /// signed (and probably negative) value. If the value is not negative, this @@ -1534,7 +1539,7 @@ public: return getActiveBits() + 1; } - /// \brief Get zero extended value + /// Get zero extended value /// /// This method attempts to return the value of this APInt as a zero extended /// uint64_t. The bitwidth must be <= 64 or the value must fit within a @@ -1546,7 +1551,7 @@ public: return U.pVal[0]; } - /// \brief Get sign extended value + /// Get sign extended value /// /// This method attempts to return the value of this APInt as a sign extended /// int64_t. The bit width must be <= 64 or the value must fit within an @@ -1558,13 +1563,13 @@ public: return int64_t(U.pVal[0]); } - /// \brief Get bits required for string value. + /// Get bits required for string value. /// /// This method determines how many bits are required to hold the APInt /// equivalent of the string given by \p str. static unsigned getBitsNeeded(StringRef str, uint8_t radix); - /// \brief The APInt version of the countLeadingZeros functions in + /// The APInt version of the countLeadingZeros functions in /// MathExtras.h. /// /// It counts the number of zeros from the most significant bit to the first @@ -1580,7 +1585,7 @@ public: return countLeadingZerosSlowCase(); } - /// \brief Count the number of leading one bits. + /// Count the number of leading one bits. /// /// This function is an APInt version of the countLeadingOnes /// functions in MathExtras.h. It counts the number of ones from the most @@ -1600,7 +1605,7 @@ public: return isNegative() ? countLeadingOnes() : countLeadingZeros(); } - /// \brief Count the number of trailing zero bits. + /// Count the number of trailing zero bits. /// /// This function is an APInt version of the countTrailingZeros /// functions in MathExtras.h. It counts the number of zeros from the least @@ -1614,7 +1619,7 @@ public: return countTrailingZerosSlowCase(); } - /// \brief Count the number of trailing one bits. + /// Count the number of trailing one bits. /// /// This function is an APInt version of the countTrailingOnes /// functions in MathExtras.h. It counts the number of ones from the least @@ -1628,7 +1633,7 @@ public: return countTrailingOnesSlowCase(); } - /// \brief Count the number of bits set. + /// Count the number of bits set. /// /// This function is an APInt version of the countPopulation functions /// in MathExtras.h. It counts the number of 1 bits in the APInt value. @@ -1662,7 +1667,7 @@ public: toString(Str, Radix, true, false); } - /// \brief Return the APInt as a std::string. + /// Return the APInt as a std::string. /// /// Note that this is an inefficient method. It is better to pass in a /// SmallVector/SmallString to the methods above to avoid thrashing the heap @@ -1676,16 +1681,16 @@ public: /// Value. APInt reverseBits() const; - /// \brief Converts this APInt to a double value. + /// Converts this APInt to a double value. double roundToDouble(bool isSigned) const; - /// \brief Converts this unsigned APInt to a double value. + /// Converts this unsigned APInt to a double value. double roundToDouble() const { return roundToDouble(false); } - /// \brief Converts this signed APInt to a double value. + /// Converts this signed APInt to a double value. double signedRoundToDouble() const { return roundToDouble(true); } - /// \brief Converts APInt bits to a double + /// Converts APInt bits to a double /// /// The conversion does not do a translation from integer to double, it just /// re-interprets the bits as a double. Note that it is valid to do this on @@ -1694,7 +1699,7 @@ public: return BitsToDouble(getWord(0)); } - /// \brief Converts APInt bits to a double + /// Converts APInt bits to a double /// /// The conversion does not do a translation from integer to float, it just /// re-interprets the bits as a float. Note that it is valid to do this on @@ -1703,7 +1708,7 @@ public: return BitsToFloat(getWord(0)); } - /// \brief Converts a double to APInt bits. + /// Converts a double to APInt bits. /// /// The conversion does not do a translation from double to integer, it just /// re-interprets the bits of the double. @@ -1711,7 +1716,7 @@ public: return APInt(sizeof(double) * CHAR_BIT, DoubleToBits(V)); } - /// \brief Converts a float to APInt bits. + /// Converts a float to APInt bits. /// /// The conversion does not do a translation from float to integer, it just /// re-interprets the bits of the float. @@ -1770,10 +1775,10 @@ public: return logBase2(); } - /// \brief Compute the square root + /// Compute the square root APInt sqrt() const; - /// \brief Get the absolute value; + /// Get the absolute value; /// /// If *this is < 0 then return -(*this), otherwise *this; APInt abs() const { @@ -1924,7 +1929,7 @@ public: /// Set the least significant BITS and clear the rest. static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits); - /// \brief debug method + /// debug method void dump() const; /// @} @@ -1947,7 +1952,7 @@ inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; } inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; } -/// \brief Unary bitwise complement operator. +/// Unary bitwise complement operator. /// /// \returns an APInt that is the bitwise complement of \p v. inline APInt operator~(APInt v) { @@ -2080,27 +2085,27 @@ inline APInt operator*(uint64_t LHS, APInt b) { namespace APIntOps { -/// \brief Determine the smaller of two APInts considered to be signed. +/// Determine the smaller of two APInts considered to be signed. inline const APInt &smin(const APInt &A, const APInt &B) { return A.slt(B) ? A : B; } -/// \brief Determine the larger of two APInts considered to be signed. +/// Determine the larger of two APInts considered to be signed. inline const APInt &smax(const APInt &A, const APInt &B) { return A.sgt(B) ? A : B; } -/// \brief Determine the smaller of two APInts considered to be signed. +/// Determine the smaller of two APInts considered to be signed. inline const APInt &umin(const APInt &A, const APInt &B) { return A.ult(B) ? A : B; } -/// \brief Determine the larger of two APInts considered to be unsigned. +/// Determine the larger of two APInts considered to be unsigned. inline const APInt &umax(const APInt &A, const APInt &B) { return A.ugt(B) ? A : B; } -/// \brief Compute GCD of two unsigned APInt values. +/// Compute GCD of two unsigned APInt values. /// /// This function returns the greatest common divisor of the two APInt values /// using Stein's algorithm. @@ -2108,38 +2113,38 @@ inline const APInt &umax(const APInt &A, const APInt &B) { /// \returns the greatest common divisor of A and B. APInt GreatestCommonDivisor(APInt A, APInt B); -/// \brief Converts the given APInt to a double value. +/// Converts the given APInt to a double value. /// /// Treats the APInt as an unsigned value for conversion purposes. inline double RoundAPIntToDouble(const APInt &APIVal) { return APIVal.roundToDouble(); } -/// \brief Converts the given APInt to a double value. +/// Converts the given APInt to a double value. /// /// Treats the APInt as a signed value for conversion purposes. inline double RoundSignedAPIntToDouble(const APInt &APIVal) { return APIVal.signedRoundToDouble(); } -/// \brief Converts the given APInt to a float vlalue. +/// Converts the given APInt to a float vlalue. inline float RoundAPIntToFloat(const APInt &APIVal) { return float(RoundAPIntToDouble(APIVal)); } -/// \brief Converts the given APInt to a float value. +/// Converts the given APInt to a float value. /// /// Treast the APInt as a signed value for conversion purposes. inline float RoundSignedAPIntToFloat(const APInt &APIVal) { return float(APIVal.signedRoundToDouble()); } -/// \brief Converts the given double value into a APInt. +/// Converts the given double value into a APInt. /// /// This function convert a double value to an APInt value. APInt RoundDoubleToAPInt(double Double, unsigned width); -/// \brief Converts a float value into a APInt. +/// Converts a float value into a APInt. /// /// Converts a float value into an APInt value. inline APInt RoundFloatToAPInt(float Float, unsigned width) { diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index dabbf3314bd022e33d7e8aa35f94683e41d91725..7ee2c4c62fced9963652357210d88ea445d2b96e 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -72,7 +72,7 @@ public: } using APInt::toString; - /// \brief Get the correctly-extended \c int64_t value. + /// Get the correctly-extended \c int64_t value. int64_t getExtValue() const { assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); return isSigned() ? getSExtValue() : getZExtValue(); @@ -279,13 +279,13 @@ public: : APInt::getSignedMinValue(numBits), Unsigned); } - /// \brief Determine if two APSInts have the same value, zero- or + /// Determine if two APSInts have the same value, zero- or /// sign-extending as needed. static bool isSameValue(const APSInt &I1, const APSInt &I2) { return !compareValues(I1, I2); } - /// \brief Compare underlying values of two numbers. + /// Compare underlying values of two numbers. static int compareValues(const APSInt &I1, const APSInt &I2) { if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned()) return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2); diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 5f7a769ddac443f95839b68f853a8bb4d5b09e8e..9cb25b09c6cb398ca5502df1b37400bcc3d37738 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -184,51 +184,51 @@ namespace llvm { /// slice(n) - Chop off the first N elements of the array. ArrayRef slice(size_t N) const { return slice(N, size() - N); } - /// \brief Drop the first \p N elements of the array. + /// Drop the first \p N elements of the array. ArrayRef drop_front(size_t N = 1) const { assert(size() >= N && "Dropping more elements than exist"); return slice(N, size() - N); } - /// \brief Drop the last \p N elements of the array. + /// Drop the last \p N elements of the array. ArrayRef drop_back(size_t N = 1) const { assert(size() >= N && "Dropping more elements than exist"); return slice(0, size() - N); } - /// \brief Return a copy of *this with the first N elements satisfying the + /// Return a copy of *this with the first N elements satisfying the /// given predicate removed. template ArrayRef drop_while(PredicateT Pred) const { return ArrayRef(find_if_not(*this, Pred), end()); } - /// \brief Return a copy of *this with the first N elements not satisfying + /// Return a copy of *this with the first N elements not satisfying /// the given predicate removed. template ArrayRef drop_until(PredicateT Pred) const { return ArrayRef(find_if(*this, Pred), end()); } - /// \brief Return a copy of *this with only the first \p N elements. + /// Return a copy of *this with only the first \p N elements. ArrayRef take_front(size_t N = 1) const { if (N >= size()) return *this; return drop_back(size() - N); } - /// \brief Return a copy of *this with only the last \p N elements. + /// Return a copy of *this with only the last \p N elements. ArrayRef take_back(size_t N = 1) const { if (N >= size()) return *this; return drop_front(size() - N); } - /// \brief Return the first N elements of this Array that satisfy the given + /// Return the first N elements of this Array that satisfy the given /// predicate. template ArrayRef take_while(PredicateT Pred) const { return ArrayRef(begin(), find_if_not(*this, Pred)); } - /// \brief Return the first N elements of this Array that don't satisfy the + /// Return the first N elements of this Array that don't satisfy the /// given predicate. template ArrayRef take_until(PredicateT Pred) const { return ArrayRef(begin(), find_if(*this, Pred)); @@ -358,7 +358,7 @@ namespace llvm { return slice(N, this->size() - N); } - /// \brief Drop the first \p N elements of the array. + /// Drop the first \p N elements of the array. MutableArrayRef drop_front(size_t N = 1) const { assert(this->size() >= N && "Dropping more elements than exist"); return slice(N, this->size() - N); @@ -369,42 +369,42 @@ namespace llvm { return slice(0, this->size() - N); } - /// \brief Return a copy of *this with the first N elements satisfying the + /// Return a copy of *this with the first N elements satisfying the /// given predicate removed. template MutableArrayRef drop_while(PredicateT Pred) const { return MutableArrayRef(find_if_not(*this, Pred), end()); } - /// \brief Return a copy of *this with the first N elements not satisfying + /// Return a copy of *this with the first N elements not satisfying /// the given predicate removed. template MutableArrayRef drop_until(PredicateT Pred) const { return MutableArrayRef(find_if(*this, Pred), end()); } - /// \brief Return a copy of *this with only the first \p N elements. + /// Return a copy of *this with only the first \p N elements. MutableArrayRef take_front(size_t N = 1) const { if (N >= this->size()) return *this; return drop_back(this->size() - N); } - /// \brief Return a copy of *this with only the last \p N elements. + /// Return a copy of *this with only the last \p N elements. MutableArrayRef take_back(size_t N = 1) const { if (N >= this->size()) return *this; return drop_front(this->size() - N); } - /// \brief Return the first N elements of this Array that satisfy the given + /// Return the first N elements of this Array that satisfy the given /// predicate. template MutableArrayRef take_while(PredicateT Pred) const { return MutableArrayRef(begin(), find_if_not(*this, Pred)); } - /// \brief Return the first N elements of this Array that don't satisfy the + /// Return the first N elements of this Array that don't satisfy the /// given predicate. template MutableArrayRef take_until(PredicateT Pred) const { diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 124c2a8c86dca44908e1e7a72d55004076d9581e..438c7d84c581b833a559bfd93914e74d755b14b0 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -779,7 +779,7 @@ public: } private: - /// \brief Perform a logical left shift of \p Count words by moving everything + /// Perform a logical left shift of \p Count words by moving everything /// \p Count words to the right in memory. /// /// While confusing, words are stored from least significant at Bits[0] to @@ -810,7 +810,7 @@ private: clear_unused_bits(); } - /// \brief Perform a logical right shift of \p Count words by moving those + /// Perform a logical right shift of \p Count words by moving those /// words to the left in memory. See wordShl for more information. /// void wordShr(uint32_t Count) { diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index e964d7fa23911d1867d53ce0317688effcc4ea78..1f3766d3c9de03c88df4c1e6dfd91af5c025880d 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -177,7 +177,7 @@ public: return *this; } - /// \brief Skips all children of the current node and traverses to next node + /// Skips all children of the current node and traverses to next node /// /// Note: This function takes care of incrementing the iterator. If you /// always increment and call this function, you risk walking off the end. diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h index db39ba4e0c50c932239447079804c547ff167609..49ef192364e8afb78f3b38f819d05d2e79a9d85d 100644 --- a/include/llvm/ADT/EpochTracker.h +++ b/include/llvm/ADT/EpochTracker.h @@ -17,7 +17,6 @@ #define LLVM_ADT_EPOCH_TRACKER_H #include "llvm/Config/abi-breaking.h" -#include "llvm/Config/llvm-config.h" #include @@ -25,7 +24,7 @@ namespace llvm { #if LLVM_ENABLE_ABI_BREAKING_CHECKS -/// \brief A base class for data structure classes wishing to make iterators +/// A base class for data structure classes wishing to make iterators /// ("handles") pointing into themselves fail-fast. When building without /// asserts, this class is empty and does nothing. /// @@ -40,15 +39,15 @@ class DebugEpochBase { public: DebugEpochBase() : Epoch(0) {} - /// \brief Calling incrementEpoch invalidates all handles pointing into the + /// Calling incrementEpoch invalidates all handles pointing into the /// calling instance. void incrementEpoch() { ++Epoch; } - /// \brief The destructor calls incrementEpoch to make use-after-free bugs + /// The destructor calls incrementEpoch to make use-after-free bugs /// more likely to crash deterministically. ~DebugEpochBase() { incrementEpoch(); } - /// \brief A base class for iterator classes ("handles") that wish to poll for + /// A base class for iterator classes ("handles") that wish to poll for /// iterator invalidating modifications in the underlying data structure. /// When LLVM is built without asserts, this class is empty and does nothing. /// @@ -66,12 +65,12 @@ public: explicit HandleBase(const DebugEpochBase *Parent) : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {} - /// \brief Returns true if the DebugEpochBase this Handle is linked to has + /// Returns true if the DebugEpochBase this Handle is linked to has /// not called incrementEpoch on itself since the creation of this /// HandleBase instance. bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; } - /// \brief Returns a pointer to the epoch word stored in the data structure + /// Returns a pointer to the epoch word stored in the data structure /// this handle points into. Can be used to check if two iterators point /// into the same data structure. const void *getEpochAddress() const { return EpochAddress; } diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index c3b574102f69d843542398b2fef8385c1e061cee..9f830baa4243b04d7394a933555ade283262cb89 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -57,7 +57,7 @@ namespace llvm { -/// \brief An opaque object representing a hash code. +/// An opaque object representing a hash code. /// /// This object represents the result of hashing some entity. It is intended to /// be used to implement hashtables or other hashing-based data structures. @@ -73,14 +73,14 @@ class hash_code { size_t value; public: - /// \brief Default construct a hash_code. + /// Default construct a hash_code. /// Note that this leaves the value uninitialized. hash_code() = default; - /// \brief Form a hash code directly from a numerical value. + /// Form a hash code directly from a numerical value. hash_code(size_t value) : value(value) {} - /// \brief Convert the hash code to its numerical value for use. + /// Convert the hash code to its numerical value for use. /*explicit*/ operator size_t() const { return value; } friend bool operator==(const hash_code &lhs, const hash_code &rhs) { @@ -90,11 +90,11 @@ public: return lhs.value != rhs.value; } - /// \brief Allow a hash_code to be directly run through hash_value. + /// Allow a hash_code to be directly run through hash_value. friend size_t hash_value(const hash_code &code) { return code.value; } }; -/// \brief Compute a hash_code for any integer value. +/// Compute a hash_code for any integer value. /// /// Note that this function is intended to compute the same hash_code for /// a particular value without regard to the pre-promotion type. This is in @@ -105,21 +105,21 @@ template typename std::enable_if::value, hash_code>::type hash_value(T value); -/// \brief Compute a hash_code for a pointer's address. +/// Compute a hash_code for a pointer's address. /// /// N.B.: This hashes the *address*. Not the value and not the type. template hash_code hash_value(const T *ptr); -/// \brief Compute a hash_code for a pair of objects. +/// Compute a hash_code for a pair of objects. template hash_code hash_value(const std::pair &arg); -/// \brief Compute a hash_code for a standard string. +/// Compute a hash_code for a standard string. template hash_code hash_value(const std::basic_string &arg); -/// \brief Override the execution seed with a fixed value. +/// Override the execution seed with a fixed value. /// /// This hashing library uses a per-execution seed designed to change on each /// run with high probability in order to ensure that the hash codes are not @@ -164,7 +164,7 @@ static const uint64_t k1 = 0xb492b66fbe98f273ULL; static const uint64_t k2 = 0x9ae16a3b2f90404fULL; static const uint64_t k3 = 0xc949d7c7509e6557ULL; -/// \brief Bitwise right rotate. +/// Bitwise right rotate. /// Normally this will compile to a single instruction, especially if the /// shift is a manifest constant. inline uint64_t rotate(uint64_t val, size_t shift) { @@ -254,13 +254,13 @@ inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) { return k2 ^ seed; } -/// \brief The intermediate state used during hashing. +/// The intermediate state used during hashing. /// Currently, the algorithm for computing hash codes is based on CityHash and /// keeps 56 bytes of arbitrary state. struct hash_state { uint64_t h0, h1, h2, h3, h4, h5, h6; - /// \brief Create a new hash_state structure and initialize it based on the + /// Create a new hash_state structure and initialize it based on the /// seed and the first 64-byte chunk. /// This effectively performs the initial mix. static hash_state create(const char *s, uint64_t seed) { @@ -272,7 +272,7 @@ struct hash_state { return state; } - /// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a' + /// Mix 32-bytes from the input sequence into the 16-bytes of 'a' /// and 'b', including whatever is already in 'a' and 'b'. static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) { a += fetch64(s); @@ -284,7 +284,7 @@ struct hash_state { a += c; } - /// \brief Mix in a 64-byte buffer of data. + /// Mix in a 64-byte buffer of data. /// We mix all 64 bytes even when the chunk length is smaller, but we /// record the actual length. void mix(const char *s) { @@ -302,7 +302,7 @@ struct hash_state { std::swap(h2, h0); } - /// \brief Compute the final 64-bit hash code value based on the current + /// Compute the final 64-bit hash code value based on the current /// state and the length of bytes hashed. uint64_t finalize(size_t length) { return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2, @@ -311,7 +311,7 @@ struct hash_state { }; -/// \brief A global, fixed seed-override variable. +/// A global, fixed seed-override variable. /// /// This variable can be set using the \see llvm::set_fixed_execution_seed /// function. See that function for details. Do not, under any circumstances, @@ -332,7 +332,7 @@ inline size_t get_execution_seed() { } -/// \brief Trait to indicate whether a type's bits can be hashed directly. +/// Trait to indicate whether a type's bits can be hashed directly. /// /// A type trait which is true if we want to combine values for hashing by /// reading the underlying data. It is false if values of this type must @@ -359,14 +359,14 @@ template struct is_hashable_data > (sizeof(T) + sizeof(U)) == sizeof(std::pair))> {}; -/// \brief Helper to get the hashable data representation for a type. +/// Helper to get the hashable data representation for a type. /// This variant is enabled when the type itself can be used. template typename std::enable_if::value, T>::type get_hashable_data(const T &value) { return value; } -/// \brief Helper to get the hashable data representation for a type. +/// Helper to get the hashable data representation for a type. /// This variant is enabled when we must first call hash_value and use the /// result as our data. template @@ -376,7 +376,7 @@ get_hashable_data(const T &value) { return hash_value(value); } -/// \brief Helper to store data from a value into a buffer and advance the +/// Helper to store data from a value into a buffer and advance the /// pointer into that buffer. /// /// This routine first checks whether there is enough space in the provided @@ -395,7 +395,7 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value, return true; } -/// \brief Implement the combining of integral values into a hash_code. +/// Implement the combining of integral values into a hash_code. /// /// This overload is selected when the value type of the iterator is /// integral. Rather than computing a hash_code for each object and then @@ -435,7 +435,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { return state.finalize(length); } -/// \brief Implement the combining of integral values into a hash_code. +/// Implement the combining of integral values into a hash_code. /// /// This overload is selected when the value type of the iterator is integral /// and when the input iterator is actually a pointer. Rather than computing @@ -470,7 +470,7 @@ hash_combine_range_impl(ValueT *first, ValueT *last) { } // namespace hashing -/// \brief Compute a hash_code for a sequence of values. +/// Compute a hash_code for a sequence of values. /// /// This hashes a sequence of values. It produces the same hash_code as /// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences @@ -486,7 +486,7 @@ hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) { namespace hashing { namespace detail { -/// \brief Helper class to manage the recursive combining of hash_combine +/// Helper class to manage the recursive combining of hash_combine /// arguments. /// /// This class exists to manage the state and various calls involved in the @@ -499,14 +499,14 @@ struct hash_combine_recursive_helper { const size_t seed; public: - /// \brief Construct a recursive hash combining helper. + /// Construct a recursive hash combining helper. /// /// This sets up the state for a recursive hash combine, including getting /// the seed and buffer setup. hash_combine_recursive_helper() : seed(get_execution_seed()) {} - /// \brief Combine one chunk of data into the current in-flight hash. + /// Combine one chunk of data into the current in-flight hash. /// /// This merges one chunk of data into the hash. First it tries to buffer /// the data. If the buffer is full, it hashes the buffer into its @@ -547,7 +547,7 @@ public: return buffer_ptr; } - /// \brief Recursive, variadic combining method. + /// Recursive, variadic combining method. /// /// This function recurses through each argument, combining that argument /// into a single hash. @@ -560,7 +560,7 @@ public: return combine(length, buffer_ptr, buffer_end, args...); } - /// \brief Base case for recursive, variadic combining. + /// Base case for recursive, variadic combining. /// /// The base case when combining arguments recursively is reached when all /// arguments have been handled. It flushes the remaining buffer and @@ -588,7 +588,7 @@ public: } // namespace detail } // namespace hashing -/// \brief Combine values into a single hash_code. +/// Combine values into a single hash_code. /// /// This routine accepts a varying number of arguments of any type. It will /// attempt to combine them into a single hash_code. For user-defined types it @@ -610,7 +610,7 @@ template hash_code hash_combine(const Ts &...args) { namespace hashing { namespace detail { -/// \brief Helper to hash the value of a single integer. +/// Helper to hash the value of a single integer. /// /// Overloads for smaller integer types are not provided to ensure consistent /// behavior in the presence of integral promotions. Essentially, diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index 60d63e09d4268a1f1cb630f66b087027bcfbe0fc..1f5e9813798d173a5023ea9219649ad4d09000bd 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -166,7 +166,7 @@ public: if (ownsAllocator()) delete &getAllocator(); } - ImmutableList concat(const T& Head, ImmutableList Tail) { + LLVM_NODISCARD ImmutableList concat(const T &Head, ImmutableList Tail) { // Profile the new list to see if it already exists in our cache. FoldingSetNodeID ID; void* InsertPos; @@ -188,7 +188,7 @@ public: return L; } - ImmutableList add(const T& D, ImmutableList L) { + LLVM_NODISCARD ImmutableList add(const T& D, ImmutableList L) { return concat(D, L); } diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index 10d1e1f0139baf43644cc86d7bf5f11ec48c26dc..cbc27ff17ccf363e85c28ec39fb5a64067358f97 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -114,12 +114,13 @@ public: ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); } - ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D) { + LLVM_NODISCARD ImmutableMap add(ImmutableMap Old, key_type_ref K, + data_type_ref D) { TreeTy *T = F.add(Old.Root, std::pair(K,D)); return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T); } - ImmutableMap remove(ImmutableMap Old, key_type_ref K) { + LLVM_NODISCARD ImmutableMap remove(ImmutableMap Old, key_type_ref K) { TreeTy *T = F.remove(Old.Root,K); return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T); } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 9d580c5a3d4165885502dc4559960da317261047..b1d5f4ac42e42887f711adef9fb7286b8087e9d5 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -1017,7 +1017,7 @@ public: /// of this operation is logarithmic in the size of the original set. /// The memory allocated to represent the set is released when the /// factory object that created the set is destroyed. - ImmutableSet add(ImmutableSet Old, value_type_ref V) { + LLVM_NODISCARD ImmutableSet add(ImmutableSet Old, value_type_ref V) { TreeTy *NewT = F.add(Old.Root, V); return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT); } @@ -1029,7 +1029,7 @@ public: /// of this operation is logarithmic in the size of the original set. /// The memory allocated to represent the set is released when the /// factory object that created the set is destroyed. - ImmutableSet remove(ImmutableSet Old, value_type_ref V) { + LLVM_NODISCARD ImmutableSet remove(ImmutableSet Old, value_type_ref V) { TreeTy *NewT = F.remove(Old.Root, V); return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT); } diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index f69f8fd1b1e0d2b1b1dacd582ea40e4be7ab64bc..47b4987f210aeb044cc53958b246a62498f9eaad 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -39,6 +39,10 @@ class MapVector { MapType Map; VectorType Vector; + static_assert( + std::is_integral::value, + "The mapped_type of the specified Map must be an integral type"); + public: using value_type = typename VectorType::value_type; using size_type = typename VectorType::size_type; @@ -93,9 +97,9 @@ public: } ValueT &operator[](const KeyT &Key) { - std::pair Pair = std::make_pair(Key, 0); + std::pair Pair = std::make_pair(Key, 0); std::pair Result = Map.insert(Pair); - unsigned &I = Result.first->second; + auto &I = Result.first->second; if (Result.second) { Vector.push_back(std::make_pair(Key, ValueT())); I = Vector.size() - 1; @@ -112,9 +116,9 @@ public: } std::pair insert(const std::pair &KV) { - std::pair Pair = std::make_pair(KV.first, 0); + std::pair Pair = std::make_pair(KV.first, 0); std::pair Result = Map.insert(Pair); - unsigned &I = Result.first->second; + auto &I = Result.first->second; if (Result.second) { Vector.push_back(std::make_pair(KV.first, KV.second)); I = Vector.size() - 1; @@ -125,9 +129,9 @@ public: std::pair insert(std::pair &&KV) { // Copy KV.first into the map, then move it into the vector. - std::pair Pair = std::make_pair(KV.first, 0); + std::pair Pair = std::make_pair(KV.first, 0); std::pair Result = Map.insert(Pair); - unsigned &I = Result.first->second; + auto &I = Result.first->second; if (Result.second) { Vector.push_back(std::move(KV)); I = Vector.size() - 1; @@ -153,14 +157,14 @@ public: (Vector.begin() + Pos->second); } - /// \brief Remove the last element from the vector. + /// Remove the last element from the vector. void pop_back() { typename MapType::iterator Pos = Map.find(Vector.back().first); Map.erase(Pos); Vector.pop_back(); } - /// \brief Remove the element given by Iterator. + /// Remove the element given by Iterator. /// /// Returns an iterator to the element following the one which was removed, /// which may be end(). @@ -183,7 +187,7 @@ public: return Next; } - /// \brief Remove all elements with the key value Key. + /// Remove all elements with the key value Key. /// /// Returns the number of elements removed. size_type erase(const KeyT &Key) { @@ -194,7 +198,7 @@ public: return 1; } - /// \brief Remove the elements that match the predicate. + /// Remove the elements that match the predicate. /// /// Erase all elements that match \c Pred in a single pass. Takes linear /// time. @@ -223,7 +227,7 @@ void MapVector::remove_if(Function Pred) { Vector.erase(O, Vector.end()); } -/// \brief A MapVector that performs no allocations if smaller than a certain +/// A MapVector that performs no allocations if smaller than a certain /// size. template struct SmallMapVector diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h index c7a99c61994ecbe29dc45f536c97ad8a39f6ad19..4b6bc1e005b5a9d006c948f056be00350d2be651 100644 --- a/include/llvm/ADT/None.h +++ b/include/llvm/ADT/None.h @@ -17,7 +17,7 @@ #define LLVM_ADT_NONE_H namespace llvm { -/// \brief A simple null object to allow implicit construction of Optional +/// A simple null object to allow implicit construction of Optional /// and similar types without having to spell out the specialization's name. // (constant value 1 in an attempt to workaround MSVC build issue... ) enum class NoneType { None = 1 }; diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h index 95adc2926813bed35b63db59c121303930391fd5..3d53c49536d065d88479b31e551fdf80ec22c2c6 100644 --- a/include/llvm/ADT/PackedVector.h +++ b/include/llvm/ADT/PackedVector.h @@ -65,7 +65,7 @@ protected: } }; -/// \brief Store a vector of values using a specific number of bits for each +/// Store a vector of values using a specific number of bits for each /// value. Both signed and unsigned types can be used, e.g /// @code /// PackedVector vec; diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index 784a58dc002f594e4fb5c98e5d6085a1a17cab43..ab1dc4613be03dae8d54b7746451f2d9d1479cdc 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -33,7 +33,7 @@ namespace llvm { -/// \brief Enumerate the SCCs of a directed graph in reverse topological order +/// Enumerate the SCCs of a directed graph in reverse topological order /// of the SCC DAG. /// /// This is implemented using Tarjan's DFS algorithm using an internal stack to @@ -104,7 +104,7 @@ public: } static scc_iterator end(const GraphT &) { return scc_iterator(); } - /// \brief Direct loop termination test which is more efficient than + /// Direct loop termination test which is more efficient than /// comparison with \c end(). bool isAtEnd() const { assert(!CurrentSCC.empty() || VisitStack.empty()); @@ -125,7 +125,7 @@ public: return CurrentSCC; } - /// \brief Test if the current SCC has a loop. + /// Test if the current SCC has a loop. /// /// If the SCC has more than one node, this is trivially true. If not, it may /// still contain a loop if the node has an edge back to itself. @@ -222,12 +222,12 @@ bool scc_iterator::hasLoop() const { return false; } -/// \brief Construct the begin iterator for a deduced graph type T. +/// Construct the begin iterator for a deduced graph type T. template scc_iterator scc_begin(const T &G) { return scc_iterator::begin(G); } -/// \brief Construct the end iterator for a deduced graph type T. +/// Construct the end iterator for a deduced graph type T. template scc_iterator scc_end(const T &G) { return scc_iterator::end(G); } diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 051b900ed4974f4524fa37ea532c70e2c1bdd663..bc47ff08373563107d0b02cd865ed09c2f35514c 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -271,60 +271,121 @@ auto reverse( /// auto R = make_filter_range(A, [](int N) { return N % 2 == 1; }); /// // R contains { 1, 3 }. /// \endcode -template -class filter_iterator +/// +/// Note: filter_iterator_base implements support for forward iteration. +/// filter_iterator_impl exists to provide support for bidirectional iteration, +/// conditional on whether the wrapped iterator supports it. +template +class filter_iterator_base : public iterator_adaptor_base< - filter_iterator, WrappedIteratorT, + filter_iterator_base, + WrappedIteratorT, typename std::common_type< - std::forward_iterator_tag, - typename std::iterator_traits< - WrappedIteratorT>::iterator_category>::type> { + IterTag, typename std::iterator_traits< + WrappedIteratorT>::iterator_category>::type> { using BaseT = iterator_adaptor_base< - filter_iterator, WrappedIteratorT, + filter_iterator_base, + WrappedIteratorT, typename std::common_type< - std::forward_iterator_tag, - typename std::iterator_traits::iterator_category>:: - type>; + IterTag, typename std::iterator_traits< + WrappedIteratorT>::iterator_category>::type>; - struct PayloadType { - WrappedIteratorT End; - PredicateT Pred; - }; - - Optional Payload; +protected: + WrappedIteratorT End; + PredicateT Pred; void findNextValid() { - assert(Payload && "Payload should be engaged when findNextValid is called"); - while (this->I != Payload->End && !Payload->Pred(*this->I)) + while (this->I != End && !Pred(*this->I)) BaseT::operator++(); } - // Construct the begin iterator. The begin iterator requires to know where end - // is, so that it can properly stop when it hits end. - filter_iterator(WrappedIteratorT Begin, WrappedIteratorT End, PredicateT Pred) - : BaseT(std::move(Begin)), - Payload(PayloadType{std::move(End), std::move(Pred)}) { + // Construct the iterator. The begin iterator needs to know where the end + // is, so that it can properly stop when it gets there. The end iterator only + // needs the predicate to support bidirectional iteration. + filter_iterator_base(WrappedIteratorT Begin, WrappedIteratorT End, + PredicateT Pred) + : BaseT(Begin), End(End), Pred(Pred) { findNextValid(); } - // Construct the end iterator. It's not incrementable, so Payload doesn't - // have to be engaged. - filter_iterator(WrappedIteratorT End) : BaseT(End) {} - public: using BaseT::operator++; - filter_iterator &operator++() { + filter_iterator_base &operator++() { BaseT::operator++(); findNextValid(); return *this; } +}; + +/// Specialization of filter_iterator_base for forward iteration only. +template +class filter_iterator_impl + : public filter_iterator_base { + using BaseT = filter_iterator_base; + +public: + filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End, + PredicateT Pred) + : BaseT(Begin, End, Pred) {} +}; + +/// Specialization of filter_iterator_base for bidirectional iteration. +template +class filter_iterator_impl + : public filter_iterator_base { + using BaseT = filter_iterator_base; + void findPrevValid() { + while (!this->Pred(*this->I)) + BaseT::operator--(); + } + +public: + using BaseT::operator--; + + filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End, + PredicateT Pred) + : BaseT(Begin, End, Pred) {} + + filter_iterator_impl &operator--() { + BaseT::operator--(); + findPrevValid(); + return *this; + } +}; + +namespace detail { + +template struct fwd_or_bidi_tag_impl { + using type = std::forward_iterator_tag; +}; - template - friend iterator_range, PT>> - make_filter_range(RT &&, PT); +template <> struct fwd_or_bidi_tag_impl { + using type = std::bidirectional_iterator_tag; }; +/// Helper which sets its type member to forward_iterator_tag if the category +/// of \p IterT does not derive from bidirectional_iterator_tag, and to +/// bidirectional_iterator_tag otherwise. +template struct fwd_or_bidi_tag { + using type = typename fwd_or_bidi_tag_impl::iterator_category>::value>::type; +}; + +} // namespace detail + +/// Defines filter_iterator to a suitable specialization of +/// filter_iterator_impl, based on the underlying iterator's category. +template +using filter_iterator = filter_iterator_impl< + WrappedIteratorT, PredicateT, + typename detail::fwd_or_bidi_tag::type>; + /// Convenience function that takes a range of elements and a predicate, /// and return a new filter_iterator range. /// @@ -337,10 +398,11 @@ iterator_range, PredicateT>> make_filter_range(RangeT &&Range, PredicateT Pred) { using FilterIteratorT = filter_iterator, PredicateT>; - return make_range(FilterIteratorT(std::begin(std::forward(Range)), - std::end(std::forward(Range)), - std::move(Pred)), - FilterIteratorT(std::end(std::forward(Range)))); + return make_range( + FilterIteratorT(std::begin(std::forward(Range)), + std::end(std::forward(Range)), Pred), + FilterIteratorT(std::end(std::forward(Range)), + std::end(std::forward(Range)), Pred)); } // forward declarations required by zip_shortest/zip_first @@ -649,7 +711,7 @@ detail::concat_range concat(RangeTs &&... Ranges) { // Extra additions to //===----------------------------------------------------------------------===// -/// \brief Function object to check whether the first component of a std::pair +/// Function object to check whether the first component of a std::pair /// compares less than the first component of another std::pair. struct less_first { template bool operator()(const T &lhs, const T &rhs) const { @@ -657,7 +719,7 @@ struct less_first { } }; -/// \brief Function object to check whether the second component of a std::pair +/// Function object to check whether the second component of a std::pair /// compares less than the second component of another std::pair. struct less_second { template bool operator()(const T &lhs, const T &rhs) const { @@ -667,14 +729,14 @@ struct less_second { // A subset of N3658. More stuff can be added as-needed. -/// \brief Represents a compile-time sequence of integers. +/// Represents a compile-time sequence of integers. template struct integer_sequence { using value_type = T; static constexpr size_t size() { return sizeof...(I); } }; -/// \brief Alias for the common case of a sequence of size_ts. +/// Alias for the common case of a sequence of size_ts. template struct index_sequence : integer_sequence {}; @@ -683,7 +745,7 @@ struct build_index_impl : build_index_impl {}; template struct build_index_impl<0, I...> : index_sequence {}; -/// \brief Creates a compile-time integer sequence for a parameter pack. +/// Creates a compile-time integer sequence for a parameter pack. template struct index_sequence_for : build_index_impl {}; @@ -692,7 +754,7 @@ struct index_sequence_for : build_index_impl {}; template struct rank : rank {}; template <> struct rank<0> {}; -/// \brief traits class for checking whether type T is one of any of the given +/// traits class for checking whether type T is one of any of the given /// types in the variadic list. template struct is_one_of { static const bool value = false; @@ -704,7 +766,7 @@ struct is_one_of { std::is_same::value || is_one_of::value; }; -/// \brief traits class for checking whether type T is a base class for all +/// traits class for checking whether type T is a base class for all /// the given types in the variadic list. template struct are_base_of { static const bool value = true; @@ -943,7 +1005,7 @@ auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) { return std::lower_bound(adl_begin(Range), adl_end(Range), I); } -/// \brief Given a range of type R, iterate the entire range and return a +/// Given a range of type R, iterate the entire range and return a /// SmallVector with elements of the vector. This is useful, for example, /// when you want to iterate a range and then sort the results. template @@ -964,13 +1026,25 @@ void erase_if(Container &C, UnaryPredicate P) { C.erase(remove_if(C, P), C.end()); } +/// Get the size of a range. This is a wrapper function around std::distance +/// which is only enabled when the operation is O(1). +template +auto size(R &&Range, typename std::enable_if< + std::is_same::iterator_category, + std::random_access_iterator_tag>::value, + void>::type * = nullptr) + -> decltype(std::distance(Range.begin(), Range.end())) { + return std::distance(Range.begin(), Range.end()); +} + //===----------------------------------------------------------------------===// // Extra additions to //===----------------------------------------------------------------------===// // Implement make_unique according to N3656. -/// \brief Constructs a `new T()` with the given args and returns a +/// Constructs a `new T()` with the given args and returns a /// `unique_ptr` which owns the object. /// /// Example: @@ -983,7 +1057,7 @@ make_unique(Args &&... args) { return std::unique_ptr(new T(std::forward(args)...)); } -/// \brief Constructs a `new T[n]` with the given args and returns a +/// Constructs a `new T[n]` with the given args and returns a /// `unique_ptr` which owns the object. /// /// \param n size of the new array. diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index 04ed52fc543f35d73cdc1dae32f3b8575ee05c8e..3d67810413209f406221a7a5900e8a2a62833e86 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -31,7 +31,7 @@ namespace llvm { -/// \brief A vector that has set insertion semantics. +/// A vector that has set insertion semantics. /// /// This adapter class provides a way to keep a set of things that also has the /// property of a deterministic iteration order. The order of iteration is the @@ -52,10 +52,10 @@ public: using const_reverse_iterator = typename vector_type::const_reverse_iterator; using size_type = typename vector_type::size_type; - /// \brief Construct an empty SetVector + /// Construct an empty SetVector SetVector() = default; - /// \brief Initialize a SetVector with a range of elements + /// Initialize a SetVector with a range of elements template SetVector(It Start, It End) { insert(Start, End); @@ -69,75 +69,75 @@ public: return std::move(vector_); } - /// \brief Determine if the SetVector is empty or not. + /// Determine if the SetVector is empty or not. bool empty() const { return vector_.empty(); } - /// \brief Determine the number of elements in the SetVector. + /// Determine the number of elements in the SetVector. size_type size() const { return vector_.size(); } - /// \brief Get an iterator to the beginning of the SetVector. + /// Get an iterator to the beginning of the SetVector. iterator begin() { return vector_.begin(); } - /// \brief Get a const_iterator to the beginning of the SetVector. + /// Get a const_iterator to the beginning of the SetVector. const_iterator begin() const { return vector_.begin(); } - /// \brief Get an iterator to the end of the SetVector. + /// Get an iterator to the end of the SetVector. iterator end() { return vector_.end(); } - /// \brief Get a const_iterator to the end of the SetVector. + /// Get a const_iterator to the end of the SetVector. const_iterator end() const { return vector_.end(); } - /// \brief Get an reverse_iterator to the end of the SetVector. + /// Get an reverse_iterator to the end of the SetVector. reverse_iterator rbegin() { return vector_.rbegin(); } - /// \brief Get a const_reverse_iterator to the end of the SetVector. + /// Get a const_reverse_iterator to the end of the SetVector. const_reverse_iterator rbegin() const { return vector_.rbegin(); } - /// \brief Get a reverse_iterator to the beginning of the SetVector. + /// Get a reverse_iterator to the beginning of the SetVector. reverse_iterator rend() { return vector_.rend(); } - /// \brief Get a const_reverse_iterator to the beginning of the SetVector. + /// Get a const_reverse_iterator to the beginning of the SetVector. const_reverse_iterator rend() const { return vector_.rend(); } - /// \brief Return the first element of the SetVector. + /// Return the first element of the SetVector. const T &front() const { assert(!empty() && "Cannot call front() on empty SetVector!"); return vector_.front(); } - /// \brief Return the last element of the SetVector. + /// Return the last element of the SetVector. const T &back() const { assert(!empty() && "Cannot call back() on empty SetVector!"); return vector_.back(); } - /// \brief Index into the SetVector. + /// Index into the SetVector. const_reference operator[](size_type n) const { assert(n < vector_.size() && "SetVector access out of range!"); return vector_[n]; } - /// \brief Insert a new element into the SetVector. + /// Insert a new element into the SetVector. /// \returns true if the element was inserted into the SetVector. bool insert(const value_type &X) { bool result = set_.insert(X).second; @@ -146,7 +146,7 @@ public: return result; } - /// \brief Insert a range of elements into the SetVector. + /// Insert a range of elements into the SetVector. template void insert(It Start, It End) { for (; Start != End; ++Start) @@ -154,7 +154,7 @@ public: vector_.push_back(*Start); } - /// \brief Remove an item from the set vector. + /// Remove an item from the set vector. bool remove(const value_type& X) { if (set_.erase(X)) { typename vector_type::iterator I = find(vector_, X); @@ -183,7 +183,7 @@ public: return vector_.erase(NI); } - /// \brief Remove items from the set vector based on a predicate function. + /// Remove items from the set vector based on a predicate function. /// /// This is intended to be equivalent to the following code, if we could /// write it: @@ -206,19 +206,19 @@ public: return true; } - /// \brief Count the number of elements of a given key in the SetVector. + /// Count the number of elements of a given key in the SetVector. /// \returns 0 if the element is not in the SetVector, 1 if it is. size_type count(const key_type &key) const { return set_.count(key); } - /// \brief Completely clear the SetVector + /// Completely clear the SetVector void clear() { set_.clear(); vector_.clear(); } - /// \brief Remove the last element of the SetVector. + /// Remove the last element of the SetVector. void pop_back() { assert(!empty() && "Cannot remove an element from an empty SetVector!"); set_.erase(back()); @@ -239,7 +239,7 @@ public: return vector_ != that.vector_; } - /// \brief Compute This := This u S, return whether 'This' changed. + /// Compute This := This u S, return whether 'This' changed. /// TODO: We should be able to use set_union from SetOperations.h, but /// SetVector interface is inconsistent with DenseSet. template @@ -254,7 +254,7 @@ public: return Changed; } - /// \brief Compute This := This - B + /// Compute This := This - B /// TODO: We should be able to use set_subtract from SetOperations.h, but /// SetVector interface is inconsistent with DenseSet. template @@ -265,7 +265,7 @@ public: } private: - /// \brief A wrapper predicate designed for use with std::remove_if. + /// A wrapper predicate designed for use with std::remove_if. /// /// This predicate wraps a predicate suitable for use with std::remove_if to /// call set_.erase(x) on each element which is slated for removal. @@ -292,7 +292,7 @@ private: vector_type vector_; ///< The vector. }; -/// \brief A SetVector that performs no allocations if smaller than +/// A SetVector that performs no allocations if smaller than /// a certain size. template class SmallSetVector @@ -300,7 +300,7 @@ class SmallSetVector public: SmallSetVector() = default; - /// \brief Initialize a SmallSetVector with a range of elements + /// Initialize a SmallSetVector with a range of elements template SmallSetVector(It Start, It End) { this->insert(Start, End); diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 78ea613af693b25c334218014c05353b81b8d409..db08e40257ba5d47e30ccce463b6b5088b131310 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -335,7 +335,7 @@ struct RoundUpToPowerOfTwo { enum { Val = RoundUpToPowerOfTwoH::Val }; }; -/// \brief A templated base class for \c SmallPtrSet which provides the +/// A templated base class for \c SmallPtrSet which provides the /// typesafe interface that is common across all small sizes. /// /// This is particularly useful for passing around between interface boundaries diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 3a0899708c9eb523a44b12a0b583b387a3e40929..90c2eefceb6c0ac61756d594a07238783a1726a5 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -169,19 +169,19 @@ protected: #define STATISTIC(VARNAME, DESC) \ static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, {false}} -/// \brief Enable the collection and printing of statistics. +/// Enable the collection and printing of statistics. void EnableStatistics(bool PrintOnExit = true); -/// \brief Check if statistics are enabled. +/// Check if statistics are enabled. bool AreStatisticsEnabled(); -/// \brief Return a file stream to print our output on. +/// Return a file stream to print our output on. std::unique_ptr CreateInfoOutputFile(); -/// \brief Print statistics to the file returned by CreateInfoOutputFile(). +/// Print statistics to the file returned by CreateInfoOutputFile(). void PrintStatistics(); -/// \brief Print statistics to the given output stream. +/// Print statistics to the given output stream. void PrintStatistics(raw_ostream &OS); /// Print statistics in JSON format. This does include all global timers (\see @@ -190,7 +190,7 @@ void PrintStatistics(raw_ostream &OS); /// PrintStatisticsJSON(). void PrintStatisticsJSON(raw_ostream &OS); -/// \brief Get the statistics. This can be used to look up the value of +/// Get the statistics. This can be used to look up the value of /// statistics without needing to parse JSON. /// /// This function does not prevent statistics being updated by other threads @@ -199,7 +199,7 @@ void PrintStatisticsJSON(raw_ostream &OS); /// completes. const std::vector> GetStatistics(); -/// \brief Reset the statistics. This can be used to zero and de-register the +/// Reset the statistics. This can be used to zero and de-register the /// statistics in order to measure a compilation. /// /// When this function begins to call destructors prior to returning, all diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 45f667797b37f17e8cfd344db5bd535eef08b858..21a1bbcfad262a4744662c0bb1532438aa796819 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -157,7 +157,7 @@ inline std::string fromHex(StringRef Input) { return Output; } -/// \brief Convert the string \p S to an integer of the specified type using +/// Convert the string \p S to an integer of the specified type using /// the radix \p Base. If \p Base is 0, auto-detects the radix. /// Returns true if the number was successfully converted, false otherwise. template bool to_integer(StringRef S, N &Num, unsigned Base = 0) { @@ -251,9 +251,13 @@ inline StringRef getOrdinalSuffix(unsigned Val) { } } -/// PrintEscapedString - Print each character of the specified string, escaping -/// it if it is not printable or if it is an escape char. -void PrintEscapedString(StringRef Name, raw_ostream &Out); +/// Print each character of the specified string, escaping it if it is not +/// printable or if it is an escape char. +void printEscapedString(StringRef Name, raw_ostream &Out); + +/// Print each character of the specified string, escaping HTML special +/// characters. +void printHTMLEscaped(StringRef String, raw_ostream &Out); /// printLowerCase - Print each character as lowercase if it is uppercase. void printLowerCase(StringRef String, raw_ostream &Out); diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 3d2417aceadded5042951499d75cbfef7242c335..2704ab00b1048bf8826730bfa67df7dbb22bac5f 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -201,7 +201,7 @@ namespace llvm { LLVM_NODISCARD int compare_numeric(StringRef RHS) const; - /// \brief Determine the edit distance between this string and another + /// Determine the edit distance between this string and another /// string. /// /// \param Other the string to compare this string against. @@ -912,7 +912,7 @@ namespace llvm { /// @} - /// \brief Compute a hash_code for a StringRef. + /// Compute a hash_code for a StringRef. LLVM_NODISCARD hash_code hash_value(StringRef S); diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index 9e073030d043a7101e46bcbd93db4da331b8f9a5..b7860b98ce5dd4d63de96849adb2118267027ced 100644 --- a/include/llvm/ADT/StringSwitch.h +++ b/include/llvm/ADT/StringSwitch.h @@ -20,7 +20,7 @@ namespace llvm { -/// \brief A switch()-like statement whose cases are string literals. +/// A switch()-like statement whose cases are string literals. /// /// The StringSwitch class is a simple form of a switch() statement that /// determines whether the given string matches one of the given string @@ -41,10 +41,10 @@ namespace llvm { /// \endcode template class StringSwitch { - /// \brief The string we are matching. + /// The string we are matching. const StringRef Str; - /// \brief The pointer to the result of this switch statement, once known, + /// The pointer to the result of this switch statement, once known, /// null before that. Optional Result; diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h index b17fb2392bafc84f4a8bc81a1227fb88d5f9176b..c86bedd0768707bfc29734d1c4005577366c99e5 100644 --- a/include/llvm/ADT/UniqueVector.h +++ b/include/llvm/ADT/UniqueVector.h @@ -72,16 +72,16 @@ public: return Vector[ID - 1]; } - /// \brief Return an iterator to the start of the vector. + /// Return an iterator to the start of the vector. iterator begin() { return Vector.begin(); } - /// \brief Return an iterator to the start of the vector. + /// Return an iterator to the start of the vector. const_iterator begin() const { return Vector.begin(); } - /// \brief Return an iterator to the end of the vector. + /// Return an iterator to the end of the vector. iterator end() { return Vector.end(); } - /// \brief Return an iterator to the end of the vector. + /// Return an iterator to the end of the vector. const_iterator end() const { return Vector.end(); } /// size - Returns the number of entries in the vector. diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h index 403130c623ebada3c807bad9367509d617825ae6..9028abe4c72c91e060f0d2f393a439dc59d3144d 100644 --- a/include/llvm/ADT/VariadicFunction.h +++ b/include/llvm/ADT/VariadicFunction.h @@ -53,7 +53,7 @@ namespace llvm { #define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30 #define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31 -/// \brief Class which can simulate a type-safe variadic function. +/// Class which can simulate a type-safe variadic function. /// /// The VariadicFunction class template makes it easy to define /// type-safe variadic functions where all arguments have the same diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h index 06a01b18a9fbc92139333c371bd11ea533ea6c5f..b2e8ec5c3f6debc85f88b3c7938f6a89d7d749a3 100644 --- a/include/llvm/ADT/edit_distance.h +++ b/include/llvm/ADT/edit_distance.h @@ -22,7 +22,7 @@ namespace llvm { -/// \brief Determine the edit distance between two sequences. +/// Determine the edit distance between two sequences. /// /// \param FromArray the first sequence to compare. /// diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index a788f811e4c68538b0392e47111db7ba3fd69f99..00bb6d528175acba972d463f17d59bc68ece8fd4 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -84,21 +84,11 @@ template struct ilist_node_traits : ilist_alloc_traits, ilist_callback_traits {}; -/// Default template traits for intrusive list. -/// -/// By inheriting from this, you can easily use default implementations for all -/// common operations. -/// -/// TODO: Remove this customization point. Specializing ilist_traits is -/// already fully general. -template -struct ilist_default_traits : public ilist_node_traits {}; - /// Template traits for intrusive list. /// /// Customize callbacks and allocation semantics. template -struct ilist_traits : public ilist_default_traits {}; +struct ilist_traits : public ilist_node_traits {}; /// Const traits should never be instantiated. template struct ilist_traits {}; @@ -178,9 +168,6 @@ template class iplist_impl : public TraitsT, IntrusiveListT { typedef IntrusiveListT base_list_type; -protected: - typedef iplist_impl iplist_impl_type; - public: typedef typename base_list_type::pointer pointer; typedef typename base_list_type::const_pointer const_pointer; @@ -369,26 +356,26 @@ public: using base_list_type::sort; - /// \brief Get the previous node, or \c nullptr for the list head. + /// Get the previous node, or \c nullptr for the list head. pointer getPrevNode(reference N) const { auto I = N.getIterator(); if (I == begin()) return nullptr; return &*std::prev(I); } - /// \brief Get the previous node, or \c nullptr for the list head. + /// Get the previous node, or \c nullptr for the list head. const_pointer getPrevNode(const_reference N) const { return getPrevNode(const_cast(N)); } - /// \brief Get the next node, or \c nullptr for the list tail. + /// Get the next node, or \c nullptr for the list tail. pointer getNextNode(reference N) const { auto Next = std::next(N.getIterator()); if (Next == end()) return nullptr; return &*Next; } - /// \brief Get the next node, or \c nullptr for the list tail. + /// Get the next node, or \c nullptr for the list tail. const_pointer getNextNode(const_reference N) const { return getNextNode(const_cast(N)); } @@ -402,7 +389,7 @@ public: template class iplist : public iplist_impl, ilist_traits> { - typedef typename iplist::iplist_impl_type iplist_impl_type; + using iplist_impl_type = typename iplist::iplist_impl; public: iplist() = default; diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h index 3362611697cb0e92bb3fa4bcc1275f8f06749f5b..dd0e6b4ec2b996e3d68b24e09399e34c4f29166f 100644 --- a/include/llvm/ADT/ilist_node.h +++ b/include/llvm/ADT/ilist_node.h @@ -271,7 +271,7 @@ private: public: /// @name Adjacent Node Accessors /// @{ - /// \brief Get the previous node, or \c nullptr for the list head. + /// Get the previous node, or \c nullptr for the list head. NodeTy *getPrevNode() { // Should be separated to a reused function, but then we couldn't use auto // (and would need the type of the list). @@ -280,12 +280,12 @@ public: return List.getPrevNode(*static_cast(this)); } - /// \brief Get the previous node, or \c nullptr for the list head. + /// Get the previous node, or \c nullptr for the list head. const NodeTy *getPrevNode() const { return const_cast(this)->getPrevNode(); } - /// \brief Get the next node, or \c nullptr for the list tail. + /// Get the next node, or \c nullptr for the list tail. NodeTy *getNextNode() { // Should be separated to a reused function, but then we couldn't use auto // (and would need the type of the list). @@ -294,7 +294,7 @@ public: return List.getNextNode(*static_cast(this)); } - /// \brief Get the next node, or \c nullptr for the list tail. + /// Get the next node, or \c nullptr for the list tail. const NodeTy *getNextNode() const { return const_cast(this)->getNextNode(); } diff --git a/include/llvm/ADT/ilist_node_options.h b/include/llvm/ADT/ilist_node_options.h index c33df1eeb8199f84733872ff40f828b1fd4f4121..7ff4005f675757c758e86bd89e3f7b17d444679d 100644 --- a/include/llvm/ADT/ilist_node_options.h +++ b/include/llvm/ADT/ilist_node_options.h @@ -11,7 +11,6 @@ #define LLVM_ADT_ILIST_NODE_OPTIONS_H #include "llvm/Config/abi-breaking.h" -#include "llvm/Config/llvm-config.h" #include diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h index 711f8f2216209e56c5d5908cbe2da9984784c74e..781dd1ec3ba0e1adcc7f0d6d8f6603ba9410574a 100644 --- a/include/llvm/ADT/iterator.h +++ b/include/llvm/ADT/iterator.h @@ -19,7 +19,7 @@ namespace llvm { -/// \brief CRTP base class which implements the entire standard iterator facade +/// CRTP base class which implements the entire standard iterator facade /// in terms of a minimal subset of the interface. /// /// Use this when it is reasonable to implement most of the iterator @@ -183,7 +183,7 @@ public: } }; -/// \brief CRTP base class for adapting an iterator to a different type. +/// CRTP base class for adapting an iterator to a different type. /// /// This class can be used through CRTP to adapt one iterator into another. /// Typically this is done through providing in the derived class a custom \c @@ -274,7 +274,7 @@ public: ReferenceT operator*() const { return *I; } }; -/// \brief An iterator type that allows iterating over the pointees via some +/// An iterator type that allows iterating over the pointees via some /// other iterator. /// /// The typical usage of this is to expose a type that iterates over Ts, but diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h index 3cbf6198eb60153d58c23f09ea17ecdc14190e6d..b8fe50641cb484d8e7c5c94560965f4815e5c06d 100644 --- a/include/llvm/ADT/iterator_range.h +++ b/include/llvm/ADT/iterator_range.h @@ -24,7 +24,7 @@ namespace llvm { -/// \brief A range adaptor for a pair of iterators. +/// A range adaptor for a pair of iterators. /// /// This just wraps two iterators into a range-compatible interface. Nothing /// fancy at all. @@ -47,7 +47,7 @@ public: IteratorT end() const { return end_iterator; } }; -/// \brief Convenience function for iterating over sub-ranges. +/// Convenience function for iterating over sub-ranges. /// /// This provides a bit of syntactic sugar to make using sub-ranges /// in for loops a bit easier. Analogous to std::make_pair(). diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index ec4a90ce7f97d72f9ce8c0089cfe889e8066599e..e018ed6ee8a0cb197bb7a0dc4a64db1ea6dfb0bd 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -325,8 +325,8 @@ public: AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); /// A convenience wrapper around the primary \c alias interface. - AliasResult alias(const Value *V1, uint64_t V1Size, const Value *V2, - uint64_t V2Size) { + AliasResult alias(const Value *V1, LocationSize V1Size, const Value *V2, + LocationSize V2Size) { return alias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size)); } @@ -343,8 +343,8 @@ public: } /// A convenience wrapper around the \c isNoAlias helper interface. - bool isNoAlias(const Value *V1, uint64_t V1Size, const Value *V2, - uint64_t V2Size) { + bool isNoAlias(const Value *V1, LocationSize V1Size, const Value *V2, + LocationSize V2Size) { return isNoAlias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size)); } @@ -501,7 +501,7 @@ public: /// getModRefInfo (for call sites) - A convenience wrapper. ModRefInfo getModRefInfo(ImmutableCallSite CS, const Value *P, - uint64_t Size) { + LocationSize Size) { return getModRefInfo(CS, MemoryLocation(P, Size)); } @@ -512,7 +512,8 @@ public: } /// getModRefInfo (for calls) - A convenience wrapper. - ModRefInfo getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const CallInst *C, const Value *P, + LocationSize Size) { return getModRefInfo(C, MemoryLocation(P, Size)); } @@ -523,7 +524,8 @@ public: } /// getModRefInfo (for invokes) - A convenience wrapper. - ModRefInfo getModRefInfo(const InvokeInst *I, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const InvokeInst *I, const Value *P, + LocationSize Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } @@ -532,7 +534,8 @@ public: ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc); /// getModRefInfo (for loads) - A convenience wrapper. - ModRefInfo getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const LoadInst *L, const Value *P, + LocationSize Size) { return getModRefInfo(L, MemoryLocation(P, Size)); } @@ -541,7 +544,8 @@ public: ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc); /// getModRefInfo (for stores) - A convenience wrapper. - ModRefInfo getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const StoreInst *S, const Value *P, + LocationSize Size) { return getModRefInfo(S, MemoryLocation(P, Size)); } @@ -550,7 +554,8 @@ public: ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc); /// getModRefInfo (for fences) - A convenience wrapper. - ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, + LocationSize Size) { return getModRefInfo(S, MemoryLocation(P, Size)); } @@ -580,7 +585,8 @@ public: ModRefInfo getModRefInfo(const VAArgInst *I, const MemoryLocation &Loc); /// getModRefInfo (for va_args) - A convenience wrapper. - ModRefInfo getModRefInfo(const VAArgInst *I, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const VAArgInst *I, const Value *P, + LocationSize Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } @@ -590,7 +596,7 @@ public: /// getModRefInfo (for catchpads) - A convenience wrapper. ModRefInfo getModRefInfo(const CatchPadInst *I, const Value *P, - uint64_t Size) { + LocationSize Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } @@ -600,7 +606,7 @@ public: /// getModRefInfo (for catchrets) - A convenience wrapper. ModRefInfo getModRefInfo(const CatchReturnInst *I, const Value *P, - uint64_t Size) { + LocationSize Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } @@ -646,7 +652,7 @@ public: /// A convenience wrapper for constructing the memory location. ModRefInfo getModRefInfo(const Instruction *I, const Value *P, - uint64_t Size) { + LocationSize Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } @@ -659,7 +665,7 @@ public: /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); - /// \brief Return information about whether a particular call site modifies + /// Return information about whether a particular call site modifies /// or reads the specified memory location \p MemLoc before instruction \p I /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up /// instruction ordering queries inside the BasicBlock containing \p I. @@ -669,9 +675,9 @@ public: const MemoryLocation &MemLoc, DominatorTree *DT, OrderedBasicBlock *OBB = nullptr); - /// \brief A convenience wrapper to synthesize a memory location. + /// A convenience wrapper to synthesize a memory location. ModRefInfo callCapturesBefore(const Instruction *I, const Value *P, - uint64_t Size, DominatorTree *DT, + LocationSize Size, DominatorTree *DT, OrderedBasicBlock *OBB = nullptr) { return callCapturesBefore(I, MemoryLocation(P, Size), DT, OBB); } @@ -687,7 +693,7 @@ public: /// A convenience wrapper synthesizing a memory location. bool canBasicBlockModify(const BasicBlock &BB, const Value *P, - uint64_t Size) { + LocationSize Size) { return canBasicBlockModify(BB, MemoryLocation(P, Size)); } @@ -702,7 +708,7 @@ public: /// A convenience wrapper synthesizing a memory location. bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, - const Value *Ptr, uint64_t Size, + const Value *Ptr, LocationSize Size, const ModRefInfo Mode) { return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode); } diff --git a/include/llvm/Analysis/AliasAnalysisEvaluator.h b/include/llvm/Analysis/AliasAnalysisEvaluator.h index cd2f631a01f42dfa7d3f4dcfcf93a443ad006ad0..0941814a56c3410dc92e01a1735e3ecc8425b123 100644 --- a/include/llvm/Analysis/AliasAnalysisEvaluator.h +++ b/include/llvm/Analysis/AliasAnalysisEvaluator.h @@ -56,7 +56,7 @@ public: } ~AAEvaluator(); - /// \brief Run the pass over the function. + /// Run the pass over the function. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); private: diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 7da3ebabb8a3e7a8b11a1ac236d16fc404574271..c9680ff40d1eea753ec3a97054d5d24aaae6c1cc 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -37,8 +37,8 @@ namespace llvm { class AliasSetTracker; class BasicBlock; class LoadInst; -class MemSetInst; -class MemTransferInst; +class AnyMemSetInst; +class AnyMemTransferInst; class raw_ostream; class StoreInst; class VAArgInst; @@ -52,7 +52,7 @@ class AliasSet : public ilist_node { PointerRec **PrevInList = nullptr; PointerRec *NextInList = nullptr; AliasSet *AS = nullptr; - uint64_t Size = 0; + LocationSize Size = 0; AAMDNodes AAInfo; public: @@ -69,7 +69,7 @@ class AliasSet : public ilist_node { return &NextInList; } - bool updateSizeAndAAInfo(uint64_t NewSize, const AAMDNodes &NewAAInfo) { + bool updateSizeAndAAInfo(LocationSize NewSize, const AAMDNodes &NewAAInfo) { bool SizeChanged = false; if (NewSize > Size) { Size = NewSize; @@ -91,7 +91,7 @@ class AliasSet : public ilist_node { return SizeChanged; } - uint64_t getSize() const { return Size; } + LocationSize getSize() const { return Size; } /// Return the AAInfo, or null if there is no information or conflicting /// information. @@ -247,7 +247,7 @@ public: value_type *operator->() const { return &operator*(); } Value *getPointer() const { return CurNode->getValue(); } - uint64_t getSize() const { return CurNode->getSize(); } + LocationSize getSize() const { return CurNode->getSize(); } AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); } iterator& operator++() { // Preincrement @@ -287,9 +287,8 @@ private: void removeFromTracker(AliasSetTracker &AST); - void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size, - const AAMDNodes &AAInfo, - bool KnownMustAlias = false); + void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size, + const AAMDNodes &AAInfo, bool KnownMustAlias = false); void addUnknownInst(Instruction *I, AliasAnalysis &AA); void removeUnknownInst(AliasSetTracker &AST, Instruction *I) { @@ -309,8 +308,8 @@ private: public: /// Return true if the specified pointer "may" (or must) alias one of the /// members in the set. - bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo, - AliasAnalysis &AA) const; + bool aliasesPointer(const Value *Ptr, LocationSize Size, + const AAMDNodes &AAInfo, AliasAnalysis &AA) const; bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const; }; @@ -364,12 +363,12 @@ public: /// These methods return true if inserting the instruction resulted in the /// addition of a new alias set (i.e., the pointer did not alias anything). /// - void add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo); // Add a loc. + void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo); // Add a loc void add(LoadInst *LI); void add(StoreInst *SI); void add(VAArgInst *VAAI); - void add(MemSetInst *MSI); - void add(MemTransferInst *MTI); + void add(AnyMemSetInst *MSI); + void add(AnyMemTransferInst *MTI); void add(Instruction *I); // Dispatch to one of the other add methods... void add(BasicBlock &BB); // Add all instructions in basic block void add(const AliasSetTracker &AST); // Add alias relations from another AST @@ -384,12 +383,12 @@ public: /// argument is non-null, this method sets the value to true if a new alias /// set is created to contain the pointer (because the pointer didn't alias /// anything). - AliasSet &getAliasSetForPointer(Value *P, uint64_t Size, + AliasSet &getAliasSetForPointer(Value *P, LocationSize Size, const AAMDNodes &AAInfo); /// Return the alias set containing the location specified if one exists, /// otherwise return null. - AliasSet *getAliasSetForPointerIfExists(const Value *P, uint64_t Size, + AliasSet *getAliasSetForPointerIfExists(const Value *P, LocationSize Size, const AAMDNodes &AAInfo) { return mergeAliasSetsForPointer(P, Size, AAInfo); } @@ -446,9 +445,9 @@ private: return *Entry; } - AliasSet &addPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo, + AliasSet &addPointer(Value *P, LocationSize Size, const AAMDNodes &AAInfo, AliasSet::AccessLattice E); - AliasSet *mergeAliasSetsForPointer(const Value *Ptr, uint64_t Size, + AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo); /// Merge all alias sets into a single set that is considered to alias any diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h index c965e62a021642b86bdf6b5f8032b927aa564148..46538b1fa86f124a561ff90d8c2547fb70e14980 100644 --- a/include/llvm/Analysis/AssumptionCache.h +++ b/include/llvm/Analysis/AssumptionCache.h @@ -32,20 +32,20 @@ class Function; class raw_ostream; class Value; -/// \brief A cache of @llvm.assume calls within a function. +/// A cache of \@llvm.assume calls within a function. /// /// This cache provides fast lookup of assumptions within a function by caching /// them and amortizing the cost of scanning for them across all queries. Passes /// that create new assumptions are required to call registerAssumption() to -/// register any new @llvm.assume calls that they create. Deletions of -/// @llvm.assume calls do not require special handling. +/// register any new \@llvm.assume calls that they create. Deletions of +/// \@llvm.assume calls do not require special handling. class AssumptionCache { - /// \brief The function for which this cache is handling assumptions. + /// The function for which this cache is handling assumptions. /// /// We track this to lazily populate our assumptions. Function &F; - /// \brief Vector of weak value handles to calls of the @llvm.assume + /// Vector of weak value handles to calls of the \@llvm.assume /// intrinsic. SmallVector AssumeHandles; @@ -64,7 +64,7 @@ class AssumptionCache { friend AffectedValueCallbackVH; - /// \brief A map of values about which an assumption might be providing + /// A map of values about which an assumption might be providing /// information to the relevant set of assumptions. using AffectedValuesMap = DenseMap, @@ -77,17 +77,17 @@ class AssumptionCache { /// Copy affected values in the cache for OV to be affected values for NV. void copyAffectedValuesInCache(Value *OV, Value *NV); - /// \brief Flag tracking whether we have scanned the function yet. + /// Flag tracking whether we have scanned the function yet. /// /// We want to be as lazy about this as possible, and so we scan the function /// at the last moment. bool Scanned = false; - /// \brief Scan the function for assumptions and add them to the cache. + /// Scan the function for assumptions and add them to the cache. void scanFunction(); public: - /// \brief Construct an AssumptionCache from a function by scanning all of + /// Construct an AssumptionCache from a function by scanning all of /// its instructions. AssumptionCache(Function &F) : F(F) {} @@ -98,17 +98,17 @@ public: return false; } - /// \brief Add an @llvm.assume intrinsic to this function's cache. + /// Add an \@llvm.assume intrinsic to this function's cache. /// /// The call passed in must be an instruction within this function and must /// not already be in the cache. void registerAssumption(CallInst *CI); - /// \brief Update the cache of values being affected by this assumption (i.e. + /// Update the cache of values being affected by this assumption (i.e. /// the values about which this assumption provides information). void updateAffectedValues(CallInst *CI); - /// \brief Clear the cache of @llvm.assume intrinsics for a function. + /// Clear the cache of \@llvm.assume intrinsics for a function. /// /// It will be re-scanned the next time it is requested. void clear() { @@ -117,7 +117,7 @@ public: Scanned = false; } - /// \brief Access the list of assumption handles currently tracked for this + /// Access the list of assumption handles currently tracked for this /// function. /// /// Note that these produce weak handles that may be null. The caller must @@ -131,7 +131,7 @@ public: return AssumeHandles; } - /// \brief Access the list of assumptions which affect this value. + /// Access the list of assumptions which affect this value. MutableArrayRef assumptionsFor(const Value *V) { if (!Scanned) scanFunction(); @@ -144,7 +144,7 @@ public: } }; -/// \brief A function analysis which provides an \c AssumptionCache. +/// A function analysis which provides an \c AssumptionCache. /// /// This analysis is intended for use with the new pass manager and will vend /// assumption caches for a given function. @@ -161,7 +161,7 @@ public: } }; -/// \brief Printer pass for the \c AssumptionAnalysis results. +/// Printer pass for the \c AssumptionAnalysis results. class AssumptionPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -171,7 +171,7 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief An immutable pass that tracks lazily created \c AssumptionCache +/// An immutable pass that tracks lazily created \c AssumptionCache /// objects. /// /// This is essentially a workaround for the legacy pass manager's weaknesses @@ -203,7 +203,7 @@ class AssumptionCacheTracker : public ImmutablePass { FunctionCallsMap AssumptionCaches; public: - /// \brief Get the cached assumptions for a function. + /// Get the cached assumptions for a function. /// /// If no assumptions are cached, this will scan the function. Otherwise, the /// existing cache will be returned. diff --git a/include/llvm/Analysis/BasicAliasAnalysis.h b/include/llvm/Analysis/BasicAliasAnalysis.h index 42e5e9714071b9d6f742953dd4a7c877902bd6fd..8fb3c3a63f276f47c94ba50d89046732953fbdab 100644 --- a/include/llvm/Analysis/BasicAliasAnalysis.h +++ b/include/llvm/Analysis/BasicAliasAnalysis.h @@ -171,9 +171,9 @@ private: static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject, - uint64_t ObjectAccessSize); + LocationSize ObjectAccessSize); - /// \brief A Heuristic for aliasGEP that searches for a constant offset + /// A Heuristic for aliasGEP that searches for a constant offset /// between the variables. /// /// GetLinearExpression has some limitations, as generally zext(%x + 1) @@ -183,31 +183,33 @@ private: /// the addition overflows. bool constantOffsetHeuristic(const SmallVectorImpl &VarIndices, - uint64_t V1Size, uint64_t V2Size, int64_t BaseOffset, - AssumptionCache *AC, DominatorTree *DT); + LocationSize V1Size, LocationSize V2Size, + int64_t BaseOffset, AssumptionCache *AC, + DominatorTree *DT); bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); void GetIndexDifference(SmallVectorImpl &Dest, const SmallVectorImpl &Src); - AliasResult aliasGEP(const GEPOperator *V1, uint64_t V1Size, + AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size, const AAMDNodes &V1AAInfo, const Value *V2, - uint64_t V2Size, const AAMDNodes &V2AAInfo, + LocationSize V2Size, const AAMDNodes &V2AAInfo, const Value *UnderlyingV1, const Value *UnderlyingV2); - AliasResult aliasPHI(const PHINode *PN, uint64_t PNSize, + AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize, const AAMDNodes &PNAAInfo, const Value *V2, - uint64_t V2Size, const AAMDNodes &V2AAInfo, + LocationSize V2Size, const AAMDNodes &V2AAInfo, const Value *UnderV2); - AliasResult aliasSelect(const SelectInst *SI, uint64_t SISize, + AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize, const AAMDNodes &SIAAInfo, const Value *V2, - uint64_t V2Size, const AAMDNodes &V2AAInfo, + LocationSize V2Size, const AAMDNodes &V2AAInfo, const Value *UnderV2); - AliasResult aliasCheck(const Value *V1, uint64_t V1Size, AAMDNodes V1AATag, - const Value *V2, uint64_t V2Size, AAMDNodes V2AATag, + AliasResult aliasCheck(const Value *V1, LocationSize V1Size, + AAMDNodes V1AATag, const Value *V2, + LocationSize V2Size, AAMDNodes V2AATag, const Value *O1 = nullptr, const Value *O2 = nullptr); }; diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h index 89370cbeeea1ca1f1bac6db02c0fe1d440b1aa72..ca12db6208b8d0866553daa927d7daa62699b593 100644 --- a/include/llvm/Analysis/BlockFrequencyInfo.h +++ b/include/llvm/Analysis/BlockFrequencyInfo.h @@ -65,17 +65,17 @@ public: /// floating points. BlockFrequency getBlockFreq(const BasicBlock *BB) const; - /// \brief Returns the estimated profile count of \p BB. + /// Returns the estimated profile count of \p BB. /// This computes the relative block frequency of \p BB and multiplies it by /// the enclosing function's count (if available) and returns the value. Optional getBlockProfileCount(const BasicBlock *BB) const; - /// \brief Returns the estimated profile count of \p Freq. + /// Returns the estimated profile count of \p Freq. /// This uses the frequency \p Freq and multiplies it by /// the enclosing function's count (if available) and returns the value. Optional getProfileCountFromFreq(uint64_t Freq) const; - /// \brief Returns true if \p BB is an irreducible loop header + /// Returns true if \p BB is an irreducible loop header /// block. Otherwise false. bool isIrrLoopHeader(const BasicBlock *BB); @@ -105,7 +105,7 @@ public: void print(raw_ostream &OS) const; }; -/// \brief Analysis pass which computes \c BlockFrequencyInfo. +/// Analysis pass which computes \c BlockFrequencyInfo. class BlockFrequencyAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -113,14 +113,14 @@ class BlockFrequencyAnalysis static AnalysisKey Key; public: - /// \brief Provide the result type for this analysis pass. + /// Provide the result type for this analysis pass. using Result = BlockFrequencyInfo; - /// \brief Run the analysis pass over a function and produce BFI. + /// Run the analysis pass over a function and produce BFI. Result run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for the \c BlockFrequencyInfo results. +/// Printer pass for the \c BlockFrequencyInfo results. class BlockFrequencyPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -131,7 +131,7 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Legacy analysis pass which computes \c BlockFrequencyInfo. +/// Legacy analysis pass which computes \c BlockFrequencyInfo. class BlockFrequencyInfoWrapperPass : public FunctionPass { BlockFrequencyInfo BFI; diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 40c40b80bc89f952066ffa36d86d4bd0f770ac65..25b2efd33c98e65df4ca3b7c0683540b9caeede5 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -66,7 +66,7 @@ struct IrreducibleGraph; // This is part of a workaround for a GCC 4.7 crash on lambdas. template struct BlockEdgesAdder; -/// \brief Mass of a block. +/// Mass of a block. /// /// This class implements a sort of fixed-point fraction always between 0.0 and /// 1.0. getMass() == std::numeric_limits::max() indicates a value of @@ -100,7 +100,7 @@ public: bool operator!() const { return isEmpty(); } - /// \brief Add another mass. + /// Add another mass. /// /// Adds another mass, saturating at \a isFull() rather than overflowing. BlockMass &operator+=(BlockMass X) { @@ -109,7 +109,7 @@ public: return *this; } - /// \brief Subtract another mass. + /// Subtract another mass. /// /// Subtracts another mass, saturating at \a isEmpty() rather than /// undeflowing. @@ -131,7 +131,7 @@ public: bool operator<(BlockMass X) const { return Mass < X.Mass; } bool operator>(BlockMass X) const { return Mass > X.Mass; } - /// \brief Convert to scaled number. + /// Convert to scaled number. /// /// Convert to \a ScaledNumber. \a isFull() gives 1.0, while \a isEmpty() /// gives slightly above 0.0. @@ -164,7 +164,7 @@ template <> struct isPodLike { static const bool value = true; }; -/// \brief Base class for BlockFrequencyInfoImpl +/// Base class for BlockFrequencyInfoImpl /// /// BlockFrequencyInfoImplBase has supporting data structures and some /// algorithms for BlockFrequencyInfoImplBase. Only algorithms that depend on @@ -177,7 +177,7 @@ public: using Scaled64 = ScaledNumber; using BlockMass = bfi_detail::BlockMass; - /// \brief Representative of a block. + /// Representative of a block. /// /// This is a simple wrapper around an index into the reverse-post-order /// traversal of the blocks. @@ -206,13 +206,13 @@ public: } }; - /// \brief Stats about a block itself. + /// Stats about a block itself. struct FrequencyData { Scaled64 Scaled; uint64_t Integer; }; - /// \brief Data about a loop. + /// Data about a loop. /// /// Contains the data necessary to represent a loop as a pseudo-node once it's /// packaged. @@ -270,7 +270,7 @@ public: } }; - /// \brief Index of loop information. + /// Index of loop information. struct WorkingData { BlockNode Node; ///< This node. LoopData *Loop = nullptr; ///< The loop this block is inside. @@ -293,7 +293,7 @@ public: return Loop->Parent->Parent; } - /// \brief Resolve a node to its representative. + /// Resolve a node to its representative. /// /// Get the node currently representing Node, which could be a containing /// loop. @@ -320,7 +320,7 @@ public: return L; } - /// \brief Get the appropriate mass for a node. + /// Get the appropriate mass for a node. /// /// Get appropriate mass for Node. If Node is a loop-header (whose loop /// has been packaged), returns the mass of its pseudo-node. If it's a @@ -333,19 +333,19 @@ public: return Loop->Parent->Mass; } - /// \brief Has ContainingLoop been packaged up? + /// Has ContainingLoop been packaged up? bool isPackaged() const { return getResolvedNode() != Node; } - /// \brief Has Loop been packaged up? + /// Has Loop been packaged up? bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; } - /// \brief Has Loop been packaged up twice? + /// Has Loop been packaged up twice? bool isADoublePackage() const { return isDoubleLoopHeader() && Loop->Parent->IsPackaged; } }; - /// \brief Unscaled probability weight. + /// Unscaled probability weight. /// /// Probability weight for an edge in the graph (including the /// successor/target node). @@ -369,7 +369,7 @@ public: : Type(Type), TargetNode(TargetNode), Amount(Amount) {} }; - /// \brief Distribution of unscaled probability weight. + /// Distribution of unscaled probability weight. /// /// Distribution of unscaled probability weight to a set of successors. /// @@ -398,7 +398,7 @@ public: add(Node, Amount, Weight::Backedge); } - /// \brief Normalize the distribution. + /// Normalize the distribution. /// /// Combines multiple edges to the same \a Weight::TargetNode and scales /// down so that \a Total fits into 32-bits. @@ -413,26 +413,26 @@ public: void add(const BlockNode &Node, uint64_t Amount, Weight::DistType Type); }; - /// \brief Data about each block. This is used downstream. + /// Data about each block. This is used downstream. std::vector Freqs; - /// \brief Whether each block is an irreducible loop header. + /// Whether each block is an irreducible loop header. /// This is used downstream. SparseBitVector<> IsIrrLoopHeader; - /// \brief Loop data: see initializeLoops(). + /// Loop data: see initializeLoops(). std::vector Working; - /// \brief Indexed information about loops. + /// Indexed information about loops. std::list Loops; - /// \brief Virtual destructor. + /// Virtual destructor. /// /// Need a virtual destructor to mask the compiler warning about /// getBlockName(). virtual ~BlockFrequencyInfoImplBase() = default; - /// \brief Add all edges out of a packaged loop to the distribution. + /// Add all edges out of a packaged loop to the distribution. /// /// Adds all edges from LocalLoopHead to Dist. Calls addToDist() to add each /// successor edge. @@ -441,7 +441,7 @@ public: bool addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop, Distribution &Dist); - /// \brief Add an edge to the distribution. + /// Add an edge to the distribution. /// /// Adds an edge to Succ to Dist. If \c LoopHead.isValid(), then whether the /// edge is local/exit/backedge is in the context of LoopHead. Otherwise, @@ -457,7 +457,7 @@ public: return *Working[Head.Index].Loop; } - /// \brief Analyze irreducible SCCs. + /// Analyze irreducible SCCs. /// /// Separate irreducible SCCs from \c G, which is an explict graph of \c /// OuterLoop (or the top-level function, if \c OuterLoop is \c nullptr). @@ -468,7 +468,7 @@ public: analyzeIrreducible(const bfi_detail::IrreducibleGraph &G, LoopData *OuterLoop, std::list::iterator Insert); - /// \brief Update a loop after packaging irreducible SCCs inside of it. + /// Update a loop after packaging irreducible SCCs inside of it. /// /// Update \c OuterLoop. Before finding irreducible control flow, it was /// partway through \a computeMassInLoop(), so \a LoopData::Exits and \a @@ -476,7 +476,7 @@ public: /// up need to be removed from \a OuterLoop::Nodes. void updateLoopWithIrreducible(LoopData &OuterLoop); - /// \brief Distribute mass according to a distribution. + /// Distribute mass according to a distribution. /// /// Distributes the mass in Source according to Dist. If LoopHead.isValid(), /// backedges and exits are stored in its entry in Loops. @@ -485,7 +485,7 @@ public: void distributeMass(const BlockNode &Source, LoopData *OuterLoop, Distribution &Dist); - /// \brief Compute the loop scale for a loop. + /// Compute the loop scale for a loop. void computeLoopScale(LoopData &Loop); /// Adjust the mass of all headers in an irreducible loop. @@ -500,19 +500,19 @@ public: void distributeIrrLoopHeaderMass(Distribution &Dist); - /// \brief Package up a loop. + /// Package up a loop. void packageLoop(LoopData &Loop); - /// \brief Unwrap loops. + /// Unwrap loops. void unwrapLoops(); - /// \brief Finalize frequency metrics. + /// Finalize frequency metrics. /// /// Calculates final frequencies and cleans up no-longer-needed data /// structures. void finalizeMetrics(); - /// \brief Clear all memory. + /// Clear all memory. void clear(); virtual std::string getBlockName(const BlockNode &Node) const; @@ -560,7 +560,7 @@ template <> struct TypeMap { using LoopInfoT = MachineLoopInfo; }; -/// \brief Get the name of a MachineBasicBlock. +/// Get the name of a MachineBasicBlock. /// /// Get the name of a MachineBasicBlock. It's templated so that including from /// CodeGen is unnecessary (that would be a layering issue). @@ -574,13 +574,13 @@ template std::string getBlockName(const BlockT *BB) { return (MachineName + "[" + BB->getName() + "]").str(); return MachineName.str(); } -/// \brief Get the name of a BasicBlock. +/// Get the name of a BasicBlock. template <> inline std::string getBlockName(const BasicBlock *BB) { assert(BB && "Unexpected nullptr"); return BB->getName().str(); } -/// \brief Graph of irreducible control flow. +/// Graph of irreducible control flow. /// /// This graph is used for determining the SCCs in a loop (or top-level /// function) that has irreducible control flow. @@ -619,7 +619,7 @@ struct IrreducibleGraph { std::vector Nodes; SmallDenseMap Lookup; - /// \brief Construct an explicit graph containing irreducible control flow. + /// Construct an explicit graph containing irreducible control flow. /// /// Construct an explicit graph of the control flow in \c OuterLoop (or the /// top-level function, if \c OuterLoop is \c nullptr). Uses \c @@ -687,7 +687,7 @@ void IrreducibleGraph::addEdges(const BlockNode &Node, } // end namespace bfi_detail -/// \brief Shared implementation for block frequency analysis. +/// Shared implementation for block frequency analysis. /// /// This is a shared implementation of BlockFrequencyInfo and /// MachineBlockFrequencyInfo, and calculates the relative frequencies of @@ -878,12 +878,12 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { return RPOT[Node.Index]; } - /// \brief Run (and save) a post-order traversal. + /// Run (and save) a post-order traversal. /// /// Saves a reverse post-order traversal of all the nodes in \a F. void initializeRPOT(); - /// \brief Initialize loop data. + /// Initialize loop data. /// /// Build up \a Loops using \a LoopInfo. \a LoopInfo gives us a mapping from /// each block to the deepest loop it's in, but we need the inverse. For each @@ -892,7 +892,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { /// the loop that are not in sub-loops. void initializeLoops(); - /// \brief Propagate to a block's successors. + /// Propagate to a block's successors. /// /// In the context of distributing mass through \c OuterLoop, divide the mass /// currently assigned to \c Node between its successors. @@ -900,7 +900,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { /// \return \c true unless there's an irreducible backedge. bool propagateMassToSuccessors(LoopData *OuterLoop, const BlockNode &Node); - /// \brief Compute mass in a particular loop. + /// Compute mass in a particular loop. /// /// Assign mass to \c Loop's header, and then for each block in \c Loop in /// reverse post-order, distribute mass to its successors. Only visits nodes @@ -910,7 +910,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { /// \return \c true unless there's an irreducible backedge. bool computeMassInLoop(LoopData &Loop); - /// \brief Try to compute mass in the top-level function. + /// Try to compute mass in the top-level function. /// /// Assign mass to the entry block, and then for each block in reverse /// post-order, distribute mass to its successors. Skips nodes that have @@ -920,7 +920,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { /// \return \c true unless there's an irreducible backedge. bool tryToComputeMassInFunction(); - /// \brief Compute mass in (and package up) irreducible SCCs. + /// Compute mass in (and package up) irreducible SCCs. /// /// Find the irreducible SCCs in \c OuterLoop, add them to \a Loops (in front /// of \c Insert), and call \a computeMassInLoop() on each of them. @@ -935,7 +935,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { void computeIrreducibleMass(LoopData *OuterLoop, std::list::iterator Insert); - /// \brief Compute mass in all loops. + /// Compute mass in all loops. /// /// For each loop bottom-up, call \a computeMassInLoop(). /// @@ -946,7 +946,7 @@ template class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { /// \post \a computeMassInLoop() has returned \c true for every loop. void computeMassInLoops(); - /// \brief Compute mass in the top-level function. + /// Compute mass in the top-level function. /// /// Uses \a tryToComputeMassInFunction() and \a computeIrreducibleMass() to /// compute mass in the top-level function. @@ -994,7 +994,7 @@ public: const BranchProbabilityInfoT &getBPI() const { return *BPI; } - /// \brief Print the frequencies for the current function. + /// Print the frequencies for the current function. /// /// Prints the frequencies for the blocks in the current function. /// @@ -1030,8 +1030,9 @@ void BlockFrequencyInfoImpl::calculate(const FunctionT &F, Nodes.clear(); // Initialize. - DEBUG(dbgs() << "\nblock-frequency: " << F.getName() << "\n=================" - << std::string(F.getName().size(), '=') << "\n"); + LLVM_DEBUG(dbgs() << "\nblock-frequency: " << F.getName() + << "\n=================" + << std::string(F.getName().size(), '=') << "\n"); initializeRPOT(); initializeLoops(); @@ -1067,10 +1068,11 @@ template void BlockFrequencyInfoImpl::initializeRPOT() { assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() && "More nodes in function than Block Frequency Info supports"); - DEBUG(dbgs() << "reverse-post-order-traversal\n"); + LLVM_DEBUG(dbgs() << "reverse-post-order-traversal\n"); for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) { BlockNode Node = getNode(I); - DEBUG(dbgs() << " - " << getIndex(I) << ": " << getBlockName(Node) << "\n"); + LLVM_DEBUG(dbgs() << " - " << getIndex(I) << ": " << getBlockName(Node) + << "\n"); Nodes[*I] = Node; } @@ -1081,7 +1083,7 @@ template void BlockFrequencyInfoImpl::initializeRPOT() { } template void BlockFrequencyInfoImpl::initializeLoops() { - DEBUG(dbgs() << "loop-detection\n"); + LLVM_DEBUG(dbgs() << "loop-detection\n"); if (LI->empty()) return; @@ -1099,7 +1101,7 @@ template void BlockFrequencyInfoImpl::initializeLoops() { Loops.emplace_back(Parent, Header); Working[Header.Index].Loop = &Loops.back(); - DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n"); + LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n"); for (const LoopT *L : *Loop) Q.emplace_back(L, &Loops.back()); @@ -1128,8 +1130,8 @@ template void BlockFrequencyInfoImpl::initializeLoops() { Working[Index].Loop = HeaderData.Loop; HeaderData.Loop->Nodes.push_back(Index); - DEBUG(dbgs() << " - loop = " << getBlockName(Header) - << ": member = " << getBlockName(Index) << "\n"); + LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header) + << ": member = " << getBlockName(Index) << "\n"); } } @@ -1150,10 +1152,10 @@ template void BlockFrequencyInfoImpl::computeMassInLoops() { template bool BlockFrequencyInfoImpl::computeMassInLoop(LoopData &Loop) { // Compute mass in loop. - DEBUG(dbgs() << "compute-mass-in-loop: " << getLoopName(Loop) << "\n"); + LLVM_DEBUG(dbgs() << "compute-mass-in-loop: " << getLoopName(Loop) << "\n"); if (Loop.isIrreducible()) { - DEBUG(dbgs() << "isIrreducible = true\n"); + LLVM_DEBUG(dbgs() << "isIrreducible = true\n"); Distribution Dist; unsigned NumHeadersWithWeight = 0; Optional MinHeaderWeight; @@ -1165,14 +1167,14 @@ bool BlockFrequencyInfoImpl::computeMassInLoop(LoopData &Loop) { IsIrrLoopHeader.set(Loop.Nodes[H].Index); Optional HeaderWeight = Block->getIrrLoopHeaderWeight(); if (!HeaderWeight) { - DEBUG(dbgs() << "Missing irr loop header metadata on " - << getBlockName(HeaderNode) << "\n"); + LLVM_DEBUG(dbgs() << "Missing irr loop header metadata on " + << getBlockName(HeaderNode) << "\n"); HeadersWithoutWeight.insert(H); continue; } - DEBUG(dbgs() << getBlockName(HeaderNode) - << " has irr loop header weight " << HeaderWeight.getValue() - << "\n"); + LLVM_DEBUG(dbgs() << getBlockName(HeaderNode) + << " has irr loop header weight " + << HeaderWeight.getValue() << "\n"); NumHeadersWithWeight++; uint64_t HeaderWeightValue = HeaderWeight.getValue(); if (!MinHeaderWeight || HeaderWeightValue < MinHeaderWeight) @@ -1194,8 +1196,8 @@ bool BlockFrequencyInfoImpl::computeMassInLoop(LoopData &Loop) { assert(!getBlock(HeaderNode)->getIrrLoopHeaderWeight() && "Shouldn't have a weight metadata"); uint64_t MinWeight = MinHeaderWeight.getValue(); - DEBUG(dbgs() << "Giving weight " << MinWeight - << " to " << getBlockName(HeaderNode) << "\n"); + LLVM_DEBUG(dbgs() << "Giving weight " << MinWeight << " to " + << getBlockName(HeaderNode) << "\n"); if (MinWeight) Dist.addLocal(HeaderNode, MinWeight); } @@ -1224,7 +1226,7 @@ bool BlockFrequencyInfoImpl::computeMassInLoop(LoopData &Loop) { template bool BlockFrequencyInfoImpl::tryToComputeMassInFunction() { // Compute mass in function. - DEBUG(dbgs() << "compute-mass-in-function\n"); + LLVM_DEBUG(dbgs() << "compute-mass-in-function\n"); assert(!Working.empty() && "no blocks in function"); assert(!Working[0].isLoopHeader() && "entry block is a loop header"); @@ -1276,9 +1278,10 @@ template struct BlockEdgesAdder { template void BlockFrequencyInfoImpl::computeIrreducibleMass( LoopData *OuterLoop, std::list::iterator Insert) { - DEBUG(dbgs() << "analyze-irreducible-in-"; - if (OuterLoop) dbgs() << "loop: " << getLoopName(*OuterLoop) << "\n"; - else dbgs() << "function\n"); + LLVM_DEBUG(dbgs() << "analyze-irreducible-in-"; + if (OuterLoop) dbgs() + << "loop: " << getLoopName(*OuterLoop) << "\n"; + else dbgs() << "function\n"); using namespace bfi_detail; @@ -1304,7 +1307,7 @@ template bool BlockFrequencyInfoImpl::propagateMassToSuccessors(LoopData *OuterLoop, const BlockNode &Node) { - DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n"); + LLVM_DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n"); // Calculate probability for successors. Distribution Dist; if (auto *Loop = Working[Node.Index].getPackagedLoop()) { diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 417b6497881185345fe59bdd75cb772b461376a6..45277db460907ddb9d165385aa3186fb4e7dae83 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -38,7 +38,7 @@ class raw_ostream; class TargetLibraryInfo; class Value; -/// \brief Analysis providing branch probability information. +/// Analysis providing branch probability information. /// /// This is a function analysis which provides information on the relative /// probabilities of each "edge" in the function's CFG where such an edge is @@ -79,7 +79,7 @@ public: void print(raw_ostream &OS) const; - /// \brief Get an edge's probability, relative to other out-edges of the Src. + /// Get an edge's probability, relative to other out-edges of the Src. /// /// This routine provides access to the fractional probability between zero /// (0%) and one (100%) of this edge executing, relative to other edges @@ -88,7 +88,7 @@ public: BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const; - /// \brief Get the probability of going from Src to Dst. + /// Get the probability of going from Src to Dst. /// /// It returns the sum of all probabilities for edges from Src to Dst. BranchProbability getEdgeProbability(const BasicBlock *Src, @@ -97,19 +97,19 @@ public: BranchProbability getEdgeProbability(const BasicBlock *Src, succ_const_iterator Dst) const; - /// \brief Test if an edge is hot relative to other out-edges of the Src. + /// Test if an edge is hot relative to other out-edges of the Src. /// /// Check whether this edge out of the source block is 'hot'. We define hot /// as having a relative probability >= 80%. bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const; - /// \brief Retrieve the hot successor of a block if one exists. + /// Retrieve the hot successor of a block if one exists. /// /// Given a basic block, look through its successors and if one exists for /// which \see isEdgeHot would return true, return that successor block. const BasicBlock *getHotSucc(const BasicBlock *BB) const; - /// \brief Print an edge's probability. + /// Print an edge's probability. /// /// Retrieves an edge's probability similarly to \see getEdgeProbability, but /// then prints that probability to the provided stream. That stream is then @@ -117,7 +117,7 @@ public: raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src, const BasicBlock *Dst) const; - /// \brief Set the raw edge probability for the given edge. + /// Set the raw edge probability for the given edge. /// /// This allows a pass to explicitly set the edge probability for an edge. It /// can be used when updating the CFG to update and preserve the branch @@ -179,13 +179,13 @@ private: DenseMap Probs; - /// \brief Track the last function we run over for printing. + /// Track the last function we run over for printing. const Function *LastF; - /// \brief Track the set of blocks directly succeeded by a returning block. + /// Track the set of blocks directly succeeded by a returning block. SmallPtrSet PostDominatedByUnreachable; - /// \brief Track the set of blocks that always lead to a cold call. + /// Track the set of blocks that always lead to a cold call. SmallPtrSet PostDominatedByColdCall; void updatePostDominatedByUnreachable(const BasicBlock *BB); @@ -201,7 +201,7 @@ private: bool calcInvokeHeuristics(const BasicBlock *BB); }; -/// \brief Analysis pass which computes \c BranchProbabilityInfo. +/// Analysis pass which computes \c BranchProbabilityInfo. class BranchProbabilityAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -209,14 +209,14 @@ class BranchProbabilityAnalysis static AnalysisKey Key; public: - /// \brief Provide the result type for this analysis pass. + /// Provide the result type for this analysis pass. using Result = BranchProbabilityInfo; - /// \brief Run the analysis pass over a function and produce BPI. + /// Run the analysis pass over a function and produce BPI. BranchProbabilityInfo run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for the \c BranchProbabilityAnalysis results. +/// Printer pass for the \c BranchProbabilityAnalysis results. class BranchProbabilityPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -227,7 +227,7 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Legacy analysis pass which computes \c BranchProbabilityInfo. +/// Legacy analysis pass which computes \c BranchProbabilityInfo. class BranchProbabilityInfoWrapperPass : public FunctionPass { BranchProbabilityInfo BPI; diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h index d569464957b030e425aa8adbc28bee963ab46472..cccdd1637411852cdd1cc840b80d90cb55538913 100644 --- a/include/llvm/Analysis/CFG.h +++ b/include/llvm/Analysis/CFG.h @@ -49,7 +49,7 @@ unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ); bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, bool AllowIdenticalEdges = false); -/// \brief Determine whether instruction 'To' is reachable from 'From', +/// Determine whether instruction 'To' is reachable from 'From', /// returning true if uncertain. /// /// Determine whether there is a path from From to To within a single function. @@ -68,7 +68,7 @@ bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); -/// \brief Determine whether block 'To' is reachable from 'From', returning +/// Determine whether block 'To' is reachable from 'From', returning /// true if uncertain. /// /// Determine whether there is a path from From to To within a single function. @@ -78,7 +78,7 @@ bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To, const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); -/// \brief Determine whether there is at least one path from a block in +/// Determine whether there is at least one path from a block in /// 'Worklist' to 'StopBB', returning true if uncertain. /// /// Determine whether there is a path from at least one block in Worklist to @@ -90,7 +90,7 @@ bool isPotentiallyReachableFromMany(SmallVectorImpl &Worklist, const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); -/// \brief Return true if the control flow in \p RPOTraversal is irreducible. +/// Return true if the control flow in \p RPOTraversal is irreducible. /// /// This is a generic implementation to detect CFG irreducibility based on loop /// info analysis. It can be used for any kind of CFG (Loop, MachineLoop, diff --git a/include/llvm/Analysis/CFLAndersAliasAnalysis.h b/include/llvm/Analysis/CFLAndersAliasAnalysis.h index 6239d530958171d0362784a53ce9b187b33e5853..8ae72553ab94b59cbd87447111c681c3f01096ec 100644 --- a/include/llvm/Analysis/CFLAndersAliasAnalysis.h +++ b/include/llvm/Analysis/CFLAndersAliasAnalysis.h @@ -56,7 +56,7 @@ public: /// Evict the given function from cache void evict(const Function *Fn); - /// \brief Get the alias summary for the given function + /// Get the alias summary for the given function /// Return nullptr if the summary is not found or not available const cflaa::AliasSummary *getAliasSummary(const Function &); @@ -64,19 +64,19 @@ public: AliasResult alias(const MemoryLocation &, const MemoryLocation &); private: - /// \brief Ensures that the given function is available in the cache. + /// Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. const Optional &ensureCached(const Function &); - /// \brief Inserts the given Function into the cache. + /// Inserts the given Function into the cache. void scan(const Function &); - /// \brief Build summary for a given function + /// Build summary for a given function FunctionInfo buildInfoFrom(const Function &); const TargetLibraryInfo &TLI; - /// \brief Cached mapping of Functions to their StratifiedSets. + /// Cached mapping of Functions to their StratifiedSets. /// If a function's sets are currently being built, it is marked /// in the cache as an Optional without a value. This way, if we /// have any kind of recursion, it is discernable from a function diff --git a/include/llvm/Analysis/CFLSteensAliasAnalysis.h b/include/llvm/Analysis/CFLSteensAliasAnalysis.h index ee9e29046af881815156d0857046e6453118deaf..09e366f11e18e434ecd7c10a8ceb3fa27caebfa9 100644 --- a/include/llvm/Analysis/CFLSteensAliasAnalysis.h +++ b/include/llvm/Analysis/CFLSteensAliasAnalysis.h @@ -55,16 +55,16 @@ public: return false; } - /// \brief Inserts the given Function into the cache. + /// Inserts the given Function into the cache. void scan(Function *Fn); void evict(Function *Fn); - /// \brief Ensures that the given function is available in the cache. + /// Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. const Optional &ensureCached(Function *Fn); - /// \brief Get the alias summary for the given function + /// Get the alias summary for the given function /// Return nullptr if the summary is not found or not available const cflaa::AliasSummary *getAliasSummary(Function &Fn); @@ -92,7 +92,7 @@ public: private: const TargetLibraryInfo &TLI; - /// \brief Cached mapping of Functions to their StratifiedSets. + /// Cached mapping of Functions to their StratifiedSets. /// If a function's sets are currently being built, it is marked /// in the cache as an Optional without a value. This way, if we /// have any kind of recursion, it is discernable from a function diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h index 457d5a0adcb0666b115c869601eeb0effc79c819..5e83ea2a6e2b38f3ab7865ca48b7ee83a32aec8f 100644 --- a/include/llvm/Analysis/CGSCCPassManager.h +++ b/include/llvm/Analysis/CGSCCPassManager.h @@ -119,7 +119,7 @@ extern template class AllAnalysesOn; extern template class AnalysisManager; -/// \brief The CGSCC analysis manager. +/// The CGSCC analysis manager. /// /// See the documentation for the AnalysisManager template for detail /// documentation. This type serves as a convenient way to refer to this @@ -140,7 +140,7 @@ PassManager; -/// \brief The CGSCC pass manager. +/// The CGSCC pass manager. /// /// See the documentation for the PassManager template for details. It runs /// a sequence of SCC passes over each SCC that the manager is run over. This @@ -175,10 +175,10 @@ public: explicit Result(CGSCCAnalysisManager &InnerAM, LazyCallGraph &G) : InnerAM(&InnerAM), G(&G) {} - /// \brief Accessor for the analysis manager. + /// Accessor for the analysis manager. CGSCCAnalysisManager &getManager() { return *InnerAM; } - /// \brief Handler for invalidation of the Module. + /// Handler for invalidation of the Module. /// /// If the proxy analysis itself is preserved, then we assume that the set of /// SCCs in the Module hasn't changed. Thus any pointers to SCCs in the @@ -302,7 +302,7 @@ struct CGSCCUpdateResult { &InlinedInternalEdges; }; -/// \brief The core module pass which does a post-order walk of the SCCs and +/// The core module pass which does a post-order walk of the SCCs and /// runs a CGSCC pass over each one. /// /// Designed to allow composition of a CGSCCPass(Manager) and @@ -338,7 +338,7 @@ public: return *this; } - /// \brief Runs the CGSCC pass across every SCC in the module. + /// Runs the CGSCC pass across every SCC in the module. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) { // Setup the CGSCC analysis manager from its proxy. CGSCCAnalysisManager &CGAM = @@ -387,15 +387,15 @@ public: do { LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val(); if (InvalidRefSCCSet.count(RC)) { - DEBUG(dbgs() << "Skipping an invalid RefSCC...\n"); + LLVM_DEBUG(dbgs() << "Skipping an invalid RefSCC...\n"); continue; } assert(CWorklist.empty() && "Should always start with an empty SCC worklist"); - DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC - << "\n"); + LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC + << "\n"); // Push the initial SCCs in reverse post-order as we'll pop off the // back and so see this in post-order. @@ -409,12 +409,13 @@ public: // other RefSCCs should be queued above, so we just need to skip both // scenarios here. if (InvalidSCCSet.count(C)) { - DEBUG(dbgs() << "Skipping an invalid SCC...\n"); + LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n"); continue; } if (&C->getOuterRefSCC() != RC) { - DEBUG(dbgs() << "Skipping an SCC that is now part of some other " - "RefSCC...\n"); + LLVM_DEBUG(dbgs() + << "Skipping an SCC that is now part of some other " + "RefSCC...\n"); continue; } @@ -436,7 +437,8 @@ public: // If the CGSCC pass wasn't able to provide a valid updated SCC, // the current SCC may simply need to be skipped if invalid. if (UR.InvalidatedSCCs.count(C)) { - DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n"); + LLVM_DEBUG(dbgs() + << "Skipping invalidated root or island SCC!\n"); break; } // Check that we didn't miss any update scenario. @@ -464,9 +466,10 @@ public: // FIXME: If we ever start having RefSCC passes, we'll want to // iterate there too. if (UR.UpdatedC) - DEBUG(dbgs() << "Re-running SCC passes after a refinement of the " - "current SCC: " - << *UR.UpdatedC << "\n"); + LLVM_DEBUG(dbgs() + << "Re-running SCC passes after a refinement of the " + "current SCC: " + << *UR.UpdatedC << "\n"); // Note that both `C` and `RC` may at this point refer to deleted, // invalid SCC and RefSCCs respectively. But we will short circuit @@ -494,7 +497,7 @@ private: CGSCCPassT Pass; }; -/// \brief A function to deduce a function pass type and wrap it in the +/// A function to deduce a function pass type and wrap it in the /// templated adaptor. template ModuleToPostOrderCGSCCPassAdaptor @@ -517,7 +520,7 @@ public: public: explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {} - /// \brief Accessor for the analysis manager. + /// Accessor for the analysis manager. FunctionAnalysisManager &getManager() { return *FAM; } bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA, @@ -552,7 +555,7 @@ LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass( LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR); -/// \brief Adaptor that maps from a SCC to its functions. +/// Adaptor that maps from a SCC to its functions. /// /// Designed to allow composition of a FunctionPass(Manager) and /// a CGSCCPassManager. Note that if this pass is constructed with a pointer @@ -585,7 +588,7 @@ public: return *this; } - /// \brief Runs the function pass across every function in the module. + /// Runs the function pass across every function in the module. PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR) { // Setup the function analysis manager from its proxy. @@ -601,7 +604,8 @@ public: // a pointer we can overwrite. LazyCallGraph::SCC *CurrentC = &C; - DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n"); + LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C + << "\n"); PreservedAnalyses PA = PreservedAnalyses::all(); for (LazyCallGraph::Node *N : Nodes) { @@ -652,7 +656,7 @@ private: FunctionPassT Pass; }; -/// \brief A function to deduce a function pass type and wrap it in the +/// A function to deduce a function pass type and wrap it in the /// templated adaptor. template CGSCCToFunctionPassAdaptor @@ -757,9 +761,9 @@ public: if (!F) return false; - DEBUG(dbgs() << "Found devirutalized call from " - << CS.getParent()->getParent()->getName() << " to " - << F->getName() << "\n"); + LLVM_DEBUG(dbgs() << "Found devirutalized call from " + << CS.getParent()->getParent()->getName() << " to " + << F->getName() << "\n"); // We now have a direct call where previously we had an indirect call, // so iterate to process this devirtualization site. @@ -793,16 +797,18 @@ public: // Otherwise, if we've already hit our max, we're done. if (Iteration >= MaxIterations) { - DEBUG(dbgs() << "Found another devirtualization after hitting the max " - "number of repetitions (" - << MaxIterations << ") on SCC: " << *C << "\n"); + LLVM_DEBUG( + dbgs() << "Found another devirtualization after hitting the max " + "number of repetitions (" + << MaxIterations << ") on SCC: " << *C << "\n"); PA.intersect(std::move(PassPA)); break; } - DEBUG(dbgs() - << "Repeating an SCC pass after finding a devirtualization in: " - << *C << "\n"); + LLVM_DEBUG( + dbgs() + << "Repeating an SCC pass after finding a devirtualization in: " << *C + << "\n"); // Move over the new call counts in preparation for iterating. CallCounts = std::move(NewCallCounts); @@ -824,7 +830,7 @@ private: int MaxIterations; }; -/// \brief A function to deduce a function pass type and wrap it in the +/// A function to deduce a function pass type and wrap it in the /// templated adaptor. template DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(PassT Pass, diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 8efc85f9fb02a6603c84bd7095f0d83216b35721..f109cf2fac4dbeabe96de15301fed206ec68fc10 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -66,7 +66,7 @@ class CallGraphNode; class Module; class raw_ostream; -/// \brief The basic data container for the call graph of a \c Module of IR. +/// The basic data container for the call graph of a \c Module of IR. /// /// This class exposes both the interface to the call graph for a module of IR. /// @@ -77,25 +77,25 @@ class CallGraph { using FunctionMapTy = std::map>; - /// \brief A map from \c Function* to \c CallGraphNode*. + /// A map from \c Function* to \c CallGraphNode*. FunctionMapTy FunctionMap; - /// \brief This node has edges to all external functions and those internal + /// This node has edges to all external functions and those internal /// functions that have their address taken. CallGraphNode *ExternalCallingNode; - /// \brief This node has edges to it from all functions making indirect calls + /// This node has edges to it from all functions making indirect calls /// or calling an external function. std::unique_ptr CallsExternalNode; - /// \brief Replace the function represented by this node by another. + /// Replace the function represented by this node by another. /// /// This does not rescan the body of the function, so it is suitable when /// splicing the body of one function to another while also updating all /// callers from the old function to the new. void spliceFunction(const Function *From, const Function *To); - /// \brief Add a function to the call graph, and link the node to all of the + /// Add a function to the call graph, and link the node to all of the /// functions that it calls. void addToCallGraph(Function *F); @@ -110,7 +110,7 @@ public: using iterator = FunctionMapTy::iterator; using const_iterator = FunctionMapTy::const_iterator; - /// \brief Returns the module the call graph corresponds to. + /// Returns the module the call graph corresponds to. Module &getModule() const { return M; } inline iterator begin() { return FunctionMap.begin(); } @@ -118,21 +118,21 @@ public: inline const_iterator begin() const { return FunctionMap.begin(); } inline const_iterator end() const { return FunctionMap.end(); } - /// \brief Returns the call graph node for the provided function. + /// Returns the call graph node for the provided function. inline const CallGraphNode *operator[](const Function *F) const { const_iterator I = FunctionMap.find(F); assert(I != FunctionMap.end() && "Function not in callgraph!"); return I->second.get(); } - /// \brief Returns the call graph node for the provided function. + /// Returns the call graph node for the provided function. inline CallGraphNode *operator[](const Function *F) { const_iterator I = FunctionMap.find(F); assert(I != FunctionMap.end() && "Function not in callgraph!"); return I->second.get(); } - /// \brief Returns the \c CallGraphNode which is used to represent + /// Returns the \c CallGraphNode which is used to represent /// undetermined calls into the callgraph. CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; } @@ -145,7 +145,7 @@ public: // modified. // - /// \brief Unlink the function from this module, returning it. + /// Unlink the function from this module, returning it. /// /// Because this removes the function from the module, the call graph node is /// destroyed. This is only valid if the function does not call any other @@ -153,25 +153,25 @@ public: /// this is to dropAllReferences before calling this. Function *removeFunctionFromModule(CallGraphNode *CGN); - /// \brief Similar to operator[], but this will insert a new CallGraphNode for + /// Similar to operator[], but this will insert a new CallGraphNode for /// \c F if one does not already exist. CallGraphNode *getOrInsertFunction(const Function *F); }; -/// \brief A node in the call graph for a module. +/// A node in the call graph for a module. /// /// Typically represents a function in the call graph. There are also special /// "null" nodes used to represent theoretical entries in the call graph. class CallGraphNode { public: - /// \brief A pair of the calling instruction (a call or invoke) + /// A pair of the calling instruction (a call or invoke) /// and the call graph node being called. using CallRecord = std::pair; public: using CalledFunctionsVector = std::vector; - /// \brief Creates a node for the specified function. + /// Creates a node for the specified function. inline CallGraphNode(Function *F) : F(F) {} CallGraphNode(const CallGraphNode &) = delete; @@ -184,7 +184,7 @@ public: using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; - /// \brief Returns the function that this call graph node represents. + /// Returns the function that this call graph node represents. Function *getFunction() const { return F; } inline iterator begin() { return CalledFunctions.begin(); } @@ -194,17 +194,17 @@ public: inline bool empty() const { return CalledFunctions.empty(); } inline unsigned size() const { return (unsigned)CalledFunctions.size(); } - /// \brief Returns the number of other CallGraphNodes in this CallGraph that + /// Returns the number of other CallGraphNodes in this CallGraph that /// reference this node in their callee list. unsigned getNumReferences() const { return NumReferences; } - /// \brief Returns the i'th called function. + /// Returns the i'th called function. CallGraphNode *operator[](unsigned i) const { assert(i < CalledFunctions.size() && "Invalid index"); return CalledFunctions[i].second; } - /// \brief Print out this call graph node. + /// Print out this call graph node. void dump() const; void print(raw_ostream &OS) const; @@ -213,7 +213,7 @@ public: // modified // - /// \brief Removes all edges from this CallGraphNode to any functions it + /// Removes all edges from this CallGraphNode to any functions it /// calls. void removeAllCalledFunctions() { while (!CalledFunctions.empty()) { @@ -222,14 +222,14 @@ public: } } - /// \brief Moves all the callee information from N to this node. + /// Moves all the callee information from N to this node. void stealCalledFunctionsFrom(CallGraphNode *N) { assert(CalledFunctions.empty() && "Cannot steal callsite information if I already have some"); std::swap(CalledFunctions, N->CalledFunctions); } - /// \brief Adds a function to the list of functions called by this one. + /// Adds a function to the list of functions called by this one. void addCalledFunction(CallSite CS, CallGraphNode *M) { assert(!CS.getInstruction() || !CS.getCalledFunction() || !CS.getCalledFunction()->isIntrinsic() || @@ -244,23 +244,23 @@ public: CalledFunctions.pop_back(); } - /// \brief Removes the edge in the node for the specified call site. + /// Removes the edge in the node for the specified call site. /// /// Note that this method takes linear time, so it should be used sparingly. void removeCallEdgeFor(CallSite CS); - /// \brief Removes all call edges from this node to the specified callee + /// Removes all call edges from this node to the specified callee /// function. /// /// This takes more time to execute than removeCallEdgeTo, so it should not /// be used unless necessary. void removeAnyCallEdgeTo(CallGraphNode *Callee); - /// \brief Removes one edge associated with a null callsite from this node to + /// Removes one edge associated with a null callsite from this node to /// the specified callee function. void removeOneAbstractEdgeTo(CallGraphNode *Callee); - /// \brief Replaces the edge in the node for the specified call site with a + /// Replaces the edge in the node for the specified call site with a /// new one. /// /// Note that this method takes linear time, so it should be used sparingly. @@ -273,18 +273,18 @@ private: std::vector CalledFunctions; - /// \brief The number of times that this CallGraphNode occurs in the + /// The number of times that this CallGraphNode occurs in the /// CalledFunctions array of this or other CallGraphNodes. unsigned NumReferences = 0; void DropRef() { --NumReferences; } void AddRef() { ++NumReferences; } - /// \brief A special function that should only be used by the CallGraph class. + /// A special function that should only be used by the CallGraph class. void allReferencesDropped() { NumReferences = 0; } }; -/// \brief An analysis pass to compute the \c CallGraph for a \c Module. +/// An analysis pass to compute the \c CallGraph for a \c Module. /// /// This class implements the concept of an analysis pass used by the \c /// ModuleAnalysisManager to run an analysis over a module and cache the @@ -295,16 +295,16 @@ class CallGraphAnalysis : public AnalysisInfoMixin { static AnalysisKey Key; public: - /// \brief A formulaic type to inform clients of the result type. + /// A formulaic type to inform clients of the result type. using Result = CallGraph; - /// \brief Compute the \c CallGraph for the module \c M. + /// Compute the \c CallGraph for the module \c M. /// /// The real work here is done in the \c CallGraph constructor. CallGraph run(Module &M, ModuleAnalysisManager &) { return CallGraph(M); } }; -/// \brief Printer pass for the \c CallGraphAnalysis results. +/// Printer pass for the \c CallGraphAnalysis results. class CallGraphPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -314,7 +314,7 @@ public: PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); }; -/// \brief The \c ModulePass which wraps up a \c CallGraph and the logic to +/// The \c ModulePass which wraps up a \c CallGraph and the logic to /// build it. /// /// This class exposes both the interface to the call graph container and the @@ -330,7 +330,7 @@ public: CallGraphWrapperPass(); ~CallGraphWrapperPass() override; - /// \brief The internal \c CallGraph around which the rest of this interface + /// The internal \c CallGraph around which the rest of this interface /// is wrapped. const CallGraph &getCallGraph() const { return *G; } CallGraph &getCallGraph() { return *G; } @@ -338,7 +338,7 @@ public: using iterator = CallGraph::iterator; using const_iterator = CallGraph::const_iterator; - /// \brief Returns the module the call graph corresponds to. + /// Returns the module the call graph corresponds to. Module &getModule() const { return G->getModule(); } inline iterator begin() { return G->begin(); } @@ -346,15 +346,15 @@ public: inline const_iterator begin() const { return G->begin(); } inline const_iterator end() const { return G->end(); } - /// \brief Returns the call graph node for the provided function. + /// Returns the call graph node for the provided function. inline const CallGraphNode *operator[](const Function *F) const { return (*G)[F]; } - /// \brief Returns the call graph node for the provided function. + /// Returns the call graph node for the provided function. inline CallGraphNode *operator[](const Function *F) { return (*G)[F]; } - /// \brief Returns the \c CallGraphNode which is used to represent + /// Returns the \c CallGraphNode which is used to represent /// undetermined calls into the callgraph. CallGraphNode *getExternalCallingNode() const { return G->getExternalCallingNode(); @@ -369,7 +369,7 @@ public: // modified. // - /// \brief Unlink the function from this module, returning it. + /// Unlink the function from this module, returning it. /// /// Because this removes the function from the module, the call graph node is /// destroyed. This is only valid if the function does not call any other @@ -379,7 +379,7 @@ public: return G->removeFunctionFromModule(CGN); } - /// \brief Similar to operator[], but this will insert a new CallGraphNode for + /// Similar to operator[], but this will insert a new CallGraphNode for /// \c F if one does not already exist. CallGraphNode *getOrInsertFunction(const Function *F) { return G->getOrInsertFunction(F); diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h index 8d2c095d8585f57df92a33ab463d3e74711a27cf..7a869a51233a035bbb8d51f4d327d2e7d652a957 100644 --- a/include/llvm/Analysis/CaptureTracking.h +++ b/include/llvm/Analysis/CaptureTracking.h @@ -46,7 +46,7 @@ namespace llvm { /// to speed up capture-tracker queries. bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - DominatorTree *DT, bool IncludeI = false, + const DominatorTree *DT, bool IncludeI = false, OrderedBasicBlock *OBB = nullptr); /// This callback is used in conjunction with PointerMayBeCaptured. In diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 9e861ac1882526785e1bd150dd56ece1ca190d3f..75290223852265ba7d27c3e996fe5067b28be67c 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -29,7 +29,7 @@ class DataLayout; class TargetTransformInfo; class Value; -/// \brief Check whether a call will lower to something small. +/// Check whether a call will lower to something small. /// /// This tests checks whether this callsite will lower to something /// significantly cheaper than a traditional call, often a single @@ -37,64 +37,64 @@ class Value; /// return true, so will this function. bool callIsSmall(ImmutableCallSite CS); -/// \brief Utility to calculate the size and a few similar metrics for a set +/// Utility to calculate the size and a few similar metrics for a set /// of basic blocks. struct CodeMetrics { - /// \brief True if this function contains a call to setjmp or other functions + /// True if this function contains a call to setjmp or other functions /// with attribute "returns twice" without having the attribute itself. bool exposesReturnsTwice = false; - /// \brief True if this function calls itself. + /// True if this function calls itself. bool isRecursive = false; - /// \brief True if this function cannot be duplicated. + /// True if this function cannot be duplicated. /// /// True if this function contains one or more indirect branches, or it contains /// one or more 'noduplicate' instructions. bool notDuplicatable = false; - /// \brief True if this function contains a call to a convergent function. + /// True if this function contains a call to a convergent function. bool convergent = false; - /// \brief True if this function calls alloca (in the C sense). + /// True if this function calls alloca (in the C sense). bool usesDynamicAlloca = false; - /// \brief Number of instructions in the analyzed blocks. + /// Number of instructions in the analyzed blocks. unsigned NumInsts = false; - /// \brief Number of analyzed blocks. + /// Number of analyzed blocks. unsigned NumBlocks = false; - /// \brief Keeps track of basic block code size estimates. + /// Keeps track of basic block code size estimates. DenseMap NumBBInsts; - /// \brief Keep track of the number of calls to 'big' functions. + /// Keep track of the number of calls to 'big' functions. unsigned NumCalls = false; - /// \brief The number of calls to internal functions with a single caller. + /// The number of calls to internal functions with a single caller. /// /// These are likely targets for future inlining, likely exposed by /// interleaved devirtualization. unsigned NumInlineCandidates = 0; - /// \brief How many instructions produce vector values. + /// How many instructions produce vector values. /// /// The inliner is more aggressive with inlining vector kernels. unsigned NumVectorInsts = 0; - /// \brief How many 'ret' instructions the blocks contain. + /// How many 'ret' instructions the blocks contain. unsigned NumRets = 0; - /// \brief Add information about a block to the current state. + /// Add information about a block to the current state. void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI, const SmallPtrSetImpl &EphValues); - /// \brief Collect a loop's ephemeral values (those used only by an assume + /// Collect a loop's ephemeral values (those used only by an assume /// or similar intrinsics in the loop). static void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl &EphValues); - /// \brief Collect a functions's ephemeral values (those used only by an + /// Collect a functions's ephemeral values (those used only by an /// assume or similar intrinsics in the function). static void collectEphemeralValues(const Function *L, AssumptionCache *AC, SmallPtrSetImpl &EphValues); diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index 354b5579236ec4dcaa5254941d01897723e1d23c..192c1abddcd2e6137f4f0a2447cd5b157af0d6f3 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -73,19 +73,19 @@ ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr); -/// \brief Attempt to constant fold a binary operation with the specified +/// Attempt to constant fold a binary operation with the specified /// operands. If it fails, it returns a constant expression of the specified /// operands. Constant *ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL); -/// \brief Attempt to constant fold a select instruction with the specified +/// Attempt to constant fold a select instruction with the specified /// operands. The constant result is returned if successful; if not, null is /// returned. Constant *ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2); -/// \brief Attempt to constant fold a cast with the specified operand. If it +/// Attempt to constant fold a cast with the specified operand. If it /// fails, it returns a constant expression of the specified operand. Constant *ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL); @@ -96,25 +96,25 @@ Constant *ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef Idxs); -/// \brief Attempt to constant fold an extractvalue instruction with the +/// Attempt to constant fold an extractvalue instruction with the /// specified operands and indices. The constant result is returned if /// successful; if not, null is returned. Constant *ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef Idxs); -/// \brief Attempt to constant fold an insertelement instruction with the +/// Attempt to constant fold an insertelement instruction with the /// specified operands and indices. The constant result is returned if /// successful; if not, null is returned. Constant *ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt, Constant *Idx); -/// \brief Attempt to constant fold an extractelement instruction with the +/// Attempt to constant fold an extractelement instruction with the /// specified operands and indices. The constant result is returned if /// successful; if not, null is returned. Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx); -/// \brief Attempt to constant fold a shufflevector instruction with the +/// Attempt to constant fold a shufflevector instruction with the /// specified operands and indices. The constant result is returned if /// successful; if not, null is returned. Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, @@ -153,7 +153,7 @@ Constant *ConstantFoldCall(ImmutableCallSite CS, Function *F, Constant *ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, const DataLayout &DL); -/// \brief Check whether the given call has no side-effects. +/// Check whether the given call has no side-effects. /// Specifically checks for math routimes which sometimes set errno. bool isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI); } diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h index 39f9c39c34e1140debf128ec3d41641b3d48c2ca..b7447a0547d53d8b77e0a6d04c58b1dbccef7550 100644 --- a/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -20,7 +20,7 @@ namespace llvm { -/// \brief Default traits class for extracting a graph from an analysis pass. +/// Default traits class for extracting a graph from an analysis pass. /// /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through. template @@ -36,7 +36,7 @@ public: DOTGraphTraitsViewer(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} - /// @brief Return true if this function should be processed. + /// Return true if this function should be processed. /// /// An implementation of this class my override this function to indicate that /// only certain functions should be viewed. @@ -78,7 +78,7 @@ public: DOTGraphTraitsPrinter(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} - /// @brief Return true if this function should be processed. + /// Return true if this function should be processed. /// /// An implementation of this class my override this function to indicate that /// only certain functions should be printed. diff --git a/include/llvm/Analysis/DemandedBits.h b/include/llvm/Analysis/DemandedBits.h index ab8668256ba2815b65260abf5e299356220da7b2..d4384609762d4a7356800dcaadc4b40fe2882219 100644 --- a/include/llvm/Analysis/DemandedBits.h +++ b/include/llvm/Analysis/DemandedBits.h @@ -96,15 +96,15 @@ class DemandedBitsAnalysis : public AnalysisInfoMixin { static AnalysisKey Key; public: - /// \brief Provide the result type for this analysis pass. + /// Provide the result type for this analysis pass. using Result = DemandedBits; - /// \brief Run the analysis pass over a function and produce demanded bits + /// Run the analysis pass over a function and produce demanded bits /// information. DemandedBits run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for DemandedBits +/// Printer pass for DemandedBits class DemandedBitsPrinterPass : public PassInfoMixin { raw_ostream &OS; diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h index 90f33b8c42e5cba1c4a87ecd3927e878f5bb8d45..b3bea92fac00cc58a6a0cf08450e8520e8ea5dd1 100644 --- a/include/llvm/Analysis/DependenceAnalysis.h +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -914,7 +914,7 @@ template class ArrayRef; SmallVectorImpl &Pair); }; // class DependenceInfo - /// \brief AnalysisPass to compute dependence information in a function + /// AnalysisPass to compute dependence information in a function class DependenceAnalysis : public AnalysisInfoMixin { public: typedef DependenceInfo Result; @@ -925,7 +925,7 @@ template class ArrayRef; friend struct AnalysisInfoMixin; }; // class DependenceAnalysis - /// \brief Legacy pass manager pass to access dependence information + /// Legacy pass manager pass to access dependence information class DependenceAnalysisWrapperPass : public FunctionPass { public: static char ID; // Class identification, replacement for typeinfo diff --git a/include/llvm/Analysis/DivergenceAnalysis.h b/include/llvm/Analysis/DivergenceAnalysis.h index dd3c68e2dd673259d99f33ed7d445b491e3da366..328c8645d3c09b255aa6d40bd87622603f6661b7 100644 --- a/include/llvm/Analysis/DivergenceAnalysis.h +++ b/include/llvm/Analysis/DivergenceAnalysis.h @@ -37,12 +37,21 @@ public: // Print all divergent branches in the function. void print(raw_ostream &OS, const Module *) const override; - // Returns true if V is divergent. + // Returns true if V is divergent at its definition. + // + // Even if this function returns false, V may still be divergent when used + // in a different basic block. bool isDivergent(const Value *V) const { return DivergentValues.count(V); } // Returns true if V is uniform/non-divergent. + // + // Even if this function returns true, V may still be divergent when used + // in a different basic block. bool isUniform(const Value *V) const { return !isDivergent(V); } + // Keep the analysis results uptodate by removing an erased value. + void removeValue(const Value *V) { DivergentValues.erase(V); } + private: // Stores all divergent values. DenseSet DivergentValues; diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h index a304dff18c79029d771008378f7e74058db687ec..d94c420d71775d9ec821d7250ec220723ce80094 100644 --- a/include/llvm/Analysis/DominanceFrontier.h +++ b/include/llvm/Analysis/DominanceFrontier.h @@ -19,6 +19,7 @@ #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H #include "llvm/ADT/GraphTraits.h" +#include "llvm/Config/llvm-config.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/GenericDomTree.h" @@ -179,7 +180,7 @@ extern template class DominanceFrontierBase; extern template class DominanceFrontierBase; extern template class ForwardDominanceFrontierBase; -/// \brief Analysis pass which computes a \c DominanceFrontier. +/// Analysis pass which computes a \c DominanceFrontier. class DominanceFrontierAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -187,14 +188,14 @@ class DominanceFrontierAnalysis static AnalysisKey Key; public: - /// \brief Provide the result type for this analysis pass. + /// Provide the result type for this analysis pass. using Result = DominanceFrontier; - /// \brief Run the analysis pass over a function and produce a dominator tree. + /// Run the analysis pass over a function and produce a dominator tree. DominanceFrontier run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for the \c DominanceFrontier. +/// Printer pass for the \c DominanceFrontier. class DominanceFrontierPrinterPass : public PassInfoMixin { raw_ostream &OS; diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h index dffb2e02b62110081f5e9972f86556d862dd7a7b..99224c0bf13134cf1204fe595e6f762c95aa7e9b 100644 --- a/include/llvm/Analysis/DominanceFrontierImpl.h +++ b/include/llvm/Analysis/DominanceFrontierImpl.h @@ -21,6 +21,7 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/Debug.h" #include "llvm/Support/GenericDomTree.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/llvm/Analysis/EHPersonalities.h b/include/llvm/Analysis/EHPersonalities.h index 2c45ab4693e6c720928b845d97e8577a0e68d4ed..fe0e65b828cac2cbeae9ce310d69410a30fd23ac 100644 --- a/include/llvm/Analysis/EHPersonalities.h +++ b/include/llvm/Analysis/EHPersonalities.h @@ -32,10 +32,11 @@ enum class EHPersonality { MSVC_Win64SEH, MSVC_CXX, CoreCLR, - Rust + Rust, + Wasm_CXX }; -/// \brief See if the given exception handling personality function is one +/// See if the given exception handling personality function is one /// that we understand. If so, return a description of it; otherwise return /// Unknown. EHPersonality classifyEHPersonality(const Value *Pers); @@ -44,7 +45,7 @@ StringRef getEHPersonalityName(EHPersonality Pers); EHPersonality getDefaultEHPersonality(const Triple &T); -/// \brief Returns true if this personality function catches asynchronous +/// Returns true if this personality function catches asynchronous /// exceptions. inline bool isAsynchronousEHPersonality(EHPersonality Pers) { // The two SEH personality functions can catch asynch exceptions. We assume @@ -59,7 +60,7 @@ inline bool isAsynchronousEHPersonality(EHPersonality Pers) { llvm_unreachable("invalid enum"); } -/// \brief Returns true if this is a personality function that invokes +/// Returns true if this is a personality function that invokes /// handler funclets (which must return to it). inline bool isFuncletEHPersonality(EHPersonality Pers) { switch (Pers) { @@ -74,7 +75,23 @@ inline bool isFuncletEHPersonality(EHPersonality Pers) { llvm_unreachable("invalid enum"); } -/// \brief Return true if this personality may be safely removed if there +/// Returns true if this personality uses scope-style EH IR instructions: +/// catchswitch, catchpad/ret, and cleanuppad/ret. +inline bool isScopedEHPersonality(EHPersonality Pers) { + switch (Pers) { + case EHPersonality::MSVC_CXX: + case EHPersonality::MSVC_X86SEH: + case EHPersonality::MSVC_Win64SEH: + case EHPersonality::CoreCLR: + case EHPersonality::Wasm_CXX: + return true; + default: + return false; + } + llvm_unreachable("invalid enum"); +} + +/// Return true if this personality may be safely removed if there /// are no invoke instructions remaining in the current function. inline bool isNoOpWithoutInvoke(EHPersonality Pers) { switch (Pers) { @@ -91,7 +108,7 @@ bool canSimplifyInvokeNoUnwind(const Function *F); typedef TinyPtrVector ColorVector; -/// \brief If an EH funclet personality is in use (see isFuncletEHPersonality), +/// If an EH funclet personality is in use (see isFuncletEHPersonality), /// this will recompute which blocks are in which funclet. It is possible that /// some blocks are in multiple funclets. Consider this analysis to be /// expensive. diff --git a/include/llvm/Analysis/IndirectCallPromotionAnalysis.h b/include/llvm/Analysis/IndirectCallPromotionAnalysis.h index 8b1c10139de88f19b37a092fc87a4ad21aaf2312..be3a28424cf53dc465232b9569fc3658d6e5593c 100644 --- a/include/llvm/Analysis/IndirectCallPromotionAnalysis.h +++ b/include/llvm/Analysis/IndirectCallPromotionAnalysis.h @@ -48,7 +48,7 @@ private: public: ICallPromotionAnalysis(); - /// \brief Returns reference to array of InstrProfValueData for the given + /// Returns reference to array of InstrProfValueData for the given /// instruction \p I. /// /// The \p NumVals, \p TotalCount and \p NumCandidates diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 138d3acb0e8a3edfdaeac195763f85fde3a77bb3..8c412057fb8103aeee2a93bb4e0b5a2ee7f3056b 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -52,7 +52,7 @@ const int NoreturnPenalty = 10000; const unsigned TotalAllocaSizeRecursiveCaller = 1024; } -/// \brief Represents the cost of inlining a function. +/// Represents the cost of inlining a function. /// /// This supports special values for functions which should "always" or /// "never" be inlined. Otherwise, the cost represents a unitless amount; @@ -68,10 +68,10 @@ class InlineCost { NeverInlineCost = INT_MAX }; - /// \brief The estimated cost of inlining this callsite. + /// The estimated cost of inlining this callsite. const int Cost; - /// \brief The adjusted threshold against which this cost was computed. + /// The adjusted threshold against which this cost was computed. const int Threshold; // Trivial constructor, interesting logic in the factory functions below. @@ -90,7 +90,7 @@ public: return InlineCost(NeverInlineCost, 0); } - /// \brief Test whether the inline cost is low enough for inlining. + /// Test whether the inline cost is low enough for inlining. explicit operator bool() const { return Cost < Threshold; } @@ -99,20 +99,20 @@ public: bool isNever() const { return Cost == NeverInlineCost; } bool isVariable() const { return !isAlways() && !isNever(); } - /// \brief Get the inline cost estimate. + /// Get the inline cost estimate. /// It is an error to call this on an "always" or "never" InlineCost. int getCost() const { assert(isVariable() && "Invalid access of InlineCost"); return Cost; } - /// \brief Get the threshold against which the cost was computed + /// Get the threshold against which the cost was computed int getThreshold() const { assert(isVariable() && "Invalid access of InlineCost"); return Threshold; } - /// \brief Get the cost delta from the threshold for inlining. + /// Get the cost delta from the threshold for inlining. /// Only valid if the cost is of the variable kind. Returns a negative /// value if the cost is too high to inline. int getCostDelta() const { return Threshold - getCost(); } @@ -178,7 +178,7 @@ InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel); /// and the call/return instruction. int getCallsiteCost(CallSite CS, const DataLayout &DL); -/// \brief Get an InlineCost object representing the cost of inlining this +/// Get an InlineCost object representing the cost of inlining this /// callsite. /// /// Note that a default threshold is passed into this function. This threshold @@ -195,7 +195,7 @@ InlineCost getInlineCost( Optional> GetBFI, ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE = nullptr); -/// \brief Get an InlineCost with the callee explicitly specified. +/// Get an InlineCost with the callee explicitly specified. /// This allows you to calculate the cost of inlining a function via a /// pointer. This behaves exactly as the version with no explicit callee /// parameter in all other respects. @@ -207,7 +207,7 @@ getInlineCost(CallSite CS, Function *Callee, const InlineParams &Params, Optional> GetBFI, ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE); -/// \brief Minimal filter to detect invalid constructs for inlining. +/// Minimal filter to detect invalid constructs for inlining. bool isInlineViable(Function &Callee); } diff --git a/include/llvm/Analysis/IteratedDominanceFrontier.h b/include/llvm/Analysis/IteratedDominanceFrontier.h index edaf4e9025bc865ef3e7963c45692587a6723b8c..6b1950733246e84fa25c26a32a8ec194d4f80e14 100644 --- a/include/llvm/Analysis/IteratedDominanceFrontier.h +++ b/include/llvm/Analysis/IteratedDominanceFrontier.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -/// \brief Compute iterated dominance frontiers using a linear time algorithm. +/// Compute iterated dominance frontiers using a linear time algorithm. /// /// The algorithm used here is based on: /// @@ -32,7 +32,7 @@ namespace llvm { -/// \brief Determine the iterated dominance frontier, given a set of defining +/// Determine the iterated dominance frontier, given a set of defining /// blocks, and optionally, a set of live-in blocks. /// /// In turn, the results can be used to place phi nodes. @@ -48,7 +48,7 @@ class IDFCalculator { IDFCalculator(DominatorTreeBase &DT) : DT(DT), useLiveIn(false) {} - /// \brief Give the IDF calculator the set of blocks in which the value is + /// Give the IDF calculator the set of blocks in which the value is /// defined. This is equivalent to the set of starting blocks it should be /// calculating the IDF for (though later gets pruned based on liveness). /// @@ -57,7 +57,7 @@ class IDFCalculator { DefBlocks = &Blocks; } - /// \brief Give the IDF calculator the set of blocks in which the value is + /// Give the IDF calculator the set of blocks in which the value is /// live on entry to the block. This is used to prune the IDF calculation to /// not include blocks where any phi insertion would be dead. /// @@ -68,14 +68,14 @@ class IDFCalculator { useLiveIn = true; } - /// \brief Reset the live-in block set to be empty, and tell the IDF + /// Reset the live-in block set to be empty, and tell the IDF /// calculator to not use liveness anymore. void resetLiveInBlocks() { LiveInBlocks = nullptr; useLiveIn = false; } - /// \brief Calculate iterated dominance frontiers + /// Calculate iterated dominance frontiers /// /// This uses the linear-time phi algorithm based on DJ-graphs mentioned in /// the file-level comment. It performs DF->IDF pruning using the live-in diff --git a/include/llvm/Analysis/LazyBlockFrequencyInfo.h b/include/llvm/Analysis/LazyBlockFrequencyInfo.h index 71ce0842f6a994f833f36520da9eae4ed01aba85..d1afb63d7e08670227c78d9f9e39e80086d2715f 100644 --- a/include/llvm/Analysis/LazyBlockFrequencyInfo.h +++ b/include/llvm/Analysis/LazyBlockFrequencyInfo.h @@ -75,7 +75,7 @@ private: const LoopInfoT *LI; }; -/// \brief This is an alternative analysis pass to +/// This is an alternative analysis pass to /// BlockFrequencyInfoWrapperPass. The difference is that with this pass the /// block frequencies are not computed when the analysis pass is executed but /// rather when the BFI result is explicitly requested by the analysis client. @@ -109,10 +109,10 @@ public: LazyBlockFrequencyInfoPass(); - /// \brief Compute and return the block frequencies. + /// Compute and return the block frequencies. BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); } - /// \brief Compute and return the block frequencies. + /// Compute and return the block frequencies. const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); } void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -126,7 +126,7 @@ public: void print(raw_ostream &OS, const Module *M) const override; }; -/// \brief Helper for client passes to initialize dependent passes for LBFI. +/// Helper for client passes to initialize dependent passes for LBFI. void initializeLazyBFIPassPass(PassRegistry &Registry); } #endif diff --git a/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/include/llvm/Analysis/LazyBranchProbabilityInfo.h index e1d404b1ada23444338f9ce8ebf4b88599a98e0b..9e6bcfedcbb94486bb23bc2926d3ae34eb9171bc 100644 --- a/include/llvm/Analysis/LazyBranchProbabilityInfo.h +++ b/include/llvm/Analysis/LazyBranchProbabilityInfo.h @@ -26,7 +26,7 @@ class Function; class LoopInfo; class TargetLibraryInfo; -/// \brief This is an alternative analysis pass to +/// This is an alternative analysis pass to /// BranchProbabilityInfoWrapperPass. The difference is that with this pass the /// branch probabilities are not computed when the analysis pass is executed but /// rather when the BPI results is explicitly requested by the analysis client. @@ -89,10 +89,10 @@ public: LazyBranchProbabilityInfoPass(); - /// \brief Compute and return the branch probabilities. + /// Compute and return the branch probabilities. BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); } - /// \brief Compute and return the branch probabilities. + /// Compute and return the branch probabilities. const BranchProbabilityInfo &getBPI() const { return LBPI->getCalculated(); } void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -106,10 +106,10 @@ public: void print(raw_ostream &OS, const Module *M) const override; }; -/// \brief Helper for client passes to initialize dependent passes for LBPI. +/// Helper for client passes to initialize dependent passes for LBPI. void initializeLazyBPIPassPass(PassRegistry &Registry); -/// \brief Simple trait class that provides a mapping between BPI passes and the +/// Simple trait class that provides a mapping between BPI passes and the /// corresponding BPInfo. template struct BPIPassTrait { static PassT &getBPI(PassT *P) { return *P; } diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h index cea5bf0df80edc1a45022c1b4752af845ae34e3c..1a4fdb59142778f3e2738bdb140dd5989f8562dc 100644 --- a/include/llvm/Analysis/LazyValueInfo.h +++ b/include/llvm/Analysis/LazyValueInfo.h @@ -128,7 +128,7 @@ public: FunctionAnalysisManager::Invalidator &Inv); }; -/// \brief Analysis to compute lazy value information. +/// Analysis to compute lazy value information. class LazyValueAnalysis : public AnalysisInfoMixin { public: typedef LazyValueInfo Result; diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h index 7c88b137ec3b10ac2c56126bd2a4a92621534ae1..db5919fd91c72d175ca8d79381785d79dcb3c370 100644 --- a/include/llvm/Analysis/Lint.h +++ b/include/llvm/Analysis/Lint.h @@ -26,12 +26,12 @@ class FunctionPass; class Module; class Function; -/// @brief Create a lint pass. +/// Create a lint pass. /// /// Check a module or function. FunctionPass *createLintPass(); -/// @brief Check a module. +/// Check a module. /// /// This should only be used for debugging, because it plays games with /// PassManagers and stuff. diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 28154c873b70903f0fb21de73e4ab4b9e0147ce2..0f3f2be9aeb4ea330df9cd2018fafc839beac177 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -38,25 +38,25 @@ class SCEVUnionPredicate; class LoopAccessInfo; class OptimizationRemarkEmitter; -/// \brief Collection of parameters shared beetween the Loop Vectorizer and the +/// Collection of parameters shared beetween the Loop Vectorizer and the /// Loop Access Analysis. struct VectorizerParams { - /// \brief Maximum SIMD width. + /// Maximum SIMD width. static const unsigned MaxVectorWidth; - /// \brief VF as overridden by the user. + /// VF as overridden by the user. static unsigned VectorizationFactor; - /// \brief Interleave factor as overridden by the user. + /// Interleave factor as overridden by the user. static unsigned VectorizationInterleave; - /// \brief True if force-vector-interleave was specified by the user. + /// True if force-vector-interleave was specified by the user. static bool isInterleaveForced(); - /// \\brief When performing memory disambiguation checks at runtime do not + /// \When performing memory disambiguation checks at runtime do not /// make more than this number of comparisons. static unsigned RuntimeMemoryCheckThreshold; }; -/// \brief Checks memory dependences among accesses to the same underlying +/// Checks memory dependences among accesses to the same underlying /// object to determine whether there vectorization is legal or not (and at /// which vectorization factor). /// @@ -94,12 +94,12 @@ class MemoryDepChecker { public: typedef PointerIntPair MemAccessInfo; typedef SmallVector MemAccessInfoList; - /// \brief Set of potential dependent memory accesses. + /// Set of potential dependent memory accesses. typedef EquivalenceClasses DepCandidates; - /// \brief Dependece between memory access instructions. + /// Dependece between memory access instructions. struct Dependence { - /// \brief The type of the dependence. + /// The type of the dependence. enum DepType { // No dependence. NoDep, @@ -127,36 +127,36 @@ public: BackwardVectorizableButPreventsForwarding }; - /// \brief String version of the types. + /// String version of the types. static const char *DepName[]; - /// \brief Index of the source of the dependence in the InstMap vector. + /// Index of the source of the dependence in the InstMap vector. unsigned Source; - /// \brief Index of the destination of the dependence in the InstMap vector. + /// Index of the destination of the dependence in the InstMap vector. unsigned Destination; - /// \brief The type of the dependence. + /// The type of the dependence. DepType Type; Dependence(unsigned Source, unsigned Destination, DepType Type) : Source(Source), Destination(Destination), Type(Type) {} - /// \brief Return the source instruction of the dependence. + /// Return the source instruction of the dependence. Instruction *getSource(const LoopAccessInfo &LAI) const; - /// \brief Return the destination instruction of the dependence. + /// Return the destination instruction of the dependence. Instruction *getDestination(const LoopAccessInfo &LAI) const; - /// \brief Dependence types that don't prevent vectorization. + /// Dependence types that don't prevent vectorization. static bool isSafeForVectorization(DepType Type); - /// \brief Lexically forward dependence. + /// Lexically forward dependence. bool isForward() const; - /// \brief Lexically backward dependence. + /// Lexically backward dependence. bool isBackward() const; - /// \brief May be a lexically backward dependence type (includes Unknown). + /// May be a lexically backward dependence type (includes Unknown). bool isPossiblyBackward() const; - /// \brief Print the dependence. \p Instr is used to map the instruction + /// Print the dependence. \p Instr is used to map the instruction /// indices to instructions. void print(raw_ostream &OS, unsigned Depth, const SmallVectorImpl &Instrs) const; @@ -167,7 +167,7 @@ public: ShouldRetryWithRuntimeCheck(false), SafeForVectorization(true), RecordDependences(true) {} - /// \brief Register the location (instructions are given increasing numbers) + /// Register the location (instructions are given increasing numbers) /// of a write access. void addAccess(StoreInst *SI) { Value *Ptr = SI->getPointerOperand(); @@ -176,7 +176,7 @@ public: ++AccessIdx; } - /// \brief Register the location (instructions are given increasing numbers) + /// Register the location (instructions are given increasing numbers) /// of a write access. void addAccess(LoadInst *LI) { Value *Ptr = LI->getPointerOperand(); @@ -185,29 +185,29 @@ public: ++AccessIdx; } - /// \brief Check whether the dependencies between the accesses are safe. + /// Check whether the dependencies between the accesses are safe. /// /// Only checks sets with elements in \p CheckDeps. bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoList &CheckDeps, const ValueToValueMap &Strides); - /// \brief No memory dependence was encountered that would inhibit + /// No memory dependence was encountered that would inhibit /// vectorization. bool isSafeForVectorization() const { return SafeForVectorization; } - /// \brief The maximum number of bytes of a vector register we can vectorize + /// The maximum number of bytes of a vector register we can vectorize /// the accesses safely with. uint64_t getMaxSafeDepDistBytes() { return MaxSafeDepDistBytes; } - /// \brief Return the number of elements that are safe to operate on + /// Return the number of elements that are safe to operate on /// simultaneously, multiplied by the size of the element in bits. uint64_t getMaxSafeRegisterWidth() const { return MaxSafeRegisterWidth; } - /// \brief In same cases when the dependency check fails we can still + /// In same cases when the dependency check fails we can still /// vectorize the loop with a dynamic array access check. bool shouldRetryWithRuntimeCheck() { return ShouldRetryWithRuntimeCheck; } - /// \brief Returns the memory dependences. If null is returned we exceeded + /// Returns the memory dependences. If null is returned we exceeded /// the MaxDependences threshold and this information is not /// available. const SmallVectorImpl *getDependences() const { @@ -216,13 +216,13 @@ public: void clearDependences() { Dependences.clear(); } - /// \brief The vector of memory access instructions. The indices are used as + /// The vector of memory access instructions. The indices are used as /// instruction identifiers in the Dependence class. const SmallVectorImpl &getMemoryInstructions() const { return InstMap; } - /// \brief Generate a mapping between the memory instructions and their + /// Generate a mapping between the memory instructions and their /// indices according to program order. DenseMap generateInstructionOrderMap() const { DenseMap OrderMap; @@ -233,7 +233,7 @@ public: return OrderMap; } - /// \brief Find the set of instructions that read or write via \p Ptr. + /// Find the set of instructions that read or write via \p Ptr. SmallVector getInstructionsForAccess(Value *Ptr, bool isWrite) const; @@ -247,42 +247,42 @@ private: PredicatedScalarEvolution &PSE; const Loop *InnermostLoop; - /// \brief Maps access locations (ptr, read/write) to program order. + /// Maps access locations (ptr, read/write) to program order. DenseMap > Accesses; - /// \brief Memory access instructions in program order. + /// Memory access instructions in program order. SmallVector InstMap; - /// \brief The program order index to be used for the next instruction. + /// The program order index to be used for the next instruction. unsigned AccessIdx; // We can access this many bytes in parallel safely. uint64_t MaxSafeDepDistBytes; - /// \brief Number of elements (from consecutive iterations) that are safe to + /// Number of elements (from consecutive iterations) that are safe to /// operate on simultaneously, multiplied by the size of the element in bits. /// The size of the element is taken from the memory access that is most /// restrictive. uint64_t MaxSafeRegisterWidth; - /// \brief If we see a non-constant dependence distance we can still try to + /// If we see a non-constant dependence distance we can still try to /// vectorize this loop with runtime checks. bool ShouldRetryWithRuntimeCheck; - /// \brief No memory dependence was encountered that would inhibit + /// No memory dependence was encountered that would inhibit /// vectorization. bool SafeForVectorization; - //// \brief True if Dependences reflects the dependences in the + //// True if Dependences reflects the dependences in the //// loop. If false we exceeded MaxDependences and //// Dependences is invalid. bool RecordDependences; - /// \brief Memory dependences collected during the analysis. Only valid if + /// Memory dependences collected during the analysis. Only valid if /// RecordDependences is true. SmallVector Dependences; - /// \brief Check whether there is a plausible dependence between the two + /// Check whether there is a plausible dependence between the two /// accesses. /// /// Access \p A must happen before \p B in program order. The two indices @@ -298,7 +298,7 @@ private: const MemAccessInfo &B, unsigned BIdx, const ValueToValueMap &Strides); - /// \brief Check whether the data dependence could prevent store-load + /// Check whether the data dependence could prevent store-load /// forwarding. /// /// \return false if we shouldn't vectorize at all or avoid larger @@ -306,7 +306,7 @@ private: bool couldPreventStoreLoadForward(uint64_t Distance, uint64_t TypeByteSize); }; -/// \brief Holds information about the memory runtime legality checks to verify +/// Holds information about the memory runtime legality checks to verify /// that a group of pointers do not overlap. class RuntimePointerChecking { public: @@ -355,13 +355,13 @@ public: unsigned ASId, const ValueToValueMap &Strides, PredicatedScalarEvolution &PSE); - /// \brief No run-time memory checking is necessary. + /// No run-time memory checking is necessary. bool empty() const { return Pointers.empty(); } /// A grouping of pointers. A single memcheck is required between /// two groups. struct CheckingPtrGroup { - /// \brief Create a new pointer checking group containing a single + /// Create a new pointer checking group containing a single /// pointer, with index \p Index in RtCheck. CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck) : RtCheck(RtCheck), High(RtCheck.Pointers[Index].End), @@ -369,7 +369,7 @@ public: Members.push_back(Index); } - /// \brief Tries to add the pointer recorded in RtCheck at index + /// Tries to add the pointer recorded in RtCheck at index /// \p Index to this pointer checking group. We can only add a pointer /// to a checking group if we will still be able to get /// the upper and lower bounds of the check. Returns true in case @@ -390,7 +390,7 @@ public: SmallVector Members; }; - /// \brief A memcheck which made up of a pair of grouped pointers. + /// A memcheck which made up of a pair of grouped pointers. /// /// These *have* to be const for now, since checks are generated from /// CheckingPtrGroups in LAI::addRuntimeChecks which is a const member @@ -399,24 +399,24 @@ public: typedef std::pair PointerCheck; - /// \brief Generate the checks and store it. This also performs the grouping + /// Generate the checks and store it. This also performs the grouping /// of pointers to reduce the number of memchecks necessary. void generateChecks(MemoryDepChecker::DepCandidates &DepCands, bool UseDependencies); - /// \brief Returns the checks that generateChecks created. + /// Returns the checks that generateChecks created. const SmallVector &getChecks() const { return Checks; } - /// \brief Decide if we need to add a check between two groups of pointers, + /// Decide if we need to add a check between two groups of pointers, /// according to needsChecking. bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N) const; - /// \brief Returns the number of run-time checks required according to + /// Returns the number of run-time checks required according to /// needsChecking. unsigned getNumberOfChecks() const { return Checks.size(); } - /// \brief Print the list run-time memory checks necessary. + /// Print the list run-time memory checks necessary. void print(raw_ostream &OS, unsigned Depth = 0) const; /// Print \p Checks. @@ -432,7 +432,7 @@ public: /// Holds a partitioning of pointers into "check groups". SmallVector CheckingGroups; - /// \brief Check if pointers are in the same partition + /// Check if pointers are in the same partition /// /// \p PtrToPartition contains the partition number for pointers (-1 if the /// pointer belongs to multiple partitions). @@ -440,17 +440,17 @@ public: arePointersInSamePartition(const SmallVectorImpl &PtrToPartition, unsigned PtrIdx1, unsigned PtrIdx2); - /// \brief Decide whether we need to issue a run-time check for pointer at + /// Decide whether we need to issue a run-time check for pointer at /// index \p I and \p J to prove their independence. bool needsChecking(unsigned I, unsigned J) const; - /// \brief Return PointerInfo for pointer at index \p PtrIdx. + /// Return PointerInfo for pointer at index \p PtrIdx. const PointerInfo &getPointerInfo(unsigned PtrIdx) const { return Pointers[PtrIdx]; } private: - /// \brief Groups pointers such that a single memcheck is required + /// Groups pointers such that a single memcheck is required /// between two different groups. This will clear the CheckingGroups vector /// and re-compute it. We will only group dependecies if \p UseDependencies /// is true, otherwise we will create a separate group for each pointer. @@ -464,12 +464,12 @@ private: /// Holds a pointer to the ScalarEvolution analysis. ScalarEvolution *SE; - /// \brief Set of run-time checks required to establish independence of + /// Set of run-time checks required to establish independence of /// otherwise may-aliasing pointers in the loop. SmallVector Checks; }; -/// \brief Drive the analysis of memory accesses in the loop +/// Drive the analysis of memory accesses in the loop /// /// This class is responsible for analyzing the memory accesses of a loop. It /// collects the accesses and then its main helper the AccessAnalysis class @@ -503,7 +503,7 @@ public: return PtrRtChecking.get(); } - /// \brief Number of memchecks required to prove independence of otherwise + /// Number of memchecks required to prove independence of otherwise /// may-alias pointers. unsigned getNumRuntimePointerChecks() const { return PtrRtChecking->getNumberOfChecks(); @@ -521,7 +521,7 @@ public: unsigned getNumStores() const { return NumStores; } unsigned getNumLoads() const { return NumLoads;} - /// \brief Add code that checks at runtime if the accessed arrays overlap. + /// Add code that checks at runtime if the accessed arrays overlap. /// /// Returns a pair of instructions where the first element is the first /// instruction generated in possibly a sequence of instructions and the @@ -529,7 +529,7 @@ public: std::pair addRuntimeChecks(Instruction *Loc) const; - /// \brief Generete the instructions for the checks in \p PointerChecks. + /// Generete the instructions for the checks in \p PointerChecks. /// /// Returns a pair of instructions where the first element is the first /// instruction generated in possibly a sequence of instructions and the @@ -539,32 +539,32 @@ public: const SmallVectorImpl &PointerChecks) const; - /// \brief The diagnostics report generated for the analysis. E.g. why we + /// The diagnostics report generated for the analysis. E.g. why we /// couldn't analyze the loop. const OptimizationRemarkAnalysis *getReport() const { return Report.get(); } - /// \brief the Memory Dependence Checker which can determine the + /// the Memory Dependence Checker which can determine the /// loop-independent and loop-carried dependences between memory accesses. const MemoryDepChecker &getDepChecker() const { return *DepChecker; } - /// \brief Return the list of instructions that use \p Ptr to read or write + /// Return the list of instructions that use \p Ptr to read or write /// memory. SmallVector getInstructionsForAccess(Value *Ptr, bool isWrite) const { return DepChecker->getInstructionsForAccess(Ptr, isWrite); } - /// \brief If an access has a symbolic strides, this maps the pointer value to + /// If an access has a symbolic strides, this maps the pointer value to /// the stride symbol. const ValueToValueMap &getSymbolicStrides() const { return SymbolicStrides; } - /// \brief Pointer has a symbolic stride. + /// Pointer has a symbolic stride. bool hasStride(Value *V) const { return StrideSet.count(V); } - /// \brief Print the information about the memory accesses in the loop. + /// Print the information about the memory accesses in the loop. void print(raw_ostream &OS, unsigned Depth = 0) const; - /// \brief Checks existence of store to invariant address inside loop. + /// Checks existence of store to invariant address inside loop. /// If the loop has any store to invariant address, then it returns true, /// else returns false. bool hasStoreToLoopInvariantAddress() const { @@ -579,15 +579,15 @@ public: const PredicatedScalarEvolution &getPSE() const { return *PSE; } private: - /// \brief Analyze the loop. + /// Analyze the loop. void analyzeLoop(AliasAnalysis *AA, LoopInfo *LI, const TargetLibraryInfo *TLI, DominatorTree *DT); - /// \brief Check if the structure of the loop allows it to be analyzed by this + /// Check if the structure of the loop allows it to be analyzed by this /// pass. bool canAnalyzeLoop(); - /// \brief Save the analysis remark. + /// Save the analysis remark. /// /// LAA does not directly emits the remarks. Instead it stores it which the /// client can retrieve and presents as its own analysis @@ -595,7 +595,7 @@ private: OptimizationRemarkAnalysis &recordAnalysis(StringRef RemarkName, Instruction *Instr = nullptr); - /// \brief Collect memory access with loop invariant strides. + /// Collect memory access with loop invariant strides. /// /// Looks for accesses like "a[i * StrideA]" where "StrideA" is loop /// invariant. @@ -607,7 +607,7 @@ private: /// at runtime. Using std::unique_ptr to make using move ctor simpler. std::unique_ptr PtrRtChecking; - /// \brief the Memory Dependence Checker which can determine the + /// the Memory Dependence Checker which can determine the /// loop-independent and loop-carried dependences between memory accesses. std::unique_ptr DepChecker; @@ -618,28 +618,28 @@ private: uint64_t MaxSafeDepDistBytes; - /// \brief Cache the result of analyzeLoop. + /// Cache the result of analyzeLoop. bool CanVecMem; - /// \brief Indicator for storing to uniform addresses. + /// Indicator for storing to uniform addresses. /// If a loop has write to a loop invariant address then it should be true. bool StoreToLoopInvariantAddress; - /// \brief The diagnostics report generated for the analysis. E.g. why we + /// The diagnostics report generated for the analysis. E.g. why we /// couldn't analyze the loop. std::unique_ptr Report; - /// \brief If an access has a symbolic strides, this maps the pointer value to + /// If an access has a symbolic strides, this maps the pointer value to /// the stride symbol. ValueToValueMap SymbolicStrides; - /// \brief Set of symbolic strides values. + /// Set of symbolic strides values. SmallPtrSet StrideSet; }; Value *stripIntegerCast(Value *V); -/// \brief Return the SCEV corresponding to a pointer with the symbolic stride +/// Return the SCEV corresponding to a pointer with the symbolic stride /// replaced with constant one, assuming the SCEV predicate associated with /// \p PSE is true. /// @@ -653,7 +653,7 @@ const SCEV *replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE, const ValueToValueMap &PtrToStride, Value *Ptr, Value *OrigPtr = nullptr); -/// \brief If the pointer has a constant stride return it in units of its +/// If the pointer has a constant stride return it in units of its /// element size. Otherwise return zero. /// /// Ensure that it does not wrap in the address space, assuming the predicate @@ -667,12 +667,26 @@ int64_t getPtrStride(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp, const ValueToValueMap &StridesMap = ValueToValueMap(), bool Assume = false, bool ShouldCheckWrap = true); -/// \brief Returns true if the memory operations \p A and \p B are consecutive. +/// Attempt to sort the pointers in \p VL and return the sorted indices +/// in \p SortedIndices, if reordering is required. +/// +/// Returns 'true' if sorting is legal, otherwise returns 'false'. +/// +/// For example, for a given \p VL of memory accesses in program order, a[i+4], +/// a[i+0], a[i+1] and a[i+7], this function will sort the \p VL and save the +/// sorted indices in \p SortedIndices as a[i+0], a[i+1], a[i+4], a[i+7] and +/// saves the mask for actual memory accesses in program order in +/// \p SortedIndices as <1,2,0,3> +bool sortPtrAccesses(ArrayRef VL, const DataLayout &DL, + ScalarEvolution &SE, + SmallVectorImpl &SortedIndices); + +/// Returns true if the memory operations \p A and \p B are consecutive. /// This is a simple API that does not depend on the analysis pass. bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, ScalarEvolution &SE, bool CheckType = true); -/// \brief This analysis provides dependence information for the memory accesses +/// This analysis provides dependence information for the memory accesses /// of a loop. /// /// It runs the analysis for a loop on demand. This can be initiated by @@ -691,7 +705,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; - /// \brief Query the result of the loop access information for the loop \p L. + /// Query the result of the loop access information for the loop \p L. /// /// If there is no cached result available run the analysis. const LoopAccessInfo &getInfo(Loop *L); @@ -701,11 +715,11 @@ public: LoopAccessInfoMap.clear(); } - /// \brief Print the result of the analysis when invoked with -analyze. + /// Print the result of the analysis when invoked with -analyze. void print(raw_ostream &OS, const Module *M = nullptr) const override; private: - /// \brief The cache. + /// The cache. DenseMap> LoopAccessInfoMap; // The used analysis passes. @@ -716,7 +730,7 @@ private: LoopInfo *LI; }; -/// \brief This analysis provides dependence information for the memory +/// This analysis provides dependence information for the memory /// accesses of a loop. /// /// It runs the analysis for a loop on demand. This can be initiated by diff --git a/include/llvm/Analysis/LoopAnalysisManager.h b/include/llvm/Analysis/LoopAnalysisManager.h index 417ee979ce978b53faa6c170f6b274a4e429b354..00e562c4f31f0bb71807179a2efdbec3f7437c8c 100644 --- a/include/llvm/Analysis/LoopAnalysisManager.h +++ b/include/llvm/Analysis/LoopAnalysisManager.h @@ -69,7 +69,7 @@ extern cl::opt EnableMSSALoopDependency; extern template class AllAnalysesOn; extern template class AnalysisManager; -/// \brief The loop analysis manager. +/// The loop analysis manager. /// /// See the documentation for the AnalysisManager template for detail /// documentation. This typedef serves as a convenient way to refer to this diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 28afc39727fabc9667684ad4885b3613d3aa7b26..cdc8d0a189597dcf7964b4ad75341adc8c91dd00 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -178,6 +178,12 @@ public: return DenseBlockSet; } + /// Return a direct, immutable handle to the blocks set. + const SmallPtrSetImpl &getBlocksSet() const { + assert(!isInvalid() && "Loop not in a valid state!"); + return DenseBlockSet; + } + /// Return true if this loop is no longer valid. The only valid use of this /// helper is "assert(L.isInvalid())" or equivalent, since IsInvalid is set to /// true by the destructor. In other words, if this accessor returns true, @@ -438,7 +444,7 @@ extern template class LoopBase; /// in the CFG are necessarily loops. class Loop : public LoopBase { public: - /// \brief A range representing the start and end location of a loop. + /// A range representing the start and end location of a loop. class LocRange { DebugLoc Start; DebugLoc End; @@ -452,7 +458,7 @@ public: const DebugLoc &getStart() const { return Start; } const DebugLoc &getEnd() const { return End; } - /// \brief Check for null. + /// Check for null. /// explicit operator bool() const { return Start && End; } }; @@ -527,7 +533,7 @@ public: /// /// If this loop contains the same llvm.loop metadata on each branch to the /// header then the node is returned. If any latch instruction does not - /// contain llvm.loop or or if multiple latches contain different nodes then + /// contain llvm.loop or if multiple latches contain different nodes then /// 0 is returned. MDNode *getLoopID() const; /// Set the llvm.loop loop id metadata for this loop. @@ -929,7 +935,7 @@ template <> struct GraphTraits { static ChildIteratorType child_end(NodeRef N) { return N->end(); } }; -/// \brief Analysis pass that exposes the \c LoopInfo for a function. +/// Analysis pass that exposes the \c LoopInfo for a function. class LoopAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; static AnalysisKey Key; @@ -940,7 +946,7 @@ public: LoopInfo run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for the \c LoopAnalysis results. +/// Printer pass for the \c LoopAnalysis results. class LoopPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -949,12 +955,12 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Verifier pass for the \c LoopAnalysis results. +/// Verifier pass for the \c LoopAnalysis results. struct LoopVerifierPass : public PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief The legacy pass manager's analysis pass to compute loop information. +/// The legacy pass manager's analysis pass to compute loop information. class LoopInfoWrapperPass : public FunctionPass { LoopInfo LI; @@ -968,7 +974,7 @@ public: LoopInfo &getLoopInfo() { return LI; } const LoopInfo &getLoopInfo() const { return LI; } - /// \brief Calculate the natural loop information for a given function. + /// Calculate the natural loop information for a given function. bool runOnFunction(Function &F) override; void verifyAnalysis() const override; diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index b3a16b5369f7b3d94b82c10c8d94eb3415256edd..e26204591072275effe09f93fa9629905590b237 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -572,8 +572,8 @@ void LoopInfoBase::print(raw_ostream &OS) const { template bool compareVectors(std::vector &BB1, std::vector &BB2) { - std::sort(BB1.begin(), BB1.end()); - std::sort(BB2.begin(), BB2.end()); + llvm::sort(BB1.begin(), BB1.end()); + llvm::sort(BB2.begin(), BB2.end()); return BB1 == BB2; } @@ -617,6 +617,15 @@ static void compareLoops(const LoopT *L, const LoopT *OtherL, std::vector OtherBBs = OtherL->getBlocks(); assert(compareVectors(BBs, OtherBBs) && "Mismatched basic blocks in the loops!"); + + const SmallPtrSetImpl &BlocksSet = L->getBlocksSet(); + const SmallPtrSetImpl &OtherBlocksSet = L->getBlocksSet(); + assert(BlocksSet.size() == OtherBlocksSet.size() && + std::all_of(BlocksSet.begin(), BlocksSet.end(), + [&OtherBlocksSet](const BlockT *BB) { + return OtherBlocksSet.count(BB); + }) && + "Mismatched basic blocks in BlocksSets!"); } #endif @@ -636,6 +645,9 @@ void LoopInfoBase::verify( LoopT *L = Entry.second; assert(Loops.count(L) && "orphaned loop"); assert(L->contains(BB) && "orphaned block"); + for (LoopT *ChildLoop : *L) + assert(!ChildLoop->contains(BB) && + "BBMap should point to the innermost loop containing BB"); } // Recompute LoopInfo to verify loops structure. diff --git a/include/llvm/Analysis/LoopUnrollAnalyzer.h b/include/llvm/Analysis/LoopUnrollAnalyzer.h index 80f3e5fdcd436871931114745867450009f95ada..f45bf0b223b8ec18b2a6bef9fb71758ab21cca5b 100644 --- a/include/llvm/Analysis/LoopUnrollAnalyzer.h +++ b/include/llvm/Analysis/LoopUnrollAnalyzer.h @@ -57,7 +57,7 @@ public: using Base::visit; private: - /// \brief A cache of pointer bases and constant-folded offsets corresponding + /// A cache of pointer bases and constant-folded offsets corresponding /// to GEP (or derived from GEP) instructions. /// /// In order to find the base pointer one needs to perform non-trivial @@ -65,11 +65,11 @@ private: /// results saved. DenseMap SimplifiedAddresses; - /// \brief SCEV expression corresponding to number of currently simulated + /// SCEV expression corresponding to number of currently simulated /// iteration. const SCEV *IterationNumber; - /// \brief A Value->Constant map for keeping values that we managed to + /// A Value->Constant map for keeping values that we managed to /// constant-fold on the given iteration. /// /// While we walk the loop instructions, we build up and maintain a mapping diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 7d53e34938b797e903d559d9d8166a4bb86786fe..5418128f16ef840b5fd8f1c4786e35940f599f58 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -53,33 +53,33 @@ class Type; class UndefValue; class Value; -/// \brief Tests if a value is a call or invoke to a library function that +/// Tests if a value is a call or invoke to a library function that /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup /// like). bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); -/// \brief Tests if a value is a call or invoke to a function that returns a +/// Tests if a value is a call or invoke to a function that returns a /// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions). bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); -/// \brief Tests if a value is a call or invoke to a library function that +/// Tests if a value is a call or invoke to a library function that /// allocates uninitialized memory (such as malloc). bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); -/// \brief Tests if a value is a call or invoke to a library function that +/// Tests if a value is a call or invoke to a library function that /// allocates zero-filled memory (such as calloc). bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); -/// \brief Tests if a value is a call or invoke to a library function that +/// Tests if a value is a call or invoke to a library function that /// allocates memory similar to malloc or calloc. bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); -/// \brief Tests if a value is a call or invoke to a library function that +/// Tests if a value is a call or invoke to a library function that /// allocates memory (either malloc, calloc, or strdup like). bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); @@ -170,14 +170,14 @@ struct ObjectSizeOpts { bool NullIsUnknownSize = false; }; -/// \brief Compute the size of the object pointed by Ptr. Returns true and the +/// Compute the size of the object pointed by Ptr. Returns true and the /// object size in Size if successful, and false otherwise. In this context, by /// object we mean the region of memory starting at Ptr to the end of the /// underlying object pointed to by Ptr. bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {}); -/// Try to turn a call to @llvm.objectsize into an integer value of the given +/// Try to turn a call to \@llvm.objectsize into an integer value of the given /// Type. Returns null on failure. /// If MustSucceed is true, this function will not return null, and may return /// conservative values governed by the second argument of the call to @@ -189,7 +189,7 @@ ConstantInt *lowerObjectSizeCall(IntrinsicInst *ObjectSize, using SizeOffsetType = std::pair; -/// \brief Evaluate the size and offset of an object pointed to by a Value* +/// Evaluate the size and offset of an object pointed to by a Value* /// statically. Fails if size or offset are not known at compile time. class ObjectSizeOffsetVisitor : public InstVisitor { @@ -248,7 +248,7 @@ private: using SizeOffsetEvalType = std::pair; -/// \brief Evaluate the size and offset of an object pointed to by a Value*. +/// Evaluate the size and offset of an object pointed to by a Value*. /// May create code to compute the result at run-time. class ObjectSizeOffsetEvaluator : public InstVisitor { diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index c2974525a6ff8932ed39ba9a8ff52f2e98fbac27..1c6ec98dfedc62020b1ca56efe189ffe80cbc9c7 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -26,6 +26,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/PredIteratorCache.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" #include @@ -302,7 +303,7 @@ private: /// The maximum size of the dereferences of the pointer. /// /// May be UnknownSize if the sizes are unknown. - uint64_t Size = MemoryLocation::UnknownSize; + LocationSize Size = MemoryLocation::UnknownSize; /// The AA tags associated with dereferences of the pointer. /// /// The members may be null if there are no tags or conflicting tags. @@ -314,7 +315,10 @@ private: /// Cache storing single nonlocal def for the instruction. /// It is set when nonlocal def would be found in function returning only /// local dependencies. - DenseMap NonLocalDefsCache; + DenseMap, NonLocalDepResult> NonLocalDefsCache; + using ReverseNonLocalDefsCacheTy = + DenseMap>; + ReverseNonLocalDefsCacheTy ReverseNonLocalDefsCache; /// This map stores the cached results of doing a pointer lookup at the /// bottom of a block. diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h index c1080742e83a2508a01182a4d5b710979043cea0..6b680000312c82dce662877b0237b8f233513225 100644 --- a/include/llvm/Analysis/MemoryLocation.h +++ b/include/llvm/Analysis/MemoryLocation.h @@ -27,8 +27,16 @@ class LoadInst; class StoreInst; class MemTransferInst; class MemIntrinsic; +class AtomicMemTransferInst; +class AtomicMemIntrinsic; +class AnyMemTransferInst; +class AnyMemIntrinsic; class TargetLibraryInfo; +// Represents the size of a MemoryLocation. Logically, it's an +// Optional, with a special UnknownSize value from `MemoryLocation`. +using LocationSize = uint64_t; + /// Representation for a specific memory location. /// /// This abstraction can be used to represent a specific location in memory. @@ -55,7 +63,7 @@ public: /// virtual address space, because there are restrictions on stepping out of /// one object and into another. See /// http://llvm.org/docs/LangRef.html#pointeraliasing - uint64_t Size; + LocationSize Size; /// The metadata nodes which describes the aliasing of the location (each /// member is null if that kind of information is unavailable). @@ -90,17 +98,21 @@ public: /// Return a location representing the source of a memory transfer. static MemoryLocation getForSource(const MemTransferInst *MTI); + static MemoryLocation getForSource(const AtomicMemTransferInst *MTI); + static MemoryLocation getForSource(const AnyMemTransferInst *MTI); /// Return a location representing the destination of a memory set or /// transfer. static MemoryLocation getForDest(const MemIntrinsic *MI); + static MemoryLocation getForDest(const AtomicMemIntrinsic *MI); + static MemoryLocation getForDest(const AnyMemIntrinsic *MI); /// Return a location representing a particular argument of a call. static MemoryLocation getForArgument(ImmutableCallSite CS, unsigned ArgIdx, const TargetLibraryInfo &TLI); explicit MemoryLocation(const Value *Ptr = nullptr, - uint64_t Size = UnknownSize, + LocationSize Size = UnknownSize, const AAMDNodes &AATags = AAMDNodes()) : Ptr(Ptr), Size(Size), AATags(AATags) {} @@ -110,7 +122,7 @@ public: return Copy; } - MemoryLocation getWithNewSize(uint64_t NewSize) const { + MemoryLocation getWithNewSize(LocationSize NewSize) const { MemoryLocation Copy(*this); Copy.Size = NewSize; return Copy; @@ -137,7 +149,7 @@ template <> struct DenseMapInfo { } static unsigned getHashValue(const MemoryLocation &Val) { return DenseMapInfo::getHashValue(Val.Ptr) ^ - DenseMapInfo::getHashValue(Val.Size) ^ + DenseMapInfo::getHashValue(Val.Size) ^ DenseMapInfo::getHashValue(Val.AATags); } static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) { diff --git a/include/llvm/Analysis/MemorySSA.h b/include/llvm/Analysis/MemorySSA.h index 289989060386525b8a82f890547a953c761155d5..3a5349a6e4d69ebc8a5cfd68bf4cd60b90bb1ec3 100644 --- a/include/llvm/Analysis/MemorySSA.h +++ b/include/llvm/Analysis/MemorySSA.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // /// \file -/// \brief This file exposes an interface to building/using memory SSA to +/// This file exposes an interface to building/using memory SSA to /// walk memory instructions using a use/def graph. /// /// Memory SSA class builds an SSA form that links together memory access @@ -130,7 +130,7 @@ using memoryaccess_def_iterator = memoryaccess_def_iterator_base; using const_memoryaccess_def_iterator = memoryaccess_def_iterator_base; -// \brief The base for all memory accesses. All memory accesses in a block are +// The base for all memory accesses. All memory accesses in a block are // linked together using an intrusive list. class MemoryAccess : public DerivedUser, @@ -159,11 +159,11 @@ public: void print(raw_ostream &OS) const; void dump() const; - /// \brief The user iterators for a memory access + /// The user iterators for a memory access using iterator = user_iterator; using const_iterator = const_user_iterator; - /// \brief This iterator walks over all of the defs in a given + /// This iterator walks over all of the defs in a given /// MemoryAccess. For MemoryPhi nodes, this walks arguments. For /// MemoryUse/MemoryDef, this walks the defining access. memoryaccess_def_iterator defs_begin(); @@ -171,7 +171,7 @@ public: memoryaccess_def_iterator defs_end(); const_memoryaccess_def_iterator defs_end() const; - /// \brief Get the iterators for the all access list and the defs only list + /// Get the iterators for the all access list and the defs only list /// We default to the all access list. AllAccessType::self_iterator getIterator() { return this->AllAccessType::getIterator(); @@ -205,11 +205,11 @@ protected: friend class MemoryUse; friend class MemoryUseOrDef; - /// \brief Used by MemorySSA to change the block of a MemoryAccess when it is + /// Used by MemorySSA to change the block of a MemoryAccess when it is /// moved. void setBlock(BasicBlock *BB) { Block = BB; } - /// \brief Used for debugging and tracking things about MemoryAccesses. + /// Used for debugging and tracking things about MemoryAccesses. /// Guaranteed unique among MemoryAccesses, no guarantees otherwise. inline unsigned getID() const; @@ -235,7 +235,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) { return OS; } -/// \brief Class that has the common methods + fields of memory uses/defs. It's +/// Class that has the common methods + fields of memory uses/defs. It's /// a little awkward to have, but there are many cases where we want either a /// use or def, and there are many cases where uses are needed (defs aren't /// acceptable), and vice-versa. @@ -248,10 +248,10 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); - /// \brief Get the instruction that this MemoryUse represents. + /// Get the instruction that this MemoryUse represents. Instruction *getMemoryInst() const { return MemoryInstruction; } - /// \brief Get the access that produces the memory state used by this Use. + /// Get the access that produces the memory state used by this Use. MemoryAccess *getDefiningAccess() const { return getOperand(0); } static bool classof(const Value *MA) { @@ -270,7 +270,7 @@ public: return OptimizedAccessAlias; } - /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to + /// Reset the ID of what this MemoryUse was optimized to, causing it to /// be rewalked by the walker if necessary. /// This really should only be called by tests. inline void resetOptimized(); @@ -313,7 +313,7 @@ struct OperandTraits : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUseOrDef, MemoryAccess) -/// \brief Represents read-only accesses to memory +/// Represents read-only accesses to memory /// /// In particular, the set of Instructions that will be represented by /// MemoryUse's is exactly the set of Instructions for which @@ -364,7 +364,7 @@ template <> struct OperandTraits : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUse, MemoryAccess) -/// \brief Represents a read-write access to memory, whether it is a must-alias, +/// Represents a read-write access to memory, whether it is a must-alias, /// or a may-alias. /// /// In particular, the set of Instructions that will be represented by @@ -424,7 +424,7 @@ template <> struct OperandTraits : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryDef, MemoryAccess) -/// \brief Represents phi nodes for memory accesses. +/// Represents phi nodes for memory accesses. /// /// These have the same semantic as regular phi nodes, with the exception that /// only one phi will ever exist in a given basic block. @@ -504,10 +504,10 @@ public: const_op_range incoming_values() const { return operands(); } - /// \brief Return the number of incoming edges + /// Return the number of incoming edges unsigned getNumIncomingValues() const { return getNumOperands(); } - /// \brief Return incoming value number x + /// Return incoming value number x MemoryAccess *getIncomingValue(unsigned I) const { return getOperand(I); } void setIncomingValue(unsigned I, MemoryAccess *V) { assert(V && "PHI node got a null value!"); @@ -517,17 +517,17 @@ public: static unsigned getOperandNumForIncomingValue(unsigned I) { return I; } static unsigned getIncomingValueNumForOperand(unsigned I) { return I; } - /// \brief Return incoming basic block number @p i. + /// Return incoming basic block number @p i. BasicBlock *getIncomingBlock(unsigned I) const { return block_begin()[I]; } - /// \brief Return incoming basic block corresponding + /// Return incoming basic block corresponding /// to an operand of the PHI. BasicBlock *getIncomingBlock(const Use &U) const { assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?"); return getIncomingBlock(unsigned(&U - op_begin())); } - /// \brief Return incoming basic block corresponding + /// Return incoming basic block corresponding /// to value use iterator. BasicBlock *getIncomingBlock(MemoryAccess::const_user_iterator I) const { return getIncomingBlock(I.getUse()); @@ -538,7 +538,7 @@ public: block_begin()[I] = BB; } - /// \brief Add an incoming value to the end of the PHI list + /// Add an incoming value to the end of the PHI list void addIncoming(MemoryAccess *V, BasicBlock *BB) { if (getNumOperands() == ReservedSpace) growOperands(); // Get more space! @@ -548,7 +548,7 @@ public: setIncomingBlock(getNumOperands() - 1, BB); } - /// \brief Return the first index of the specified basic + /// Return the first index of the specified basic /// block in the value list for this PHI. Returns -1 if no instance. int getBasicBlockIndex(const BasicBlock *BB) const { for (unsigned I = 0, E = getNumOperands(); I != E; ++I) @@ -557,7 +557,7 @@ public: return -1; } - Value *getIncomingValueForBlock(const BasicBlock *BB) const { + MemoryAccess *getIncomingValueForBlock(const BasicBlock *BB) const { int Idx = getBasicBlockIndex(BB); assert(Idx >= 0 && "Invalid basic block argument!"); return getIncomingValue(Idx); @@ -574,7 +574,7 @@ public: protected: friend class MemorySSA; - /// \brief this is more complicated than the generic + /// this is more complicated than the generic /// User::allocHungoffUses, because we have to allocate Uses for the incoming /// values and pointers to the incoming blocks, all in one allocation. void allocHungoffUses(unsigned N) { @@ -586,7 +586,7 @@ private: const unsigned ID; unsigned ReservedSpace; - /// \brief This grows the operand list in response to a push_back style of + /// This grows the operand list in response to a push_back style of /// operation. This grows the number of ops by 1.5 times. void growOperands() { unsigned E = getNumOperands(); @@ -635,7 +635,7 @@ inline void MemoryUseOrDef::resetOptimized() { template <> struct OperandTraits : public HungoffOperandTraits<2> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess) -/// \brief Encapsulates MemorySSA, including all data associated with memory +/// Encapsulates MemorySSA, including all data associated with memory /// accesses. class MemorySSA { public: @@ -644,7 +644,7 @@ public: MemorySSAWalker *getWalker(); - /// \brief Given a memory Mod/Ref'ing instruction, get the MemorySSA + /// Given a memory Mod/Ref'ing instruction, get the MemorySSA /// access associated with it. If passed a basic block gets the memory phi /// node that exists for that block, if there is one. Otherwise, this will get /// a MemoryUseOrDef. @@ -654,7 +654,7 @@ public: void dump() const; void print(raw_ostream &) const; - /// \brief Return true if \p MA represents the live on entry value + /// Return true if \p MA represents the live on entry value /// /// Loads and stores from pointer arguments and other global values may be /// defined by memory operations that do not occur in the current function, so @@ -678,14 +678,14 @@ public: using DefsList = simple_ilist>; - /// \brief Return the list of MemoryAccess's for a given basic block. + /// Return the list of MemoryAccess's for a given basic block. /// /// This list is not modifiable by the user. const AccessList *getBlockAccesses(const BasicBlock *BB) const { return getWritableBlockAccesses(BB); } - /// \brief Return the list of MemoryDef's and MemoryPhi's for a given basic + /// Return the list of MemoryDef's and MemoryPhi's for a given basic /// block. /// /// This list is not modifiable by the user. @@ -693,19 +693,19 @@ public: return getWritableBlockDefs(BB); } - /// \brief Given two memory accesses in the same basic block, determine + /// Given two memory accesses in the same basic block, determine /// whether MemoryAccess \p A dominates MemoryAccess \p B. bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const; - /// \brief Given two memory accesses in potentially different blocks, + /// Given two memory accesses in potentially different blocks, /// determine whether MemoryAccess \p A dominates MemoryAccess \p B. bool dominates(const MemoryAccess *A, const MemoryAccess *B) const; - /// \brief Given a MemoryAccess and a Use, determine whether MemoryAccess \p A + /// Given a MemoryAccess and a Use, determine whether MemoryAccess \p A /// dominates Use \p B. bool dominates(const MemoryAccess *A, const Use &B) const; - /// \brief Verify that MemorySSA is self consistent (IE definitions dominate + /// Verify that MemorySSA is self consistent (IE definitions dominate /// all uses, uses appear in the right places). This is used by unit tests. void verifyMemorySSA() const; @@ -776,8 +776,7 @@ private: MemoryPhi *createMemoryPhi(BasicBlock *BB); MemoryUseOrDef *createNewAccess(Instruction *); MemoryAccess *findDominatingDef(BasicBlock *, enum InsertionPlace); - void placePHINodes(const SmallPtrSetImpl &, - const DenseMap &); + void placePHINodes(const SmallPtrSetImpl &); MemoryAccess *renameBlock(BasicBlock *, MemoryAccess *, bool); void renameSuccessorPhis(BasicBlock *, MemoryAccess *, bool); void renamePass(DomTreeNode *, MemoryAccess *IncomingVal, @@ -859,7 +858,7 @@ public: Result run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for \c MemorySSA. +/// Printer pass for \c MemorySSA. class MemorySSAPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -869,12 +868,12 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Verifier pass for \c MemorySSA. +/// Verifier pass for \c MemorySSA. struct MemorySSAVerifierPass : PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Legacy analysis pass which computes \c MemorySSA. +/// Legacy analysis pass which computes \c MemorySSA. class MemorySSAWrapperPass : public FunctionPass { public: MemorySSAWrapperPass(); @@ -895,7 +894,7 @@ private: std::unique_ptr MSSA; }; -/// \brief This is the generic walker interface for walkers of MemorySSA. +/// This is the generic walker interface for walkers of MemorySSA. /// Walkers are used to be able to further disambiguate the def-use chains /// MemorySSA gives you, or otherwise produce better info than MemorySSA gives /// you. @@ -913,7 +912,7 @@ public: using MemoryAccessSet = SmallVector; - /// \brief Given a memory Mod/Ref/ModRef'ing instruction, calling this + /// Given a memory Mod/Ref/ModRef'ing instruction, calling this /// will give you the nearest dominating MemoryAccess that Mod's the location /// the instruction accesses (by skipping any def which AA can prove does not /// alias the location(s) accessed by the instruction given). @@ -945,7 +944,7 @@ public: /// but takes a MemoryAccess instead of an Instruction. virtual MemoryAccess *getClobberingMemoryAccess(MemoryAccess *) = 0; - /// \brief Given a potentially clobbering memory access and a new location, + /// Given a potentially clobbering memory access and a new location, /// calling this will give you the nearest dominating clobbering MemoryAccess /// (by skipping non-aliasing def links). /// @@ -959,7 +958,7 @@ public: virtual MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, const MemoryLocation &) = 0; - /// \brief Given a memory access, invalidate anything this walker knows about + /// Given a memory access, invalidate anything this walker knows about /// that access. /// This API is used by walkers that store information to perform basic cache /// invalidation. This will be called by MemorySSA at appropriate times for @@ -974,7 +973,7 @@ protected: MemorySSA *MSSA; }; -/// \brief A MemorySSAWalker that does no alias queries, or anything else. It +/// A MemorySSAWalker that does no alias queries, or anything else. It /// simply returns the links as they were constructed by the builder. class DoNothingMemorySSAWalker final : public MemorySSAWalker { public: @@ -990,7 +989,7 @@ public: using MemoryAccessPair = std::pair; using ConstMemoryAccessPair = std::pair; -/// \brief Iterator base class used to implement const and non-const iterators +/// Iterator base class used to implement const and non-const iterators /// over the defining accesses of a MemoryAccess. template class memoryaccess_def_iterator_base @@ -1063,7 +1062,7 @@ inline const_memoryaccess_def_iterator MemoryAccess::defs_end() const { return const_memoryaccess_def_iterator(); } -/// \brief GraphTraits for a MemoryAccess, which walks defs in the normal case, +/// GraphTraits for a MemoryAccess, which walks defs in the normal case, /// and uses in the inverse case. template <> struct GraphTraits { using NodeRef = MemoryAccess *; @@ -1083,7 +1082,7 @@ template <> struct GraphTraits> { static ChildIteratorType child_end(NodeRef N) { return N->user_end(); } }; -/// \brief Provide an iterator that walks defs, giving both the memory access, +/// Provide an iterator that walks defs, giving both the memory access, /// and the current pointer location, updating the pointer location as it /// changes due to phi node translation. /// diff --git a/include/llvm/Analysis/MemorySSAUpdater.h b/include/llvm/Analysis/MemorySSAUpdater.h index 3f4ef0614ca998a384edbfcd4e3f8216f3a94299..d5272a58d9a2e422853bd69aafb78e25f80a8bf2 100644 --- a/include/llvm/Analysis/MemorySSAUpdater.h +++ b/include/llvm/Analysis/MemorySSAUpdater.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // \file -// \brief An automatic updater for MemorySSA that handles arbitrary insertion, +// An automatic updater for MemorySSA that handles arbitrary insertion, // deletion, and moves. It performs phi insertion where necessary, and // automatically updates the MemorySSA IR to be correct. // While updating loads or removing instructions is often easy enough to not @@ -33,6 +33,7 @@ #define LLVM_ANALYSIS_MEMORYSSAUPDATER_H #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/IR/BasicBlock.h" @@ -61,6 +62,7 @@ private: MemorySSA *MSSA; SmallVector InsertedPHIs; SmallPtrSet VisitedBlocks; + SmallSet, 8> NonOptPhis; public: MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {} @@ -94,7 +96,7 @@ public: // the edge cases right, and the above calls already operate in near-optimal // time bounds. - /// \brief Create a MemoryAccess in MemorySSA at a specified point in a block, + /// Create a MemoryAccess in MemorySSA at a specified point in a block, /// with a specified clobbering definition. /// /// Returns the new MemoryAccess. @@ -111,7 +113,7 @@ public: const BasicBlock *BB, MemorySSA::InsertionPlace Point); - /// \brief Create a MemoryAccess in MemorySSA before or after an existing + /// Create a MemoryAccess in MemorySSA before or after an existing /// MemoryAccess. /// /// Returns the new MemoryAccess. @@ -128,7 +130,7 @@ public: MemoryAccess *Definition, MemoryAccess *InsertPt); - /// \brief Remove a MemoryAccess from MemorySSA, including updating all + /// Remove a MemoryAccess from MemorySSA, including updating all /// definitions and uses. /// This should be called when a memory instruction that has a MemoryAccess /// associated with it is erased from the program. For example, if a store or diff --git a/include/llvm/Analysis/MustExecute.h b/include/llvm/Analysis/MustExecute.h index fb48bb6d47fd5ccdaf34b4461079d8f8b931c79a..8daf156567cd925ac10d021013ce836b7be4a9f0 100644 --- a/include/llvm/Analysis/MustExecute.h +++ b/include/llvm/Analysis/MustExecute.h @@ -30,7 +30,7 @@ class Instruction; class DominatorTree; class Loop; -/// \brief Captures loop safety information. +/// Captures loop safety information. /// It keep information for loop & its header may throw exception or otherwise /// exit abnormaly on any iteration of the loop which might actually execute /// at runtime. The primary way to consume this infromation is via @@ -46,7 +46,7 @@ struct LoopSafetyInfo { LoopSafetyInfo() = default; }; -/// \brief Computes safety information for a loop checks loop body & header for +/// Computes safety information for a loop checks loop body & header for /// the possibility of may throw exception, it takes LoopSafetyInfo and loop as /// argument. Updates safety information in LoopSafetyInfo argument. /// Note: This is defined to clear and reinitialize an already initialized diff --git a/include/llvm/Analysis/ObjCARCAliasAnalysis.h b/include/llvm/Analysis/ObjCARCAliasAnalysis.h index db524ff64ecdb2bea39bcf627c6bb932f98d516d..559c77c308119bb06b363305d455618ee63d1c3f 100644 --- a/include/llvm/Analysis/ObjCARCAliasAnalysis.h +++ b/include/llvm/Analysis/ObjCARCAliasAnalysis.h @@ -29,7 +29,7 @@ namespace llvm { namespace objcarc { -/// \brief This is a simple alias analysis implementation that uses knowledge +/// This is a simple alias analysis implementation that uses knowledge /// of ARC constructs to answer queries. /// /// TODO: This class could be generalized to know about other ObjC-specific diff --git a/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/include/llvm/Analysis/ObjCARCAnalysisUtils.h index 096573f4da80f4523b5bbae7735f2d13f8571df1..4179544f7cf4e9ade2afa0a960b8d0cbf92e858d 100644 --- a/include/llvm/Analysis/ObjCARCAnalysisUtils.h +++ b/include/llvm/Analysis/ObjCARCAnalysisUtils.h @@ -43,10 +43,10 @@ class raw_ostream; namespace llvm { namespace objcarc { -/// \brief A handy option to enable/disable all ARC Optimizations. +/// A handy option to enable/disable all ARC Optimizations. extern bool EnableARCOpts; -/// \brief Test if the given module looks interesting to run ARC optimization +/// Test if the given module looks interesting to run ARC optimization /// on. inline bool ModuleHasARC(const Module &M) { return @@ -71,7 +71,7 @@ inline bool ModuleHasARC(const Module &M) { M.getNamedValue("clang.arc.use"); } -/// \brief This is a wrapper around getUnderlyingObject which also knows how to +/// This is a wrapper around getUnderlyingObject which also knows how to /// look through objc_retain and objc_autorelease calls, which we know to return /// their argument verbatim. inline const Value *GetUnderlyingObjCPtr(const Value *V, @@ -129,7 +129,7 @@ inline Value *GetRCIdentityRoot(Value *V) { return const_cast(GetRCIdentityRoot((const Value *)V)); } -/// \brief Assuming the given instruction is one of the special calls such as +/// Assuming the given instruction is one of the special calls such as /// objc_retain or objc_release, return the RCIdentity root of the argument of /// the call. inline Value *GetArgRCIdentityRoot(Value *Inst) { @@ -146,7 +146,7 @@ inline bool IsNoopInstruction(const Instruction *I) { cast(I)->hasAllZeroIndices()); } -/// \brief Test whether the given value is possible a retainable object pointer. +/// Test whether the given value is possible a retainable object pointer. inline bool IsPotentialRetainableObjPtr(const Value *Op) { // Pointers to static or stack storage are not valid retainable object // pointers. @@ -191,7 +191,7 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op, return true; } -/// \brief Helper for GetARCInstKind. Determines what kind of construct CS +/// Helper for GetARCInstKind. Determines what kind of construct CS /// is. inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) { for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); @@ -202,7 +202,7 @@ inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) { return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call; } -/// \brief Return true if this value refers to a distinct and identifiable +/// Return true if this value refers to a distinct and identifiable /// object. /// /// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses diff --git a/include/llvm/Analysis/ObjCARCInstKind.h b/include/llvm/Analysis/ObjCARCInstKind.h index 02ff035782388f8954e610ae1da2c68a6bf3270d..0b92d8b4835601aaf798fbc4075d0174eb84a785 100644 --- a/include/llvm/Analysis/ObjCARCInstKind.h +++ b/include/llvm/Analysis/ObjCARCInstKind.h @@ -18,7 +18,7 @@ namespace objcarc { /// \enum ARCInstKind /// -/// \brief Equivalence classes of instructions in the ARC Model. +/// Equivalence classes of instructions in the ARC Model. /// /// Since we do not have "instructions" to represent ARC concepts in LLVM IR, /// we instead operate on equivalence classes of instructions. @@ -57,32 +57,32 @@ enum class ARCInstKind { raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class); -/// \brief Test if the given class is a kind of user. +/// Test if the given class is a kind of user. bool IsUser(ARCInstKind Class); -/// \brief Test if the given class is objc_retain or equivalent. +/// Test if the given class is objc_retain or equivalent. bool IsRetain(ARCInstKind Class); -/// \brief Test if the given class is objc_autorelease or equivalent. +/// Test if the given class is objc_autorelease or equivalent. bool IsAutorelease(ARCInstKind Class); -/// \brief Test if the given class represents instructions which return their +/// Test if the given class represents instructions which return their /// argument verbatim. bool IsForwarding(ARCInstKind Class); -/// \brief Test if the given class represents instructions which do nothing if +/// Test if the given class represents instructions which do nothing if /// passed a null pointer. bool IsNoopOnNull(ARCInstKind Class); -/// \brief Test if the given class represents instructions which are always safe +/// Test if the given class represents instructions which are always safe /// to mark with the "tail" keyword. bool IsAlwaysTail(ARCInstKind Class); -/// \brief Test if the given class represents instructions which are never safe +/// Test if the given class represents instructions which are never safe /// to mark with the "tail" keyword. bool IsNeverTail(ARCInstKind Class); -/// \brief Test if the given class represents instructions which are always safe +/// Test if the given class represents instructions which are always safe /// to mark with the nounwind attribute. bool IsNoThrow(ARCInstKind Class); @@ -90,11 +90,11 @@ bool IsNoThrow(ARCInstKind Class); /// autoreleasepool pop. bool CanInterruptRV(ARCInstKind Class); -/// \brief Determine if F is one of the special known Functions. If it isn't, +/// Determine if F is one of the special known Functions. If it isn't, /// return ARCInstKind::CallOrUser. ARCInstKind GetFunctionClass(const Function *F); -/// \brief Determine which objc runtime call instruction class V belongs to. +/// Determine which objc runtime call instruction class V belongs to. /// /// This is similar to GetARCInstKind except that it only detects objc /// runtime calls. This allows it to be faster. diff --git a/include/llvm/Analysis/OptimizationRemarkEmitter.h b/include/llvm/Analysis/OptimizationRemarkEmitter.h index 26f32acdcda54dd8d7ec372dc50e0974eba4ee6a..fa838696e2f876af21d4372071e60e2a51331813 100644 --- a/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/include/llvm/Analysis/OptimizationRemarkEmitter.h @@ -40,7 +40,7 @@ public: OptimizationRemarkEmitter(const Function *F, BlockFrequencyInfo *BFI) : F(F), BFI(BFI) {} - /// \brief This variant can be used to generate ORE on demand (without the + /// This variant can be used to generate ORE on demand (without the /// analysis pass). /// /// Note that this ctor has a very different cost depending on whether @@ -66,11 +66,11 @@ public: bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv); - /// \brief Output the remark via the diagnostic handler and to the + /// Output the remark via the diagnostic handler and to the /// optimization record file. void emit(DiagnosticInfoOptimizationBase &OptDiag); - /// \brief Take a lambda that returns a remark which will be emitted. Second + /// Take a lambda that returns a remark which will be emitted. Second /// argument is only used to restrict this to functions. template void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) { @@ -85,7 +85,7 @@ public: } } - /// \brief Whether we allow for extra compile-time budget to perform more + /// Whether we allow for extra compile-time budget to perform more /// analysis to produce fewer false positives. /// /// This is useful when reporting missed optimizations. In this case we can @@ -112,7 +112,7 @@ private: /// Similar but use value from \p OptDiag and update hotness there. void computeHotness(DiagnosticInfoIROptimization &OptDiag); - /// \brief Only allow verbose messages if we know we're filtering by hotness + /// Only allow verbose messages if we know we're filtering by hotness /// (BFI is only set in this case). bool shouldEmitVerbose() { return BFI != nullptr; } @@ -120,7 +120,7 @@ private: void operator=(const OptimizationRemarkEmitter &) = delete; }; -/// \brief Add a small namespace to avoid name clashes with the classes used in +/// Add a small namespace to avoid name clashes with the classes used in /// the streaming interface. We want these to be short for better /// write/readability. namespace ore { @@ -158,10 +158,10 @@ class OptimizationRemarkEmitterAnalysis static AnalysisKey Key; public: - /// \brief Provide the result typedef for this analysis pass. + /// Provide the result typedef for this analysis pass. typedef OptimizationRemarkEmitter Result; - /// \brief Run the analysis pass over a function and produce BFI. + /// Run the analysis pass over a function and produce BFI. Result run(Function &F, FunctionAnalysisManager &AM); }; } diff --git a/include/llvm/Analysis/OrderedBasicBlock.h b/include/llvm/Analysis/OrderedBasicBlock.h index 2e716af1f60ddbbf77f92dbeebb80a1ab337c6d8..0776aa626005f0739b4e6650ffb0e12254dde4c0 100644 --- a/include/llvm/Analysis/OrderedBasicBlock.h +++ b/include/llvm/Analysis/OrderedBasicBlock.h @@ -33,28 +33,28 @@ class BasicBlock; class OrderedBasicBlock { private: - /// \brief Map a instruction to its position in a BasicBlock. + /// Map a instruction to its position in a BasicBlock. SmallDenseMap NumberedInsts; - /// \brief Keep track of last instruction inserted into \p NumberedInsts. + /// Keep track of last instruction inserted into \p NumberedInsts. /// It speeds up queries for uncached instructions by providing a start point /// for new queries in OrderedBasicBlock::comesBefore. BasicBlock::const_iterator LastInstFound; - /// \brief The position/number to tag the next instruction to be found. + /// The position/number to tag the next instruction to be found. unsigned NextInstPos; - /// \brief The source BasicBlock to map. + /// The source BasicBlock to map. const BasicBlock *BB; - /// \brief Given no cached results, find if \p A comes before \p B in \p BB. + /// Given no cached results, find if \p A comes before \p B in \p BB. /// Cache and number out instruction while walking \p BB. bool comesBefore(const Instruction *A, const Instruction *B); public: OrderedBasicBlock(const BasicBlock *BasicB); - /// \brief Find out whether \p A dominates \p B, meaning whether \p A + /// Find out whether \p A dominates \p B, meaning whether \p A /// comes before \p B in \p BB. This is a simplification that considers /// cached instruction positions and ignores other basic blocks, being /// only relevant to compare relative instructions positions inside \p BB. diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index f0f34f3a51f59243037de6908576860363a32659..0a335b6be6c732cfb024e3a82e4390df142f705a 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -43,7 +43,7 @@ class PHITransAddr { /// TLI - The target library info if known, otherwise null. const TargetLibraryInfo *TLI; - /// A cache of @llvm.assume calls used by SimplifyInstruction. + /// A cache of \@llvm.assume calls used by SimplifyInstruction. AssumptionCache *AC; /// InstInputs - The inputs for our symbolic address. diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 9a8c4d7807d3c2e569931a6b236b30c950c9b842..f2dc8d135d71cb4a162c26f41682f874f4dca193 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -30,12 +30,14 @@ class PostDominatorTree : public PostDomTreeBase { public: using Base = PostDomTreeBase; + PostDominatorTree() = default; + explicit PostDominatorTree(Function &F) { recalculate(F); } /// Handle invalidation explicitly. bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &); }; -/// \brief Analysis pass which computes a \c PostDominatorTree. +/// Analysis pass which computes a \c PostDominatorTree. class PostDominatorTreeAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -43,15 +45,15 @@ class PostDominatorTreeAnalysis static AnalysisKey Key; public: - /// \brief Provide the result type for this analysis pass. + /// Provide the result type for this analysis pass. using Result = PostDominatorTree; - /// \brief Run the analysis pass over a function and produce a post dominator + /// Run the analysis pass over a function and produce a post dominator /// tree. PostDominatorTree run(Function &F, FunctionAnalysisManager &); }; -/// \brief Printer pass for the \c PostDominatorTree. +/// Printer pass for the \c PostDominatorTree. class PostDominatorTreePrinterPass : public PassInfoMixin { raw_ostream &OS; diff --git a/include/llvm/Analysis/ProfileSummaryInfo.h b/include/llvm/Analysis/ProfileSummaryInfo.h index 293033458429cb962ad4b467ed3d3041e5c47a9d..58b67e74ba5130074615e02d903167d4cc59613b 100644 --- a/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/include/llvm/Analysis/ProfileSummaryInfo.h @@ -31,7 +31,7 @@ class BasicBlock; class BlockFrequencyInfo; class CallSite; class ProfileSummary; -/// \brief Analysis providing profile information. +/// Analysis providing profile information. /// /// This is an immutable analysis pass that provides ability to query global /// (program-level) profile information. The main APIs are isHotCount and @@ -59,16 +59,16 @@ public: ProfileSummaryInfo(ProfileSummaryInfo &&Arg) : M(Arg.M), Summary(std::move(Arg.Summary)) {} - /// \brief Returns true if profile summary is available. + /// Returns true if profile summary is available. bool hasProfileSummary() { return computeSummary(); } - /// \brief Returns true if module \c M has sample profile. + /// Returns true if module \c M has sample profile. bool hasSampleProfile() { return hasProfileSummary() && Summary->getKind() == ProfileSummary::PSK_Sample; } - /// \brief Returns true if module \c M has instrumentation profile. + /// Returns true if module \c M has instrumentation profile. bool hasInstrumentationProfile() { return hasProfileSummary() && Summary->getKind() == ProfileSummary::PSK_Instr; @@ -90,31 +90,37 @@ public: BlockFrequencyInfo *BFI); /// Returns true if the working set size of the code is considered huge. bool hasHugeWorkingSetSize(); - /// \brief Returns true if \p F has hot function entry. + /// Returns true if \p F has hot function entry. bool isFunctionEntryHot(const Function *F); /// Returns true if \p F contains hot code. bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI); - /// \brief Returns true if \p F has cold function entry. + /// Returns true if \p F has cold function entry. bool isFunctionEntryCold(const Function *F); /// Returns true if \p F contains only cold code. bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI); - /// \brief Returns true if \p F is a hot function. + /// Returns true if \p F is a hot function. bool isHotCount(uint64_t C); - /// \brief Returns true if count \p C is considered cold. + /// Returns true if count \p C is considered cold. bool isColdCount(uint64_t C); - /// \brief Returns true if BasicBlock \p B is considered hot. + /// Returns true if BasicBlock \p B is considered hot. bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI); - /// \brief Returns true if BasicBlock \p B is considered cold. + /// Returns true if BasicBlock \p B is considered cold. bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI); - /// \brief Returns true if CallSite \p CS is considered hot. + /// Returns true if CallSite \p CS is considered hot. bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); - /// \brief Returns true if Callsite \p CS is considered cold. + /// Returns true if Callsite \p CS is considered cold. bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); - /// \brief Returns HotCountThreshold if set. + /// Returns HotCountThreshold if set. Recompute HotCountThreshold + /// if not set. + uint64_t getOrCompHotCountThreshold(); + /// Returns ColdCountThreshold if set. Recompute HotCountThreshold + /// if not set. + uint64_t getOrCompColdCountThreshold(); + /// Returns HotCountThreshold if set. uint64_t getHotCountThreshold() { return HotCountThreshold ? HotCountThreshold.getValue() : 0; } - /// \brief Returns ColdCountThreshold if set. + /// Returns ColdCountThreshold if set. uint64_t getColdCountThreshold() { return ColdCountThreshold ? ColdCountThreshold.getValue() : 0; } @@ -152,7 +158,7 @@ private: static AnalysisKey Key; }; -/// \brief Printer pass that uses \c ProfileSummaryAnalysis. +/// Printer pass that uses \c ProfileSummaryAnalysis. class ProfileSummaryPrinterPass : public PassInfoMixin { raw_ostream &OS; diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h index f934aa6d19269ec30a502f98bfb3481c77dedcfc..b34b25c75040ad4a3f745a980c9348714ae829ed 100644 --- a/include/llvm/Analysis/PtrUseVisitor.h +++ b/include/llvm/Analysis/PtrUseVisitor.h @@ -47,7 +47,7 @@ namespace llvm { namespace detail { -/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor. +/// Implementation of non-dependent functionality for \c PtrUseVisitor. /// /// See \c PtrUseVisitor for the public interface and detailed comments about /// usage. This class is just a helper base class which is not templated and @@ -55,7 +55,7 @@ namespace detail { /// PtrUseVisitor. class PtrUseVisitorBase { public: - /// \brief This class provides information about the result of a visit. + /// This class provides information about the result of a visit. /// /// After walking all the users (recursively) of a pointer, the basic /// infrastructure records some commonly useful information such as escape @@ -64,7 +64,7 @@ public: public: PtrInfo() : AbortedInfo(nullptr, false), EscapedInfo(nullptr, false) {} - /// \brief Reset the pointer info, clearing all state. + /// Reset the pointer info, clearing all state. void reset() { AbortedInfo.setPointer(nullptr); AbortedInfo.setInt(false); @@ -72,37 +72,37 @@ public: EscapedInfo.setInt(false); } - /// \brief Did we abort the visit early? + /// Did we abort the visit early? bool isAborted() const { return AbortedInfo.getInt(); } - /// \brief Is the pointer escaped at some point? + /// Is the pointer escaped at some point? bool isEscaped() const { return EscapedInfo.getInt(); } - /// \brief Get the instruction causing the visit to abort. + /// Get the instruction causing the visit to abort. /// \returns a pointer to the instruction causing the abort if one is /// available; otherwise returns null. Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); } - /// \brief Get the instruction causing the pointer to escape. + /// Get the instruction causing the pointer to escape. /// \returns a pointer to the instruction which escapes the pointer if one /// is available; otherwise returns null. Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); } - /// \brief Mark the visit as aborted. Intended for use in a void return. + /// Mark the visit as aborted. Intended for use in a void return. /// \param I The instruction which caused the visit to abort, if available. void setAborted(Instruction *I = nullptr) { AbortedInfo.setInt(true); AbortedInfo.setPointer(I); } - /// \brief Mark the pointer as escaped. Intended for use in a void return. + /// Mark the pointer as escaped. Intended for use in a void return. /// \param I The instruction which escapes the pointer, if available. void setEscaped(Instruction *I = nullptr) { EscapedInfo.setInt(true); EscapedInfo.setPointer(I); } - /// \brief Mark the pointer as escaped, and the visit as aborted. Intended + /// Mark the pointer as escaped, and the visit as aborted. Intended /// for use in a void return. /// \param I The instruction which both escapes the pointer and aborts the /// visit, if available. @@ -121,10 +121,10 @@ protected: /// \name Visitation infrastructure /// @{ - /// \brief The info collected about the pointer being visited thus far. + /// The info collected about the pointer being visited thus far. PtrInfo PI; - /// \brief A struct of the data needed to visit a particular use. + /// A struct of the data needed to visit a particular use. /// /// This is used to maintain a worklist fo to-visit uses. This is used to /// make the visit be iterative rather than recursive. @@ -135,10 +135,10 @@ protected: APInt Offset; }; - /// \brief The worklist of to-visit uses. + /// The worklist of to-visit uses. SmallVector Worklist; - /// \brief A set of visited uses to break cycles in unreachable code. + /// A set of visited uses to break cycles in unreachable code. SmallPtrSet VisitedUses; /// @} @@ -147,14 +147,14 @@ protected: /// This state is reset for each instruction visited. /// @{ - /// \brief The use currently being visited. + /// The use currently being visited. Use *U; - /// \brief True if we have a known constant offset for the use currently + /// True if we have a known constant offset for the use currently /// being visited. bool IsOffsetKnown; - /// \brief The constant offset of the use if that is known. + /// The constant offset of the use if that is known. APInt Offset; /// @} @@ -163,13 +163,13 @@ protected: /// class, we can't create instances directly of this class. PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} - /// \brief Enqueue the users of this instruction in the visit worklist. + /// Enqueue the users of this instruction in the visit worklist. /// /// This will visit the users with the same offset of the current visit /// (including an unknown offset if that is the current state). void enqueueUsers(Instruction &I); - /// \brief Walk the operands of a GEP and adjust the offset as appropriate. + /// Walk the operands of a GEP and adjust the offset as appropriate. /// /// This routine does the heavy lifting of the pointer walk by computing /// offsets and looking through GEPs. @@ -178,7 +178,7 @@ protected: } // end namespace detail -/// \brief A base class for visitors over the uses of a pointer value. +/// A base class for visitors over the uses of a pointer value. /// /// Once constructed, a user can call \c visit on a pointer value, and this /// will walk its uses and visit each instruction using an InstVisitor. It also @@ -216,7 +216,7 @@ public: "Must pass the derived type to this template!"); } - /// \brief Recursively visit the uses of the given pointer. + /// Recursively visit the uses of the given pointer. /// \returns An info struct about the pointer. See \c PtrInfo for details. PtrInfo visitPtr(Instruction &I) { // This must be a pointer type. Get an integer type suitable to hold diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 4bf64d191e5981c5e2b096b5c9c0e60459f77c46..27f6cc197927ce5fc5fd15025c481d94acd1fd93 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -42,6 +42,7 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Config/llvm-config.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/PassManager.h" @@ -102,7 +103,7 @@ struct RegionTraits { } }; -/// @brief Marker class to iterate over the elements of a Region in flat mode. +/// Marker class to iterate over the elements of a Region in flat mode. /// /// The class is used to either iterate in Flat mode or by not using it to not /// iterate in Flat mode. During a Flat mode iteration all Regions are entered @@ -112,7 +113,7 @@ struct RegionTraits { template class FlatIt {}; -/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a +/// A RegionNode represents a subregion or a BasicBlock that is part of a /// Region. template class RegionNodeBase { @@ -135,12 +136,12 @@ private: /// RegionNode. PointerIntPair entry; - /// @brief The parent Region of this RegionNode. + /// The parent Region of this RegionNode. /// @see getParent() RegionT *parent; protected: - /// @brief Create a RegionNode. + /// Create a RegionNode. /// /// @param Parent The parent of this RegionNode. /// @param Entry The entry BasicBlock of the RegionNode. If this @@ -156,7 +157,7 @@ public: RegionNodeBase(const RegionNodeBase &) = delete; RegionNodeBase &operator=(const RegionNodeBase &) = delete; - /// @brief Get the parent Region of this RegionNode. + /// Get the parent Region of this RegionNode. /// /// The parent Region is the Region this RegionNode belongs to. If for /// example a BasicBlock is element of two Regions, there exist two @@ -166,7 +167,7 @@ public: /// @return Get the parent Region of this RegionNode. inline RegionT *getParent() const { return parent; } - /// @brief Get the entry BasicBlock of this RegionNode. + /// Get the entry BasicBlock of this RegionNode. /// /// If this RegionNode represents a BasicBlock this is just the BasicBlock /// itself, otherwise we return the entry BasicBlock of the Subregion @@ -174,7 +175,7 @@ public: /// @return The entry BasicBlock of this RegionNode. inline BlockT *getEntry() const { return entry.getPointer(); } - /// @brief Get the content of this RegionNode. + /// Get the content of this RegionNode. /// /// This can be either a BasicBlock or a subregion. Before calling getNodeAs() /// check the type of the content with the isSubRegion() function call. @@ -182,7 +183,7 @@ public: /// @return The content of this RegionNode. template inline T *getNodeAs() const; - /// @brief Is this RegionNode a subregion? + /// Is this RegionNode a subregion? /// /// @return True if it contains a subregion. False if it contains a /// BasicBlock. @@ -190,7 +191,7 @@ public: }; //===----------------------------------------------------------------------===// -/// @brief A single entry single exit Region. +/// A single entry single exit Region. /// /// A Region is a connected subgraph of a control flow graph that has exactly /// two connections to the remaining graph. It can be used to analyze or @@ -301,7 +302,7 @@ class RegionBase : public RegionNodeBase { void verifyRegionNest() const; public: - /// @brief Create a new region. + /// Create a new region. /// /// @param Entry The entry basic block of the region. /// @param Exit The exit basic block of the region. @@ -318,25 +319,25 @@ public: /// Delete the Region and all its subregions. ~RegionBase(); - /// @brief Get the entry BasicBlock of the Region. + /// Get the entry BasicBlock of the Region. /// @return The entry BasicBlock of the region. BlockT *getEntry() const { return RegionNodeBase::getEntry(); } - /// @brief Replace the entry basic block of the region with the new basic + /// Replace the entry basic block of the region with the new basic /// block. /// /// @param BB The new entry basic block of the region. void replaceEntry(BlockT *BB); - /// @brief Replace the exit basic block of the region with the new basic + /// Replace the exit basic block of the region with the new basic /// block. /// /// @param BB The new exit basic block of the region. void replaceExit(BlockT *BB); - /// @brief Recursively replace the entry basic block of the region. + /// Recursively replace the entry basic block of the region. /// /// This function replaces the entry basic block with a new basic block. It /// also updates all child regions that have the same entry basic block as @@ -345,7 +346,7 @@ public: /// @param NewEntry The new entry basic block. void replaceEntryRecursive(BlockT *NewEntry); - /// @brief Recursively replace the exit basic block of the region. + /// Recursively replace the exit basic block of the region. /// /// This function replaces the exit basic block with a new basic block. It /// also updates all child regions that have the same exit basic block as @@ -354,38 +355,38 @@ public: /// @param NewExit The new exit basic block. void replaceExitRecursive(BlockT *NewExit); - /// @brief Get the exit BasicBlock of the Region. + /// Get the exit BasicBlock of the Region. /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel /// Region. BlockT *getExit() const { return exit; } - /// @brief Get the parent of the Region. + /// Get the parent of the Region. /// @return The parent of the Region or NULL if this is a top level /// Region. RegionT *getParent() const { return RegionNodeBase::getParent(); } - /// @brief Get the RegionNode representing the current Region. + /// Get the RegionNode representing the current Region. /// @return The RegionNode representing the current Region. RegionNodeT *getNode() const { return const_cast( reinterpret_cast(this)); } - /// @brief Get the nesting level of this Region. + /// Get the nesting level of this Region. /// /// An toplevel Region has depth 0. /// /// @return The depth of the region. unsigned getDepth() const; - /// @brief Check if a Region is the TopLevel region. + /// Check if a Region is the TopLevel region. /// /// The toplevel region represents the whole function. bool isTopLevelRegion() const { return exit == nullptr; } - /// @brief Return a new (non-canonical) region, that is obtained by joining + /// Return a new (non-canonical) region, that is obtained by joining /// this region with its predecessors. /// /// @return A region also starting at getEntry(), but reaching to the next @@ -393,43 +394,43 @@ public: /// NULL if such a basic block does not exist. RegionT *getExpandedRegion() const; - /// @brief Return the first block of this region's single entry edge, + /// Return the first block of this region's single entry edge, /// if existing. /// /// @return The BasicBlock starting this region's single entry edge, /// else NULL. BlockT *getEnteringBlock() const; - /// @brief Return the first block of this region's single exit edge, + /// Return the first block of this region's single exit edge, /// if existing. /// /// @return The BasicBlock starting this region's single exit edge, /// else NULL. BlockT *getExitingBlock() const; - /// @brief Collect all blocks of this region's single exit edge, if existing. + /// Collect all blocks of this region's single exit edge, if existing. /// /// @return True if this region contains all the predecessors of the exit. bool getExitingBlocks(SmallVectorImpl &Exitings) const; - /// @brief Is this a simple region? + /// Is this a simple region? /// /// A region is simple if it has exactly one exit and one entry edge. /// /// @return True if the Region is simple. bool isSimple() const; - /// @brief Returns the name of the Region. + /// Returns the name of the Region. /// @return The Name of the Region. std::string getNameStr() const; - /// @brief Return the RegionInfo object, that belongs to this Region. + /// Return the RegionInfo object, that belongs to this Region. RegionInfoT *getRegionInfo() const { return RI; } /// PrintStyle - Print region in difference ways. enum PrintStyle { PrintNone, PrintBB, PrintRN }; - /// @brief Print the region. + /// Print the region. /// /// @param OS The output stream the Region is printed to. /// @param printTree Print also the tree of subregions. @@ -438,17 +439,17 @@ public: PrintStyle Style = PrintNone) const; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - /// @brief Print the region to stderr. + /// Print the region to stderr. void dump() const; #endif - /// @brief Check if the region contains a BasicBlock. + /// Check if the region contains a BasicBlock. /// /// @param BB The BasicBlock that might be contained in this Region. /// @return True if the block is contained in the region otherwise false. bool contains(const BlockT *BB) const; - /// @brief Check if the region contains another region. + /// Check if the region contains another region. /// /// @param SubRegion The region that might be contained in this Region. /// @return True if SubRegion is contained in the region otherwise false. @@ -462,14 +463,14 @@ public: SubRegion->getExit() == getExit()); } - /// @brief Check if the region contains an Instruction. + /// Check if the region contains an Instruction. /// /// @param Inst The Instruction that might be contained in this region. /// @return True if the Instruction is contained in the region otherwise /// false. bool contains(const InstT *Inst) const { return contains(Inst->getParent()); } - /// @brief Check if the region contains a loop. + /// Check if the region contains a loop. /// /// @param L The loop that might be contained in this region. /// @return True if the loop is contained in the region otherwise false. @@ -478,7 +479,7 @@ public: /// In that case true is returned. bool contains(const LoopT *L) const; - /// @brief Get the outermost loop in the region that contains a loop. + /// Get the outermost loop in the region that contains a loop. /// /// Find for a Loop L the outermost loop OuterL that is a parent loop of L /// and is itself contained in the region. @@ -488,7 +489,7 @@ public: /// exist or if the region describes the whole function. LoopT *outermostLoopInRegion(LoopT *L) const; - /// @brief Get the outermost loop in the region that contains a basic block. + /// Get the outermost loop in the region that contains a basic block. /// /// Find for a basic block BB the outermost loop L that contains BB and is /// itself contained in the region. @@ -499,13 +500,13 @@ public: /// exist or if the region describes the whole function. LoopT *outermostLoopInRegion(LoopInfoT *LI, BlockT *BB) const; - /// @brief Get the subregion that starts at a BasicBlock + /// Get the subregion that starts at a BasicBlock /// /// @param BB The BasicBlock the subregion should start. /// @return The Subregion if available, otherwise NULL. RegionT *getSubRegionNode(BlockT *BB) const; - /// @brief Get the RegionNode for a BasicBlock + /// Get the RegionNode for a BasicBlock /// /// @param BB The BasicBlock at which the RegionNode should start. /// @return If available, the RegionNode that represents the subregion @@ -513,38 +514,38 @@ public: /// representing BB. RegionNodeT *getNode(BlockT *BB) const; - /// @brief Get the BasicBlock RegionNode for a BasicBlock + /// Get the BasicBlock RegionNode for a BasicBlock /// /// @param BB The BasicBlock for which the RegionNode is requested. /// @return The RegionNode representing the BB. RegionNodeT *getBBNode(BlockT *BB) const; - /// @brief Add a new subregion to this Region. + /// Add a new subregion to this Region. /// /// @param SubRegion The new subregion that will be added. /// @param moveChildren Move the children of this region, that are also /// contained in SubRegion into SubRegion. void addSubRegion(RegionT *SubRegion, bool moveChildren = false); - /// @brief Remove a subregion from this Region. + /// Remove a subregion from this Region. /// /// The subregion is not deleted, as it will probably be inserted into another /// region. /// @param SubRegion The SubRegion that will be removed. RegionT *removeSubRegion(RegionT *SubRegion); - /// @brief Move all direct child nodes of this Region to another Region. + /// Move all direct child nodes of this Region to another Region. /// /// @param To The Region the child nodes will be transferred to. void transferChildrenTo(RegionT *To); - /// @brief Verify if the region is a correct region. + /// Verify if the region is a correct region. /// /// Check if this is a correctly build Region. This is an expensive check, as /// the complete CFG of the Region will be walked. void verifyRegion() const; - /// @brief Clear the cache for BB RegionNodes. + /// Clear the cache for BB RegionNodes. /// /// After calling this function the BasicBlock RegionNodes will be stored at /// different memory locations. RegionNodes obtained before this function is @@ -620,12 +621,12 @@ public: using block_range = iterator_range; using const_block_range = iterator_range; - /// @brief Returns a range view of the basic blocks in the region. + /// Returns a range view of the basic blocks in the region. inline block_range blocks() { return block_range(block_begin(), block_end()); } - /// @brief Returns a range view of the basic blocks in the region. + /// Returns a range view of the basic blocks in the region. /// /// This is the 'const' version of the range view. inline const_block_range blocks() const { @@ -667,7 +668,7 @@ template inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase &Node); //===----------------------------------------------------------------------===// -/// @brief Analysis that detects all canonical Regions. +/// Analysis that detects all canonical Regions. /// /// The RegionInfo pass detects all canonical regions in a function. The Regions /// are connected using the parent relation. This builds a Program Structure @@ -725,7 +726,7 @@ class RegionInfoBase { BBtoRegionMap BBtoRegion; protected: - /// \brief Update refences to a RegionInfoT held by the RegionT managed here + /// Update refences to a RegionInfoT held by the RegionT managed here /// /// This is a post-move helper. Regions hold references to the owning /// RegionInfo object. After a move these need to be fixed. @@ -739,7 +740,7 @@ protected: } private: - /// \brief Wipe this region tree's state without releasing any resources. + /// Wipe this region tree's state without releasing any resources. /// /// This is essentially a post-move helper only. It leaves the object in an /// assignable and destroyable state, but otherwise invalid. @@ -811,40 +812,40 @@ public: void releaseMemory(); - /// @brief Get the smallest region that contains a BasicBlock. + /// Get the smallest region that contains a BasicBlock. /// /// @param BB The basic block. /// @return The smallest region, that contains BB or NULL, if there is no /// region containing BB. RegionT *getRegionFor(BlockT *BB) const; - /// @brief Set the smallest region that surrounds a basic block. + /// Set the smallest region that surrounds a basic block. /// /// @param BB The basic block surrounded by a region. /// @param R The smallest region that surrounds BB. void setRegionFor(BlockT *BB, RegionT *R); - /// @brief A shortcut for getRegionFor(). + /// A shortcut for getRegionFor(). /// /// @param BB The basic block. /// @return The smallest region, that contains BB or NULL, if there is no /// region containing BB. RegionT *operator[](BlockT *BB) const; - /// @brief Return the exit of the maximal refined region, that starts at a + /// Return the exit of the maximal refined region, that starts at a /// BasicBlock. /// /// @param BB The BasicBlock the refined region starts. BlockT *getMaxRegionExit(BlockT *BB) const; - /// @brief Find the smallest region that contains two regions. + /// Find the smallest region that contains two regions. /// /// @param A The first region. /// @param B The second region. /// @return The smallest region containing A and B. RegionT *getCommonRegion(RegionT *A, RegionT *B) const; - /// @brief Find the smallest region that contains two basic blocks. + /// Find the smallest region that contains two basic blocks. /// /// @param A The first basic block. /// @param B The second basic block. @@ -853,13 +854,13 @@ public: return getCommonRegion(getRegionFor(A), getRegionFor(B)); } - /// @brief Find the smallest region that contains a set of regions. + /// Find the smallest region that contains a set of regions. /// /// @param Regions A vector of regions. /// @return The smallest region that contains all regions in Regions. RegionT *getCommonRegion(SmallVectorImpl &Regions) const; - /// @brief Find the smallest region that contains a set of basic blocks. + /// Find the smallest region that contains a set of basic blocks. /// /// @param BBs A vector of basic blocks. /// @return The smallest region that contains all basic blocks in BBS. @@ -867,7 +868,7 @@ public: RegionT *getTopLevelRegion() const { return TopLevelRegion; } - /// @brief Clear the Node Cache for all Regions. + /// Clear the Node Cache for all Regions. /// /// @see Region::clearNodeCache() void clearNodeCache() { @@ -930,12 +931,12 @@ public: DominanceFrontier *DF); #ifndef NDEBUG - /// @brief Opens a viewer to show the GraphViz visualization of the regions. + /// Opens a viewer to show the GraphViz visualization of the regions. /// /// Useful during debugging as an alternative to dump(). void view(); - /// @brief Opens a viewer to show the GraphViz visualization of this region + /// Opens a viewer to show the GraphViz visualization of this region /// without instructions in the BasicBlocks. /// /// Useful during debugging as an alternative to dump(). @@ -967,7 +968,7 @@ public: //@} }; -/// \brief Analysis pass that exposes the \c RegionInfo for a function. +/// Analysis pass that exposes the \c RegionInfo for a function. class RegionInfoAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; @@ -979,7 +980,7 @@ public: RegionInfo run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Printer pass for the \c RegionInfo. +/// Printer pass for the \c RegionInfo. class RegionInfoPrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -989,7 +990,7 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Verifier pass for the \c RegionInfo. +/// Verifier pass for the \c RegionInfo. struct RegionInfoVerifierPass : PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h index eb6baac2d5e4fc1dc3078047fc2e9848d4390bae..5904214aa925432699962d5c6665d7938346520b 100644 --- a/include/llvm/Analysis/RegionInfoImpl.h +++ b/include/llvm/Analysis/RegionInfoImpl.h @@ -22,6 +22,7 @@ #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/RegionIterator.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -674,7 +675,7 @@ typename Tr::RegionT *RegionInfoBase::createRegion(BlockT *entry, #ifdef EXPENSIVE_CHECKS region->verifyRegion(); #else - DEBUG(region->verifyRegion()); + LLVM_DEBUG(region->verifyRegion()); #endif updateStatistics(region); diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h index 4f823cc822103338b176477c205082e73b8306cc..4fd92fcde20b86b81f7d40af7749a87dc45d2284 100644 --- a/include/llvm/Analysis/RegionIterator.h +++ b/include/llvm/Analysis/RegionIterator.h @@ -26,7 +26,7 @@ namespace llvm { class BasicBlock; //===----------------------------------------------------------------------===// -/// @brief Hierarchical RegionNode successor iterator. +/// Hierarchical RegionNode successor iterator. /// /// This iterator iterates over all successors of a RegionNode. /// @@ -102,7 +102,7 @@ public: using Self = RNSuccIterator; using value_type = typename super::value_type; - /// @brief Create begin iterator of a RegionNode. + /// Create begin iterator of a RegionNode. inline RNSuccIterator(NodeRef node) : Node(node, node->isSubRegion() ? ItRgBegin : ItBB), BItor(BlockTraits::child_begin(node->getEntry())) { @@ -115,7 +115,7 @@ public: advanceRegionSucc(); } - /// @brief Create an end iterator. + /// Create an end iterator. inline RNSuccIterator(NodeRef node, bool) : Node(node, node->isSubRegion() ? ItRgEnd : ItBB), BItor(BlockTraits::child_end(node->getEntry())) {} @@ -158,7 +158,7 @@ public: }; //===----------------------------------------------------------------------===// -/// @brief Flat RegionNode iterator. +/// Flat RegionNode iterator. /// /// The Flat Region iterator will iterate over all BasicBlock RegionNodes that /// are contained in the Region and its subregions. This is close to a virtual @@ -177,7 +177,7 @@ public: using Self = RNSuccIterator, BlockT, RegionT>; using value_type = typename super::value_type; - /// @brief Create the iterator from a RegionNode. + /// Create the iterator from a RegionNode. /// /// Note that the incoming node must be a bb node, otherwise it will trigger /// an assertion when we try to get a BasicBlock. @@ -193,7 +193,7 @@ public: ++Itor; } - /// @brief Create an end iterator + /// Create an end iterator inline RNSuccIterator(NodeRef node, bool) : Node(node), Itor(BlockTraits::child_end(node->getEntry())) { assert(!Node->isSubRegion() && diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index 515b362e540710c0f8a607b8aafc54b99b0a6b69..b3da91c89cbd63dd8dfbe5df1bc4b7d215136ea3 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -28,7 +28,7 @@ class RGPassManager; class Function; //===----------------------------------------------------------------------===// -/// @brief A pass that runs on each Region in a function. +/// A pass that runs on each Region in a function. /// /// RegionPass is managed by RGPassManager. class RegionPass : public Pass { @@ -39,7 +39,7 @@ public: /// @name To be implemented by every RegionPass /// //@{ - /// @brief Run the pass on a specific Region + /// Run the pass on a specific Region /// /// Accessing regions not contained in the current region is not allowed. /// @@ -49,7 +49,7 @@ public: /// @return True if the pass modifies this Region. virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0; - /// @brief Get a pass to print the LLVM IR in the region. + /// Get a pass to print the LLVM IR in the region. /// /// @param O The output stream to print the Region. /// @param Banner The banner to separate different printed passes. @@ -85,7 +85,7 @@ protected: bool skipRegion(Region &R) const; }; -/// @brief The pass manager to schedule RegionPasses. +/// The pass manager to schedule RegionPasses. class RGPassManager : public FunctionPass, public PMDataManager { std::deque RQ; bool skipThisRegion; @@ -97,7 +97,7 @@ public: static char ID; explicit RGPassManager(); - /// @brief Execute all of the passes scheduled for execution. + /// Execute all of the passes scheduled for execution. /// /// @return True if any of the passes modifies the function. bool runOnFunction(Function &F) override; @@ -111,10 +111,10 @@ public: PMDataManager *getAsPMDataManager() override { return this; } Pass *getAsPass() override { return this; } - /// @brief Print passes managed by this manager. + /// Print passes managed by this manager. void dumpPassStructure(unsigned Offset) override; - /// @brief Get passes contained by this manager. + /// Get passes contained by this manager. Pass *getContainedPass(unsigned N) { assert(N < PassVector.size() && "Pass number out of range!"); Pass *FP = static_cast(PassVector[N]); diff --git a/include/llvm/Analysis/RegionPrinter.h b/include/llvm/Analysis/RegionPrinter.h index 8f0035cfd8e68806abbe4fafa947a5ef88ebda61..e132eaea567460a40ef6135c7fa4b1c4f60f959b 100644 --- a/include/llvm/Analysis/RegionPrinter.h +++ b/include/llvm/Analysis/RegionPrinter.h @@ -26,7 +26,7 @@ namespace llvm { FunctionPass *createRegionOnlyPrinterPass(); #ifndef NDEBUG - /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// Open a viewer to display the GraphViz vizualization of the analysis /// result. /// /// Practical to call in the debugger. @@ -35,7 +35,7 @@ namespace llvm { /// @param RI The analysis to display. void viewRegion(llvm::RegionInfo *RI); - /// @brief Analyze the regions of a function and open its GraphViz + /// Analyze the regions of a function and open its GraphViz /// visualization in a viewer. /// /// Useful to call in the debugger. @@ -46,7 +46,7 @@ namespace llvm { /// @param F Function to analyze. void viewRegion(const llvm::Function *F); - /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// Open a viewer to display the GraphViz vizualization of the analysis /// result. /// /// Useful to call in the debugger. @@ -55,7 +55,7 @@ namespace llvm { /// @param RI The analysis to display. void viewRegionOnly(llvm::RegionInfo *RI); - /// @brief Analyze the regions of a function and open its GraphViz + /// Analyze the regions of a function and open its GraphViz /// visualization in a viewer. /// /// Useful to call in the debugger. diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 7a43b81d8d7a62062d48afec86e68fff998b0afd..20d61d06ab8d981c3c007653e4a283fb7c7e2504 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -587,7 +587,9 @@ public: const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getUMaxExpr(SmallVectorImpl &Operands); const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS); + const SCEV *getSMinExpr(SmallVectorImpl &Operands); const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS); + const SCEV *getUMinExpr(SmallVectorImpl &Operands); const SCEV *getUnknown(Value *V); const SCEV *getCouldNotCompute(); @@ -650,6 +652,10 @@ public: /// then perform a umin operation with them. const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); + /// Promote the operands to the wider of the types using zero-extension, and + /// then perform a umin operation with them. N-ary function. + const SCEV *getUMinFromMismatchedTypes(SmallVectorImpl &Ops); + /// Transitively follow the chain of pointer-type operands until reaching a /// SCEV that does not have a single pointer operand. This returns a /// SCEVUnknown pointer for well-formed pointer-type expressions, but corner @@ -764,6 +770,12 @@ public: /// loop bodies. void forgetLoop(const Loop *L); + // This method invokes forgetLoop for the outermost loop of the given loop + // \p L, making ScalarEvolution forget about all this subtree. This needs to + // be done whenever we make a transform that may affect the parameters of the + // outer loop, such as exit counts for branches. + void forgetTopmostLoop(const Loop *L); + /// This method should be called by the client when it has changed a value /// in a way that may effect its value, or which may disconnect it from a /// def-use chain linking it to a loop. @@ -1085,7 +1097,7 @@ private: /// The target library information for the target we are targeting. TargetLibraryInfo &TLI; - /// The tracker for @llvm.assume intrinsics in this function. + /// The tracker for \@llvm.assume intrinsics in this function. AssumptionCache &AC; /// The dominator tree. @@ -1142,6 +1154,9 @@ private: /// Mark SCEVUnknown Phis currently being processed by getRangeRef. SmallPtrSet PendingPhiRanges; + // Mark SCEVUnknown Phis currently being processed by isImpliedViaMerge. + SmallPtrSet PendingMerges; + /// Set to true by isLoopBackedgeGuardedByCond when we're walking the set of /// conditions dominating the backedge of a loop. bool WalkingBEDominatingConds = false; @@ -1667,6 +1682,18 @@ private: const SCEV *FoundLHS, const SCEV *FoundRHS); + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by Pred, FoundLHS, and FoundRHS is + /// true. + /// + /// This routine tries to figure out predicate for Phis which are SCEVUnknown + /// if it is true for every possible incoming value from their respective + /// basic blocks. + bool isImpliedViaMerge(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS, + const SCEV *FoundLHS, const SCEV *FoundRHS, + unsigned Depth); + /// If we know that the specified Phi is in the header of its containing /// loop, we know the loop executes a constant number of times, and the PHI /// node is just a recurrence involving constants, fold it. diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 3df04e98bd2415006c89db828a30a93504a611aa..6476568695cefcb9d3e7aa611531d833bc637daa 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -321,7 +321,7 @@ namespace llvm { /// Arrange for there to be a cast of V to Ty at IP, reusing an existing /// cast if a suitable one exists, moving an existing cast if a suitable one - /// exists but isn't in the right place, or or creating a new one. + /// exists but isn't in the right place, or creating a new one. Value *ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op, BasicBlock::iterator IP); diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h index 1b8df03b3a1bec45c332a6620a4b8ab526b6a597..defcf96afb25e35b08b4d480ab762a0a85d01151 100644 --- a/include/llvm/Analysis/SparsePropagation.h +++ b/include/llvm/Analysis/SparsePropagation.h @@ -238,7 +238,7 @@ SparseSolver::getValueState(LatticeKey Key) { // If this value is untracked, don't add it to the map. if (LV == LatticeFunc->getUntrackedVal()) return LV; - return ValueState[Key] = LV; + return ValueState[Key] = std::move(LV); } template @@ -250,7 +250,7 @@ void SparseSolver::UpdateState(LatticeKey Key, // Update the state of the given LatticeKey and add its corresponding LLVM // value to the work list. - ValueState[Key] = LV; + ValueState[Key] = std::move(LV); if (Value *V = KeyInfo::getValueFromLatticeKey(Key)) ValueWorkList.push_back(V); } @@ -260,7 +260,7 @@ void SparseSolver::MarkBlockExecutable( BasicBlock *BB) { if (!BBExecutable.insert(BB).second) return; - DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << "\n"); + LLVM_DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << "\n"); BBWorkList.push_back(BB); // Add the block to the work list! } @@ -270,8 +270,8 @@ void SparseSolver::markEdgeExecutable( if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second) return; // This edge is already known to be executable! - DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName() << " -> " - << Dest->getName() << "\n"); + LLVM_DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName() + << " -> " << Dest->getName() << "\n"); if (BBExecutable.count(Dest)) { // The destination is already executable, but we just made an edge @@ -318,7 +318,7 @@ void SparseSolver::getFeasibleSuccessors( Constant *C = dyn_cast_or_null(LatticeFunc->GetValueFromLatticeVal( - BCValue, BI->getCondition()->getType())); + std::move(BCValue), BI->getCondition()->getType())); if (!C || !isa(C)) { // Non-constant values can go either way. Succs[0] = Succs[1] = true; @@ -360,7 +360,7 @@ void SparseSolver::getFeasibleSuccessors( return; Constant *C = dyn_cast_or_null(LatticeFunc->GetValueFromLatticeVal( - SCValue, SI.getCondition()->getType())); + std::move(SCValue), SI.getCondition()->getType())); if (!C || !isa(C)) { // All destinations are executable! Succs.assign(TI.getNumSuccessors(), true); @@ -408,7 +408,8 @@ void SparseSolver::visitPHINode(PHINode &PN) { LatticeFunc->ComputeInstructionState(PN, ChangedValues, *this); for (auto &ChangedValue : ChangedValues) if (ChangedValue.second != LatticeFunc->getUntrackedVal()) - UpdateState(ChangedValue.first, ChangedValue.second); + UpdateState(std::move(ChangedValue.first), + std::move(ChangedValue.second)); return; } @@ -477,7 +478,7 @@ void SparseSolver::Solve() { Value *V = ValueWorkList.back(); ValueWorkList.pop_back(); - DEBUG(dbgs() << "\nPopped off V-WL: " << *V << "\n"); + LLVM_DEBUG(dbgs() << "\nPopped off V-WL: " << *V << "\n"); // "V" got into the work list because it made a transition. See if any // users are both live and in need of updating. @@ -492,7 +493,7 @@ void SparseSolver::Solve() { BasicBlock *BB = BBWorkList.back(); BBWorkList.pop_back(); - DEBUG(dbgs() << "\nPopped off BBWL: " << *BB); + LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB); // Notify all instructions in this basic block that they are newly // executable. diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def index a461ed813b9b6f75a0c21bbd9f862a51ab205cf1..f94debba9c52b8f46fc1c9f94ec98f0450d6acea 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.def +++ b/include/llvm/Analysis/TargetLibraryInfo.def @@ -119,6 +119,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdaPv") /// void operator delete[](void*, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZdaPvRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZdaPvRKSt9nothrow_t") +/// void operator delete[](void*, align_val_t); +TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_t") +/// void operator delete[](void*, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_tRKSt9nothrow_t") /// void operator delete[](void*, unsigned int); TLI_DEFINE_ENUM_INTERNAL(ZdaPvj) TLI_DEFINE_STRING_INTERNAL("_ZdaPvj") @@ -131,6 +137,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdlPv") /// void operator delete(void*, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZdlPvRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZdlPvRKSt9nothrow_t") +/// void operator delete(void*, align_val_t) +TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_t") +/// void operator delete(void*, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_tRKSt9nothrow_t") /// void operator delete(void*, unsigned int); TLI_DEFINE_ENUM_INTERNAL(ZdlPvj) TLI_DEFINE_STRING_INTERNAL("_ZdlPvj") @@ -143,24 +155,48 @@ TLI_DEFINE_STRING_INTERNAL("_Znaj") /// void *new[](unsigned int, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZnajRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZnajRKSt9nothrow_t") +/// void *new[](unsigned int, align_val_t) +TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_t") +/// void *new[](unsigned int, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_tRKSt9nothrow_t") /// void *new[](unsigned long); TLI_DEFINE_ENUM_INTERNAL(Znam) TLI_DEFINE_STRING_INTERNAL("_Znam") /// void *new[](unsigned long, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZnamRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZnamRKSt9nothrow_t") +/// void *new[](unsigned long, align_val_t) +TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_t") +/// void *new[](unsigned long, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_tRKSt9nothrow_t") /// void *new(unsigned int); TLI_DEFINE_ENUM_INTERNAL(Znwj) TLI_DEFINE_STRING_INTERNAL("_Znwj") /// void *new(unsigned int, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZnwjRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZnwjRKSt9nothrow_t") +/// void *new(unsigned int, align_val_t) +TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_t") +/// void *new(unsigned int, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_tRKSt9nothrow_t") /// void *new(unsigned long); TLI_DEFINE_ENUM_INTERNAL(Znwm) TLI_DEFINE_STRING_INTERNAL("_Znwm") /// void *new(unsigned long, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t") +/// void *new(unsigned long, align_val_t) +TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_t") +/// void *new(unsigned long, align_val_t, nothrow) +TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_tRKSt9nothrow_t) +TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_tRKSt9nothrow_t") /// double __acos_finite(double x); TLI_DEFINE_ENUM_INTERNAL(acos_finite) TLI_DEFINE_STRING_INTERNAL("__acos_finite") @@ -601,12 +637,18 @@ TLI_DEFINE_STRING_INTERNAL("ffsll") /// int fgetc(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fgetc) TLI_DEFINE_STRING_INTERNAL("fgetc") +/// int fgetc_unlocked(FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fgetc_unlocked) +TLI_DEFINE_STRING_INTERNAL("fgetc_unlocked") /// int fgetpos(FILE *stream, fpos_t *pos); TLI_DEFINE_ENUM_INTERNAL(fgetpos) TLI_DEFINE_STRING_INTERNAL("fgetpos") /// char *fgets(char *s, int n, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fgets) TLI_DEFINE_STRING_INTERNAL("fgets") +/// char *fgets_unlocked(char *s, int n, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fgets_unlocked) +TLI_DEFINE_STRING_INTERNAL("fgets_unlocked") /// int fileno(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fileno) TLI_DEFINE_STRING_INTERNAL("fileno") @@ -673,12 +715,21 @@ TLI_DEFINE_STRING_INTERNAL("fprintf") /// int fputc(int c, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fputc) TLI_DEFINE_STRING_INTERNAL("fputc") +/// int fputc_unlocked(int c, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fputc_unlocked) +TLI_DEFINE_STRING_INTERNAL("fputc_unlocked") /// int fputs(const char *s, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fputs) TLI_DEFINE_STRING_INTERNAL("fputs") +/// int fputs_unlocked(const char *s, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fputs_unlocked) +TLI_DEFINE_STRING_INTERNAL("fputs_unlocked") /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fread) TLI_DEFINE_STRING_INTERNAL("fread") +/// size_t fread_unlocked(void *ptr, size_t size, size_t nitems, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fread_unlocked) +TLI_DEFINE_STRING_INTERNAL("fread_unlocked") /// void free(void *ptr); TLI_DEFINE_ENUM_INTERNAL(free) TLI_DEFINE_STRING_INTERNAL("free") @@ -736,6 +787,9 @@ TLI_DEFINE_STRING_INTERNAL("funlockfile") /// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(fwrite) TLI_DEFINE_STRING_INTERNAL("fwrite") +/// size_t fwrite_unlocked(const void *ptr, size_t size, size_t nitems, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(fwrite_unlocked) +TLI_DEFINE_STRING_INTERNAL("fwrite_unlocked") /// int getc(FILE *stream); TLI_DEFINE_ENUM_INTERNAL(getc) TLI_DEFINE_STRING_INTERNAL("getc") @@ -745,6 +799,9 @@ TLI_DEFINE_STRING_INTERNAL("getc_unlocked") /// int getchar(void); TLI_DEFINE_ENUM_INTERNAL(getchar) TLI_DEFINE_STRING_INTERNAL("getchar") +/// int getchar_unlocked(void); +TLI_DEFINE_ENUM_INTERNAL(getchar_unlocked) +TLI_DEFINE_STRING_INTERNAL("getchar_unlocked") /// char *getenv(const char *name); TLI_DEFINE_ENUM_INTERNAL(getenv) TLI_DEFINE_STRING_INTERNAL("getenv") @@ -950,9 +1007,15 @@ TLI_DEFINE_STRING_INTERNAL("printf") /// int putc(int c, FILE *stream); TLI_DEFINE_ENUM_INTERNAL(putc) TLI_DEFINE_STRING_INTERNAL("putc") +/// int putc_unlocked(int c, FILE *stream); +TLI_DEFINE_ENUM_INTERNAL(putc_unlocked) +TLI_DEFINE_STRING_INTERNAL("putc_unlocked") /// int putchar(int c); TLI_DEFINE_ENUM_INTERNAL(putchar) TLI_DEFINE_STRING_INTERNAL("putchar") +/// int putchar_unlocked(int c); +TLI_DEFINE_ENUM_INTERNAL(putchar_unlocked) +TLI_DEFINE_STRING_INTERNAL("putchar_unlocked") /// int puts(const char *s); TLI_DEFINE_ENUM_INTERNAL(puts) TLI_DEFINE_STRING_INTERNAL("puts") diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index 9e9c661e14f48463ba5644e82dfbdba76defd896..913d1744ea81f02fdc3beaed76dafd789f42bc17 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -49,7 +49,7 @@ class Type; class User; class Value; -/// \brief Information about a load/store intrinsic defined by the target. +/// Information about a load/store intrinsic defined by the target. struct MemIntrinsicInfo { /// This is the pointer that the intrinsic is loading from or storing to. /// If this is non-null, then analysis/optimization passes can assume that @@ -73,18 +73,18 @@ struct MemIntrinsicInfo { } }; -/// \brief This pass provides access to the codegen interfaces that are needed +/// This pass provides access to the codegen interfaces that are needed /// for IR-level transformations. class TargetTransformInfo { public: - /// \brief Construct a TTI object using a type implementing the \c Concept + /// Construct a TTI object using a type implementing the \c Concept /// API below. /// /// This is used by targets to construct a TTI wrapping their target-specific /// implementaion that encodes appropriate costs for their target. template TargetTransformInfo(T Impl); - /// \brief Construct a baseline TTI object using a minimal implementation of + /// Construct a baseline TTI object using a minimal implementation of /// the \c Concept API below. /// /// The TTI implementation will reflect the information in the DataLayout @@ -99,7 +99,7 @@ public: // out-of-line. ~TargetTransformInfo(); - /// \brief Handle the invalidation of this information. + /// Handle the invalidation of this information. /// /// When used as a result of \c TargetIRAnalysis this method will be called /// when the function this was computed for changes. When it returns false, @@ -114,7 +114,7 @@ public: /// \name Generic Target Information /// @{ - /// \brief The kind of cost model. + /// The kind of cost model. /// /// There are several different cost models that can be customized by the /// target. The normalization of each cost model may be target specific. @@ -124,7 +124,7 @@ public: TCK_CodeSize ///< Instruction code size. }; - /// \brief Query the cost of a specified instruction. + /// Query the cost of a specified instruction. /// /// Clients should use this interface to query the cost of an existing /// instruction. The instruction must have a valid parent (basic block). @@ -145,7 +145,7 @@ public: llvm_unreachable("Unknown instruction cost kind"); } - /// \brief Underlying constants for 'cost' values in this interface. + /// Underlying constants for 'cost' values in this interface. /// /// Many APIs in this interface return a cost. This enum defines the /// fundamental values that should be used to interpret (and produce) those @@ -169,7 +169,7 @@ public: TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86. }; - /// \brief Estimate the cost of a specific operation when lowered. + /// Estimate the cost of a specific operation when lowered. /// /// Note that this is designed to work on an arbitrary synthetic opcode, and /// thus work for hypothetical queries before an instruction has even been @@ -185,7 +185,7 @@ public: /// comments for a detailed explanation of the cost values. int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy = nullptr) const; - /// \brief Estimate the cost of a GEP operation when lowered. + /// Estimate the cost of a GEP operation when lowered. /// /// The contract for this function is the same as \c getOperationCost except /// that it supports an interface that provides extra information specific to @@ -193,14 +193,14 @@ public: int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) const; - /// \brief Estimate the cost of a EXT operation when lowered. + /// Estimate the cost of a EXT operation when lowered. /// /// The contract for this function is the same as \c getOperationCost except /// that it supports an interface that provides extra information specific to /// the EXT operation. int getExtCost(const Instruction *I, const Value *Src) const; - /// \brief Estimate the cost of a function call when lowered. + /// Estimate the cost of a function call when lowered. /// /// The contract for this is the same as \c getOperationCost except that it /// supports an interface that provides extra information specific to call @@ -211,13 +211,13 @@ public: /// The latter is only interesting for varargs function types. int getCallCost(FunctionType *FTy, int NumArgs = -1) const; - /// \brief Estimate the cost of calling a specific function when lowered. + /// Estimate the cost of calling a specific function when lowered. /// /// This overload adds the ability to reason about the particular function /// being called in the event it is a library call with special lowering. int getCallCost(const Function *F, int NumArgs = -1) const; - /// \brief Estimate the cost of calling a specific function when lowered. + /// Estimate the cost of calling a specific function when lowered. /// /// This overload allows specifying a set of candidate argument values. int getCallCost(const Function *F, ArrayRef Arguments) const; @@ -230,13 +230,13 @@ public: /// individual classes of instructions would be better. unsigned getInliningThresholdMultiplier() const; - /// \brief Estimate the cost of an intrinsic when lowered. + /// Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef ParamTys) const; - /// \brief Estimate the cost of an intrinsic when lowered. + /// Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, @@ -248,7 +248,7 @@ public: unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JTSize) const; - /// \brief Estimate the cost of a given IR user when lowered. + /// Estimate the cost of a given IR user when lowered. /// /// This can estimate the cost of either a ConstantExpr or Instruction when /// lowered. It has two primary advantages over the \c getOperationCost and @@ -271,7 +271,7 @@ public: /// comments for a detailed explanation of the cost values. int getUserCost(const User *U, ArrayRef Operands) const; - /// \brief This is a helper function which calls the two-argument getUserCost + /// This is a helper function which calls the two-argument getUserCost /// with \p Operands which are the current operands U has. int getUserCost(const User *U) const { SmallVector Operands(U->value_op_begin(), @@ -279,14 +279,14 @@ public: return getUserCost(U, Operands); } - /// \brief Return true if branch divergence exists. + /// Return true if branch divergence exists. /// /// Branch divergence has a significantly negative impact on GPU performance /// when threads in the same wavefront take different paths due to conditional /// branches. bool hasBranchDivergence() const; - /// \brief Returns whether V is a source of divergence. + /// Returns whether V is a source of divergence. /// /// This function provides the target-dependent information for /// the target-independent DivergenceAnalysis. DivergenceAnalysis first @@ -294,7 +294,7 @@ public: /// starting with the sources of divergence. bool isSourceOfDivergence(const Value *V) const; - // \brief Returns true for the target specific + // Returns true for the target specific // set of operations which produce uniform result // even taking non-unform arguments bool isAlwaysUniform(const Value *V) const; @@ -317,7 +317,7 @@ public: /// optimize away. unsigned getFlatAddressSpace() const; - /// \brief Test whether calls to a function lower to actual program function + /// Test whether calls to a function lower to actual program function /// calls. /// /// The idea is to test whether the program is likely to require a 'call' @@ -424,7 +424,7 @@ public: bool UnrollRemainder; }; - /// \brief Get target-customized preferences for the generic loop unrolling + /// Get target-customized preferences for the generic loop unrolling /// transformation. The caller will initialize UP with the current /// target-independent defaults. void getUnrollingPreferences(Loop *L, ScalarEvolution &, @@ -435,7 +435,7 @@ public: /// \name Scalar Target Information /// @{ - /// \brief Flags indicating the kind of support for population count. + /// Flags indicating the kind of support for population count. /// /// Compared to the SW implementation, HW support is supposed to /// significantly boost the performance when the population is dense, and it @@ -445,18 +445,18 @@ public: /// considered as "Slow". enum PopcntSupportKind { PSK_Software, PSK_SlowHardware, PSK_FastHardware }; - /// \brief Return true if the specified immediate is legal add immediate, that + /// Return true if the specified immediate is legal add immediate, that /// is the target has add instructions which can add a register with the /// immediate without having to materialize the immediate into a register. bool isLegalAddImmediate(int64_t Imm) const; - /// \brief Return true if the specified immediate is legal icmp immediate, + /// Return true if the specified immediate is legal icmp immediate, /// that is the target has icmp instructions which can compare a register /// against the immediate without having to materialize the immediate into a /// register. bool isLegalICmpImmediate(int64_t Imm) const; - /// \brief Return true if the addressing mode represented by AM is legal for + /// Return true if the addressing mode represented by AM is legal for /// this target, for a load/store of the specified type. /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. @@ -467,7 +467,7 @@ public: unsigned AddrSpace = 0, Instruction *I = nullptr) const; - /// \brief Return true if LSR cost of C1 is lower than C1. + /// Return true if LSR cost of C1 is lower than C1. bool isLSRCostLess(TargetTransformInfo::LSRCost &C1, TargetTransformInfo::LSRCost &C2) const; @@ -480,12 +480,12 @@ public: /// addressing mode expressions. bool shouldFavorPostInc() const; - /// \brief Return true if the target supports masked load/store + /// Return true if the target supports masked load/store /// AVX2 and AVX-512 targets allow masks for consecutive load and store bool isLegalMaskedStore(Type *DataType) const; bool isLegalMaskedLoad(Type *DataType) const; - /// \brief Return true if the target supports masked gather/scatter + /// Return true if the target supports masked gather/scatter /// AVX-512 fully supports gather and scatter for vectors with 32 and 64 /// bits scalar type. bool isLegalMaskedScatter(Type *DataType) const; @@ -508,7 +508,7 @@ public: /// Return true if target doesn't mind addresses in vectors. bool prefersVectorizedAddressing() const; - /// \brief Return the cost of the scaling factor used in the addressing + /// Return the cost of the scaling factor used in the addressing /// mode represented by AM for this target, for a load/store /// of the specified type. /// If the AM is supported, the return value must be >= 0. @@ -518,41 +518,41 @@ public: bool HasBaseReg, int64_t Scale, unsigned AddrSpace = 0) const; - /// \brief Return true if the loop strength reduce pass should make + /// Return true if the loop strength reduce pass should make /// Instruction* based TTI queries to isLegalAddressingMode(). This is /// needed on SystemZ, where e.g. a memcpy can only have a 12 bit unsigned /// immediate offset and no index register. bool LSRWithInstrQueries() const; - /// \brief Return true if it's free to truncate a value of type Ty1 to type + /// Return true if it's free to truncate a value of type Ty1 to type /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16 /// by referencing its sub-register AX. bool isTruncateFree(Type *Ty1, Type *Ty2) const; - /// \brief Return true if it is profitable to hoist instruction in the + /// Return true if it is profitable to hoist instruction in the /// then/else to before if. bool isProfitableToHoist(Instruction *I) const; bool useAA() const; - /// \brief Return true if this type is legal. + /// Return true if this type is legal. bool isTypeLegal(Type *Ty) const; - /// \brief Returns the target's jmp_buf alignment in bytes. + /// Returns the target's jmp_buf alignment in bytes. unsigned getJumpBufAlignment() const; - /// \brief Returns the target's jmp_buf size in bytes. + /// Returns the target's jmp_buf size in bytes. unsigned getJumpBufSize() const; - /// \brief Return true if switches should be turned into lookup tables for the + /// Return true if switches should be turned into lookup tables for the /// target. bool shouldBuildLookupTables() const; - /// \brief Return true if switches should be turned into lookup tables + /// Return true if switches should be turned into lookup tables /// containing this constant value for the target. bool shouldBuildLookupTablesForConstant(Constant *C) const; - /// \brief Return true if the input function which is cold at all call sites, + /// Return true if the input function which is cold at all call sites, /// should use coldcc calling convention. bool useColdCCForColdCall(Function &F) const; @@ -566,10 +566,10 @@ public: /// the scalarization cost of a load/store. bool supportsEfficientVectorElementLoadStore() const; - /// \brief Don't restrict interleaved unrolling to small loops. + /// Don't restrict interleaved unrolling to small loops. bool enableAggressiveInterleaving(bool LoopHasReductions) const; - /// \brief If not nullptr, enable inline expansion of memcmp. IsZeroCmp is + /// If not nullptr, enable inline expansion of memcmp. IsZeroCmp is /// true if this is the expansion of memcmp(p1, p2, s) == 0. struct MemCmpExpansionOptions { // The list of available load sizes (in bytes), sorted in decreasing order. @@ -577,10 +577,10 @@ public: }; const MemCmpExpansionOptions *enableMemCmpExpansion(bool IsZeroCmp) const; - /// \brief Enable matching of interleaved access groups. + /// Enable matching of interleaved access groups. bool enableInterleavedAccessVectorization() const; - /// \brief Indicate that it is potentially unsafe to automatically vectorize + /// Indicate that it is potentially unsafe to automatically vectorize /// floating-point operations because the semantics of vector and scalar /// floating-point semantics may differ. For example, ARM NEON v7 SIMD math /// does not support IEEE-754 denormal numbers, while depending on the @@ -589,16 +589,16 @@ public: /// operations, shuffles, or casts. bool isFPVectorizationPotentiallyUnsafe() const; - /// \brief Determine if the target supports unaligned memory accesses. + /// Determine if the target supports unaligned memory accesses. bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth, unsigned AddressSpace = 0, unsigned Alignment = 1, bool *Fast = nullptr) const; - /// \brief Return hardware support for population count. + /// Return hardware support for population count. PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; - /// \brief Return true if the hardware has a fast square-root instruction. + /// Return true if the hardware has a fast square-root instruction. bool haveFastSqrt(Type *Ty) const; /// Return true if it is faster to check if a floating-point value is NaN @@ -607,15 +607,15 @@ public: /// generally as cheap as checking for ordered/unordered. bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const; - /// \brief Return the expected cost of supporting the floating point operation + /// Return the expected cost of supporting the floating point operation /// of the specified type. int getFPOpCost(Type *Ty) const; - /// \brief Return the expected cost of materializing for the given integer + /// Return the expected cost of materializing for the given integer /// immediate of the specified type. int getIntImmCost(const APInt &Imm, Type *Ty) const; - /// \brief Return the expected cost of materialization for the given integer + /// Return the expected cost of materialization for the given integer /// immediate of the specified type for a given instruction. The cost can be /// zero if the immediate can be folded into the specified instruction. int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, @@ -623,7 +623,7 @@ public: int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty) const; - /// \brief Return the expected cost for the given integer when optimising + /// Return the expected cost for the given integer when optimising /// for size. This is different than the other integer immediate cost /// functions in that it is subtarget agnostic. This is useful when you e.g. /// target one ISA such as Aarch32 but smaller encodings could be possible @@ -637,11 +637,12 @@ public: /// \name Vector Target Information /// @{ - /// \brief The various kinds of shuffle patterns for vector queries. + /// The various kinds of shuffle patterns for vector queries. enum ShuffleKind { SK_Broadcast, ///< Broadcast element 0 to all other elements. SK_Reverse, ///< Reverse the order of the vector. SK_Alternate, ///< Choose alternate elements from vector. + SK_Transpose, ///< Transpose two vectors. SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset. SK_ExtractSubvector,///< ExtractSubvector Index indicates start offset. SK_PermuteTwoSrc, ///< Merge elements from two source vectors into one @@ -650,7 +651,7 @@ public: ///< shuffle mask. }; - /// \brief Additional information about an operand's possible values. + /// Additional information about an operand's possible values. enum OperandValueKind { OK_AnyValue, // Operand can have any value. OK_UniformValue, // Operand is uniform (splat of a value). @@ -658,7 +659,7 @@ public: OK_NonUniformConstantValue // Operand is a non uniform constant value. }; - /// \brief Additional properties of an operand's values. + /// Additional properties of an operand's values. enum OperandValueProperties { OP_None = 0, OP_PowerOf2 = 1 }; /// \return The number of scalar or vector registers that the target has. @@ -680,6 +681,11 @@ public: /// size of the widest element type. bool shouldMaximizeVectorBandwidth(bool OptSize) const; + /// \return The minimum vectorization factor for types of given element + /// bit width, or 0 if there is no mimimum VF. The returned value only + /// applies when shouldMaximizeVectorBandwidth returns true. + unsigned getMinimumVF(unsigned ElemWidth) const; + /// \return True if it should be considered for address type promotion. /// \p AllowPromotionWithoutCommonHeader Set true if promoting \p I is /// profitable without finding other extensions fed by the same input. @@ -806,7 +812,7 @@ public: ArrayRef Indices, unsigned Alignment, unsigned AddressSpace) const; - /// \brief Calculate the cost of performing a vector reduction. + /// Calculate the cost of performing a vector reduction. /// /// This is the cost of reducing the vector value of type \p Ty to a scalar /// value using the operation denoted by \p Opcode. The form of the reduction @@ -900,7 +906,7 @@ public: bool areInlineCompatible(const Function *Caller, const Function *Callee) const; - /// \brief The type of load/store indexing. + /// The type of load/store indexing. enum MemIndexedMode { MIM_Unindexed, ///< No indexing. MIM_PreInc, ///< Pre-incrementing. @@ -966,19 +972,19 @@ public: /// @} private: - /// \brief Estimate the latency of specified instruction. + /// Estimate the latency of specified instruction. /// Returns 1 as the default value. int getInstructionLatency(const Instruction *I) const; - /// \brief Returns the expected throughput cost of the instruction. + /// Returns the expected throughput cost of the instruction. /// Returns -1 if the cost is unknown. int getInstructionThroughput(const Instruction *I) const; - /// \brief The abstract base class used to type erase specific TTI + /// The abstract base class used to type erase specific TTI /// implementations. class Concept; - /// \brief The template model for the base class which wraps a concrete + /// The template model for the base class which wraps a concrete /// implementation in a type erased interface. template class Model; @@ -1074,6 +1080,7 @@ public: virtual unsigned getRegisterBitWidth(bool Vector) const = 0; virtual unsigned getMinVectorRegisterBitWidth() = 0; virtual bool shouldMaximizeVectorBandwidth(bool OptSize) const = 0; + virtual unsigned getMinimumVF(unsigned ElemWidth) const = 0; virtual bool shouldConsiderAddressTypePromotion( const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0; virtual unsigned getCacheLineSize() = 0; @@ -1373,6 +1380,9 @@ public: bool shouldMaximizeVectorBandwidth(bool OptSize) const override { return Impl.shouldMaximizeVectorBandwidth(OptSize); } + unsigned getMinimumVF(unsigned ElemWidth) const override { + return Impl.getMinimumVF(ElemWidth); + } bool shouldConsiderAddressTypePromotion( const Instruction &I, bool &AllowPromotionWithoutCommonHeader) override { return Impl.shouldConsiderAddressTypePromotion( @@ -1564,7 +1574,7 @@ template TargetTransformInfo::TargetTransformInfo(T Impl) : TTIImpl(new Model(Impl)) {} -/// \brief Analysis pass providing the \c TargetTransformInfo. +/// Analysis pass providing the \c TargetTransformInfo. /// /// The core idea of the TargetIRAnalysis is to expose an interface through /// which LLVM targets can analyze and provide information about the middle @@ -1579,13 +1589,13 @@ class TargetIRAnalysis : public AnalysisInfoMixin { public: typedef TargetTransformInfo Result; - /// \brief Default construct a target IR analysis. + /// Default construct a target IR analysis. /// /// This will use the module's datalayout to construct a baseline /// conservative TTI result. TargetIRAnalysis(); - /// \brief Construct an IR analysis pass around a target-provide callback. + /// Construct an IR analysis pass around a target-provide callback. /// /// The callback will be called with a particular function for which the TTI /// is needed and must return a TTI object for that function. @@ -1611,7 +1621,7 @@ private: friend AnalysisInfoMixin; static AnalysisKey Key; - /// \brief The callback used to produce a result. + /// The callback used to produce a result. /// /// We use a completely opaque callback so that targets can provide whatever /// mechanism they desire for constructing the TTI for a given function. @@ -1623,11 +1633,11 @@ private: /// the external TargetMachine, and that reference needs to never dangle. std::function TTICallback; - /// \brief Helper function used as the callback in the default constructor. + /// Helper function used as the callback in the default constructor. static Result getDefaultTTI(const Function &F); }; -/// \brief Wrapper pass for TargetTransformInfo. +/// Wrapper pass for TargetTransformInfo. /// /// This pass can be constructed from a TTI object which it stores internally /// and is queried by passes. @@ -1640,7 +1650,7 @@ class TargetTransformInfoWrapperPass : public ImmutablePass { public: static char ID; - /// \brief We must provide a default constructor for the pass but it should + /// We must provide a default constructor for the pass but it should /// never be used. /// /// Use the constructor below or call one of the creation routines. @@ -1651,7 +1661,7 @@ public: TargetTransformInfo &getTTI(const Function &F); }; -/// \brief Create an analysis pass wrapper around a TTI object. +/// Create an analysis pass wrapper around a TTI object. /// /// This analysis pass just holds the TTI instance and makes it available to /// clients. diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index df4f853acf9da235ef1f8c1e8275e0c598655db6..e14e2bd440345d85312a9797a836a00055ec7d21 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -27,7 +27,7 @@ namespace llvm { -/// \brief Base class for use as a mix-in that aids implementing +/// Base class for use as a mix-in that aids implementing /// a TargetTransformInfo-compatible class. class TargetTransformInfoImplBase { protected: @@ -155,6 +155,7 @@ public: case Intrinsic::sideeffect: case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::dbg_label: case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: @@ -353,6 +354,8 @@ public: bool shouldMaximizeVectorBandwidth(bool OptSize) const { return false; } + unsigned getMinimumVF(unsigned ElemWidth) const { return 0; } + bool shouldConsiderAddressTypePromotion(const Instruction &I, bool &AllowPromotionWithoutCommonHeader) { @@ -649,7 +652,7 @@ protected: } }; -/// \brief CRTP base class for use as a mix-in that aids implementing +/// CRTP base class for use as a mix-in that aids implementing /// a TargetTransformInfo-compatible class. template class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase { diff --git a/include/llvm/Analysis/TypeMetadataUtils.h b/include/llvm/Analysis/TypeMetadataUtils.h index 422e153a5a78cc761b1a1e410668bd6ced7f013b..6764563f6830d0980759f716dd4bf779b1d0c1bd 100644 --- a/include/llvm/Analysis/TypeMetadataUtils.h +++ b/include/llvm/Analysis/TypeMetadataUtils.h @@ -35,13 +35,13 @@ struct DevirtCallSite { CallSite CS; }; -/// Given a call to the intrinsic @llvm.type.test, find all devirtualizable +/// Given a call to the intrinsic \@llvm.type.test, find all devirtualizable /// call sites based on the call and return them in DevirtCalls. void findDevirtualizableCallsForTypeTest( SmallVectorImpl &DevirtCalls, SmallVectorImpl &Assumes, const CallInst *CI); -/// Given a call to the intrinsic @llvm.type.checked.load, find all +/// Given a call to the intrinsic \@llvm.type.checked.load, find all /// devirtualizable call sites based on the call and return them in DevirtCalls. void findDevirtualizableCallsForTypeCheckedLoad( SmallVectorImpl &DevirtCalls, diff --git a/include/llvm/Analysis/Utils/Local.h b/include/llvm/Analysis/Utils/Local.h index 42a654d3ddd79207ca568553528bc0bef4c5f79c..fb6444f72eb740c8bda873884b519f6ebb700f8f 100644 --- a/include/llvm/Analysis/Utils/Local.h +++ b/include/llvm/Analysis/Utils/Local.h @@ -141,6 +141,18 @@ bool wouldInstructionBeTriviallyDead(Instruction *I, bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI = nullptr); +/// Delete all of the instructions in `DeadInsts`, and all other instructions +/// that deleting these in turn causes to be trivially dead. +/// +/// The initial instructions in the provided vector must all have empty use +/// lists and satisfy `isInstructionTriviallyDead`. +/// +/// `DeadInsts` will be used as scratch storage for this routine and will be +/// empty afterward. +void RecursivelyDeleteTriviallyDeadInstructions( + SmallVectorImpl &DeadInsts, + const TargetLibraryInfo *TLI = nullptr); + /// If the specified value is an effectively dead PHI node, due to being a /// def-use chain of single-use nodes that either forms a cycle or is terminated /// by a trivially dead instruction, delete it. If that makes any of its diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index ced95df94d4e3981594e7fbe46abee39721e1a3a..249f0fdbd42701233b161caf58dadd3bdfb1851e 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -276,6 +276,22 @@ class Value; /// pointer, return 'len+1'. If we can't, return 0. uint64_t GetStringLength(const Value *V, unsigned CharSize = 8); + /// This function returns call pointer argument that is considered the same by + /// aliasing rules. You CAN'T use it to replace one value with another. + const Value *getArgumentAliasingToReturnedPointer(ImmutableCallSite CS); + inline Value *getArgumentAliasingToReturnedPointer(CallSite CS) { + return const_cast( + getArgumentAliasingToReturnedPointer(ImmutableCallSite(CS))); + } + + // {launder,strip}.invariant.group returns pointer that aliases its argument, + // and it only captures pointer by returning it. + // These intrinsics are not marked as nocapture, because returning is + // considered as capture. The arguments are not marked as returned neither, + // because it would make it useless. + bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( + ImmutableCallSite CS); + /// This method strips off any GEP address adjustments and pointer casts from /// the specified value, returning the original object being addressed. Note /// that the returned value has pointer type if the specified value does. If @@ -288,7 +304,7 @@ class Value; return GetUnderlyingObject(const_cast(V), DL, MaxLookup); } - /// \brief This method is similar to GetUnderlyingObject except that it can + /// This method is similar to GetUnderlyingObject except that it can /// look through phi and select instructions and return multiple objects. /// /// If LoopInfo is passed, loop phis are further analyzed. If a pointer @@ -384,6 +400,11 @@ class Value; AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT); + OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, + const DataLayout &DL, + AssumptionCache *AC, + const Instruction *CxtI, + const DominatorTree *DT); OverflowResult computeOverflowForUnsignedAdd(const Value *LHS, const Value *RHS, const DataLayout &DL, @@ -401,6 +422,16 @@ class Value; AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); + OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, + const DataLayout &DL, + AssumptionCache *AC, + const Instruction *CxtI, + const DominatorTree *DT); + OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, + const DataLayout &DL, + AssumptionCache *AC, + const Instruction *CxtI, + const DominatorTree *DT); /// Returns true if the arithmetic part of the \p II 's result is /// used only along the paths control dependent on the computation @@ -461,7 +492,7 @@ class Value; /// the parent of I. bool programUndefinedIfFullPoison(const Instruction *PoisonI); - /// \brief Specific patterns of select instructions we can match. + /// Specific patterns of select instructions we can match. enum SelectPatternFlavor { SPF_UNKNOWN = 0, SPF_SMIN, /// Signed minimum @@ -474,7 +505,7 @@ class Value; SPF_NABS /// Negated absolute value }; - /// \brief Behavior when a floating point min/max is given one NaN and one + /// Behavior when a floating point min/max is given one NaN and one /// non-NaN as input. enum SelectPatternNaNBehavior { SPNB_NA = 0, /// NaN behavior not applicable. @@ -502,6 +533,9 @@ class Value; /// Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind /// and providing the out parameter results if we successfully match. /// + /// For ABS/NABS, LHS will be set to the input to the abs idiom. RHS will be + /// the negation instruction from the idiom. + /// /// If CastOp is not nullptr, also match MIN/MAX idioms where the type does /// not match that of the original select. If this is the case, the cast /// operation (one of Trunc,SExt,Zext) that must be done to transform the diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h index 6315e8408f056bf6b10276c6f3f395815ae2d974..9fde36d61091a3b3223e0ad8abbbd3ccc567a6d6 100644 --- a/include/llvm/Analysis/VectorUtils.h +++ b/include/llvm/Analysis/VectorUtils.h @@ -33,50 +33,50 @@ namespace Intrinsic { enum ID : unsigned; } -/// \brief Identify if the intrinsic is trivially vectorizable. +/// Identify if the intrinsic is trivially vectorizable. /// This method returns true if the intrinsic's argument types are all /// scalars for the scalar form of the intrinsic and all vectors for /// the vector form of the intrinsic. bool isTriviallyVectorizable(Intrinsic::ID ID); -/// \brief Identifies if the intrinsic has a scalar operand. It checks for +/// Identifies if the intrinsic has a scalar operand. It checks for /// ctlz,cttz and powi special intrinsics whose argument is scalar. bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, unsigned ScalarOpdIdx); -/// \brief Returns intrinsic ID for call. +/// Returns intrinsic ID for call. /// For the input call instruction it finds mapping intrinsic and returns /// its intrinsic ID, in case it does not found it return not_intrinsic. Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI); -/// \brief Find the operand of the GEP that should be checked for consecutive +/// Find the operand of the GEP that should be checked for consecutive /// stores. This ignores trailing indices that have no effect on the final /// pointer. unsigned getGEPInductionOperand(const GetElementPtrInst *Gep); -/// \brief If the argument is a GEP, then returns the operand identified by +/// If the argument is a GEP, then returns the operand identified by /// getGEPInductionOperand. However, if there is some other non-loop-invariant /// operand, it returns that instead. Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp); -/// \brief If a value has only one user that is a CastInst, return it. +/// If a value has only one user that is a CastInst, return it. Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty); -/// \brief Get the stride of a pointer access in a loop. Looks for symbolic +/// Get the stride of a pointer access in a loop. Looks for symbolic /// strides "a[i*stride]". Returns the symbolic stride, or null otherwise. Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp); -/// \brief Given a vector and an element number, see if the scalar value is +/// Given a vector and an element number, see if the scalar value is /// already around as a register, for example if it were inserted then extracted /// from the vector. Value *findScalarElement(Value *V, unsigned EltNo); -/// \brief Get splat value if the input is a splat vector or return nullptr. +/// Get splat value if the input is a splat vector or return nullptr. /// The value may be extracted from a splat constants vector or from /// a sequence of instructions that broadcast a single value into a vector. const Value *getSplatValue(const Value *V); -/// \brief Compute a map of integer instructions to their minimum legal type +/// Compute a map of integer instructions to their minimum legal type /// size. /// /// C semantics force sub-int-sized values (e.g. i8, i16) to be promoted to int @@ -124,7 +124,7 @@ computeMinimumValueSizes(ArrayRef Blocks, /// This function always sets a (possibly null) value for each K in Kinds. Instruction *propagateMetadata(Instruction *I, ArrayRef VL); -/// \brief Create an interleave shuffle mask. +/// Create an interleave shuffle mask. /// /// This function creates a shuffle mask for interleaving \p NumVecs vectors of /// vectorization factor \p VF into a single wide vector. The mask is of the @@ -138,7 +138,7 @@ Instruction *propagateMetadata(Instruction *I, ArrayRef VL); Constant *createInterleaveMask(IRBuilder<> &Builder, unsigned VF, unsigned NumVecs); -/// \brief Create a stride shuffle mask. +/// Create a stride shuffle mask. /// /// This function creates a shuffle mask whose elements begin at \p Start and /// are incremented by \p Stride. The mask can be used to deinterleave an @@ -153,7 +153,7 @@ Constant *createInterleaveMask(IRBuilder<> &Builder, unsigned VF, Constant *createStrideMask(IRBuilder<> &Builder, unsigned Start, unsigned Stride, unsigned VF); -/// \brief Create a sequential shuffle mask. +/// Create a sequential shuffle mask. /// /// This function creates shuffle mask whose elements are sequential and begin /// at \p Start. The mask contains \p NumInts integers and is padded with \p @@ -167,7 +167,7 @@ Constant *createStrideMask(IRBuilder<> &Builder, unsigned Start, Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start, unsigned NumInts, unsigned NumUndefs); -/// \brief Concatenate a list of vectors. +/// Concatenate a list of vectors. /// /// This function generates code that concatenate the vectors in \p Vecs into a /// single large vector. The number of vectors should be greater than one, and diff --git a/include/llvm/AsmParser/Parser.h b/include/llvm/AsmParser/Parser.h index 4e2210192a09e8f23aeeec09315960a3b6d255db..c8c8e18a1fac0148d480ad99c7cd87dbbaebbb9c 100644 --- a/include/llvm/AsmParser/Parser.h +++ b/include/llvm/AsmParser/Parser.h @@ -30,7 +30,7 @@ class Type; /// Module (intermediate representation) with the corresponding features. Note /// that this does not verify that the generated Module is valid, so you should /// run the verifier after parsing the file to check that it is okay. -/// \brief Parse LLVM Assembly from a file +/// Parse LLVM Assembly from a file /// \param Filename The name of the file to parse /// \param Error Error result info. /// \param Context Context in which to allocate globals info. @@ -50,7 +50,7 @@ parseAssemblyFile(StringRef Filename, SMDiagnostic &Error, LLVMContext &Context, /// Module (intermediate representation) with the corresponding features. Note /// that this does not verify that the generated Module is valid, so you should /// run the verifier after parsing the file to check that it is okay. -/// \brief Parse LLVM Assembly from a string +/// Parse LLVM Assembly from a string /// \param AsmString The string containing assembly /// \param Error Error result info. /// \param Context Context in which to allocate globals info. @@ -68,7 +68,7 @@ std::unique_ptr parseAssemblyString(StringRef AsmString, StringRef DataLayoutString = ""); /// parseAssemblyFile and parseAssemblyString are wrappers around this function. -/// \brief Parse LLVM Assembly from a MemoryBuffer. +/// Parse LLVM Assembly from a MemoryBuffer. /// \param F The MemoryBuffer containing assembly /// \param Err Error result info. /// \param Slots The optional slot mapping that will be initialized during diff --git a/include/llvm/BinaryFormat/COFF.h b/include/llvm/BinaryFormat/COFF.h index 4d726aa5ce9668798ff0d15cb84d833ec781ab58..7b973c03cc80fc7d39d3d323065f21d913776c2d 100644 --- a/include/llvm/BinaryFormat/COFF.h +++ b/include/llvm/BinaryFormat/COFF.h @@ -463,7 +463,7 @@ union Auxiliary { AuxiliarySectionDefinition SectionDefinition; }; -/// @brief The Import Directory Table. +/// The Import Directory Table. /// /// There is a single array of these and one entry per imported DLL. struct ImportDirectoryTableEntry { @@ -474,7 +474,7 @@ struct ImportDirectoryTableEntry { uint32_t ImportAddressTableRVA; }; -/// @brief The PE32 Import Lookup Table. +/// The PE32 Import Lookup Table. /// /// There is an array of these for each imported DLL. It represents either /// the ordinal to import from the target DLL, or a name to lookup and import @@ -485,32 +485,32 @@ struct ImportDirectoryTableEntry { struct ImportLookupTableEntry32 { uint32_t data; - /// @brief Is this entry specified by ordinal, or name? + /// Is this entry specified by ordinal, or name? bool isOrdinal() const { return data & 0x80000000; } - /// @brief Get the ordinal value of this entry. isOrdinal must be true. + /// Get the ordinal value of this entry. isOrdinal must be true. uint16_t getOrdinal() const { assert(isOrdinal() && "ILT entry is not an ordinal!"); return data & 0xFFFF; } - /// @brief Set the ordinal value and set isOrdinal to true. + /// Set the ordinal value and set isOrdinal to true. void setOrdinal(uint16_t o) { data = o; data |= 0x80000000; } - /// @brief Get the Hint/Name entry RVA. isOrdinal must be false. + /// Get the Hint/Name entry RVA. isOrdinal must be false. uint32_t getHintNameRVA() const { assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!"); return data; } - /// @brief Set the Hint/Name entry RVA and set isOrdinal to false. + /// Set the Hint/Name entry RVA and set isOrdinal to false. void setHintNameRVA(uint32_t rva) { data = rva; } }; -/// @brief The DOS compatible header at the front of all PEs. +/// The DOS compatible header at the front of all PEs. struct DOSHeader { uint16_t Magic; uint16_t UsedBytesInTheLastPage; diff --git a/include/llvm/BinaryFormat/DynamicTags.def b/include/llvm/BinaryFormat/DynamicTags.def index c39f38a0c30649aac58c55f122fb9bdd923b145a..34c888d2759e0c0938dac7b2b96044346b4d7bb1 100644 --- a/include/llvm/BinaryFormat/DynamicTags.def +++ b/include/llvm/BinaryFormat/DynamicTags.def @@ -16,6 +16,11 @@ #define MIPS_DYNAMIC_TAG_DEFINED #endif +#ifndef PPC64_DYNAMIC_TAG +#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) +#define PPC64_DYNAMIC_TAG_DEFINED +#endif + #ifndef DYNAMIC_TAG_MARKER #define DYNAMIC_TAG_MARKER(name, value) DYNAMIC_TAG(name, value) #define DYNAMIC_TAG_MARKER_DEFINED @@ -171,6 +176,10 @@ MIPS_DYNAMIC_TAG(MIPS_RWPLT, 0x70000034) // Points to the base MIPS_DYNAMIC_TAG(MIPS_RLD_MAP_REL, 0x70000035) // Relative offset of run time loader // map, used for debugging. +// PPC64 specific dynamic table entries. +PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the + // first glink lazy resolver stub. + // Sun machine-independent extensions. DYNAMIC_TAG(AUXILIARY, 0x7FFFFFFD) // Shared object to load before self DYNAMIC_TAG(FILTER, 0x7FFFFFFF) // Shared object to get values from @@ -181,7 +190,13 @@ DYNAMIC_TAG(FILTER, 0x7FFFFFFF) // Shared object to get values from #endif #ifdef MIPS_DYNAMIC_TAG_DEFINED #undef MIPS_DYNAMIC_TAG +#undef MIPS_DYNAMIC_TAG_DEFINED #endif #ifdef HEXAGON_DYNAMIC_TAG_DEFINED #undef HEXAGON_DYNAMIC_TAG +#undef HEXAGON_DYNAMIC_TAG_DEFINED +#endif +#ifdef PPC64_DYNAMIC_TAG_DEFINED +#undef PPC64_DYNAMIC_TAG +#undef PPC64_DYNAMIC_TAG_DEFINED #endif diff --git a/include/llvm/BinaryFormat/ELF.h b/include/llvm/BinaryFormat/ELF.h index 4651e518c4bc2af218211d8f8958490b92cb0193..c4ec63cb43143c22b39d0619e3bb4bf0815fa3ca 100644 --- a/include/llvm/BinaryFormat/ELF.h +++ b/include/llvm/BinaryFormat/ELF.h @@ -658,8 +658,7 @@ enum : unsigned { EF_AMDGPU_MACH_NONE = 0x000, // R600-based processors. - EF_AMDGPU_MACH_R600_FIRST = 0x001, - EF_AMDGPU_MACH_R600_LAST = 0x010, + // Radeon HD 2000/3000 Series (R600). EF_AMDGPU_MACH_R600_R600 = 0x001, EF_AMDGPU_MACH_R600_R630 = 0x002, @@ -685,9 +684,12 @@ enum : unsigned { EF_AMDGPU_MACH_R600_RESERVED_FIRST = 0x011, EF_AMDGPU_MACH_R600_RESERVED_LAST = 0x01f, + // First/last R600-based processors. + EF_AMDGPU_MACH_R600_FIRST = EF_AMDGPU_MACH_R600_R600, + EF_AMDGPU_MACH_R600_LAST = EF_AMDGPU_MACH_R600_TURKS, + // AMDGCN-based processors. - EF_AMDGPU_MACH_AMDGCN_FIRST = 0x020, - EF_AMDGPU_MACH_AMDGCN_LAST = 0x02d, + // AMDGCN GFX6. EF_AMDGPU_MACH_AMDGCN_GFX600 = 0x020, EF_AMDGPU_MACH_AMDGCN_GFX601 = 0x021, @@ -705,12 +707,16 @@ enum : unsigned { // AMDGCN GFX9. EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c, EF_AMDGPU_MACH_AMDGCN_GFX902 = 0x02d, + EF_AMDGPU_MACH_AMDGCN_GFX904 = 0x02e, + EF_AMDGPU_MACH_AMDGCN_GFX906 = 0x02f, // Reserved for AMDGCN-based processors. EF_AMDGPU_MACH_AMDGCN_RESERVED0 = 0x027, - EF_AMDGPU_MACH_AMDGCN_RESERVED1 = 0x02e, - EF_AMDGPU_MACH_AMDGCN_RESERVED2 = 0x02f, - EF_AMDGPU_MACH_AMDGCN_RESERVED3 = 0x030, + EF_AMDGPU_MACH_AMDGCN_RESERVED1 = 0x030, + + // First/last AMDGCN-based processors. + EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600, + EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX906, // Indicates if the xnack target feature is enabled for all code contained in // the object. @@ -797,6 +803,7 @@ enum : unsigned { SHT_ANDROID_RELA = 0x60000002, SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table. SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options. + SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile. SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes. SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. @@ -1299,7 +1306,7 @@ enum { }; // Property types used in GNU_PROPERTY_TYPE_0 notes. -enum { +enum : unsigned { GNU_PROPERTY_STACK_SIZE = 1, GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2, }; diff --git a/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def b/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def index 3a47c5a07574bd723fa1bf8630773bb67bafc128..d2dbc793a135c37b200086cda8a7bdade8cc4caf 100644 --- a/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def +++ b/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def @@ -89,6 +89,7 @@ #undef R_PPC64_DTPREL16_HIGHESTA #undef R_PPC64_TLSGD #undef R_PPC64_TLSLD +#undef R_PPC64_IRELATIVE #undef R_PPC64_REL16 #undef R_PPC64_REL16_LO #undef R_PPC64_REL16_HI @@ -175,6 +176,7 @@ ELF_RELOC(R_PPC64_DTPREL16_HIGHEST, 105) ELF_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) ELF_RELOC(R_PPC64_TLSGD, 107) ELF_RELOC(R_PPC64_TLSLD, 108) +ELF_RELOC(R_PPC64_IRELATIVE, 248) ELF_RELOC(R_PPC64_REL16, 249) ELF_RELOC(R_PPC64_REL16_LO, 250) ELF_RELOC(R_PPC64_REL16_HI, 251) diff --git a/include/llvm/BinaryFormat/MachO.h b/include/llvm/BinaryFormat/MachO.h index 060fbe162ad26bc87cfc84360eb2f16dec18c142..2eacc6d8cc05f93df68f158cc27b4ac45669d141 100644 --- a/include/llvm/BinaryFormat/MachO.h +++ b/include/llvm/BinaryFormat/MachO.h @@ -1973,9 +1973,11 @@ const uint32_t PPC_THREAD_STATE_COUNT = // Define a union of all load command structs #define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data; -union macho_load_command { +LLVM_PACKED_START +union LLVM_ALIGNAS(4) macho_load_command { #include "llvm/BinaryFormat/MachO.def" }; +LLVM_PACKED_END } // end namespace MachO } // end namespace llvm diff --git a/include/llvm/BinaryFormat/Magic.h b/include/llvm/BinaryFormat/Magic.h index 4ac826e4c508236d03ac2ff70d5cbf425d9362c3..04801f810be37bee2dfb55e0bb36acfd8a1ef68f 100644 --- a/include/llvm/BinaryFormat/Magic.h +++ b/include/llvm/BinaryFormat/Magic.h @@ -59,10 +59,10 @@ private: Impl V = unknown; }; -/// @brief Identify the type of a binary file based on how magical it is. +/// Identify the type of a binary file based on how magical it is. file_magic identify_magic(StringRef magic); -/// @brief Get and identify \a path's type based on its content. +/// Get and identify \a path's type based on its content. /// /// @param path Input path. /// @param result Set to the type of file, or file_magic::unknown. diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 91b217fbf165973d80e76977192ea6fd1d9c86eb..fa5448dacec4e6895bc41f4eb7e085cce4c85083 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -24,6 +24,8 @@ namespace wasm { const char WasmMagic[] = {'\0', 'a', 's', 'm'}; // Wasm binary format version const uint32_t WasmVersion = 0x1; +// Wasm linking metadata version +const uint32_t WasmMetadataVersion = 0x1; // Wasm uses a 64k page size const uint32_t WasmPageSize = 65536; @@ -74,7 +76,7 @@ struct WasmGlobal { uint32_t Index; WasmGlobalType Type; WasmInitExpr InitExpr; - StringRef Name; // from the "linking" or "names" section + StringRef SymbolName; // from the "linking" section }; struct WasmImport { @@ -100,7 +102,9 @@ struct WasmFunction { ArrayRef Body; uint32_t CodeSectionOffset; uint32_t Size; - StringRef Name; // from the "linking" or "names" section + uint32_t CodeOffset; // start of Locals and Body + StringRef SymbolName; // from the "linking" section + StringRef DebugName; // from the "name" section uint32_t Comdat; // from the "comdat info" section }; @@ -108,7 +112,7 @@ struct WasmDataSegment { uint32_t MemoryIndex; WasmInitExpr Offset; ArrayRef Content; - StringRef Name; + StringRef Name; // from the "segment info" section uint32_t Alignment; uint32_t Flags; uint32_t Comdat; // from the "comdat info" section @@ -144,8 +148,9 @@ struct WasmSymbolInfo { StringRef Name; uint8_t Kind; uint32_t Flags; + StringRef Module; // For undefined symbols the module name of the import union { - // For function or global symbols, the index in function of global index + // For function or global symbols, the index in function or global index // space. uint32_t ElementIndex; // For a data symbols, the address of the data relative to segment. @@ -159,6 +164,7 @@ struct WasmFunctionName { }; struct WasmLinkingData { + uint32_t Version; std::vector InitFunctions; std::vector Comdats; std::vector SymbolTable; @@ -245,8 +251,9 @@ enum : unsigned { // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE enum WasmSymbolType : unsigned { WASM_SYMBOL_TYPE_FUNCTION = 0x0, - WASM_SYMBOL_TYPE_DATA = 0x1, - WASM_SYMBOL_TYPE_GLOBAL = 0x2, + WASM_SYMBOL_TYPE_DATA = 0x1, + WASM_SYMBOL_TYPE_GLOBAL = 0x2, + WASM_SYMBOL_TYPE_SECTION = 0x3, }; const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; @@ -284,6 +291,9 @@ inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { return !(LHS == RHS); } +std::string toString(wasm::WasmSymbolType type); +std::string relocTypetoString(uint32_t type); + } // end namespace wasm } // end namespace llvm diff --git a/include/llvm/BinaryFormat/WasmRelocs.def b/include/llvm/BinaryFormat/WasmRelocs.def index d6f0e42b33bf2724dd22731047d6ba538388d638..8ffd51e483f38bdf9cba9e289d7a0a16601f7987 100644 --- a/include/llvm/BinaryFormat/WasmRelocs.def +++ b/include/llvm/BinaryFormat/WasmRelocs.def @@ -11,3 +11,5 @@ WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_SLEB, 4) WASM_RELOC(R_WEBASSEMBLY_MEMORY_ADDR_I32, 5) WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6) WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7) +WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32, 8) +WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32, 9) diff --git a/include/llvm/Bitcode/BitcodeWriter.h b/include/llvm/Bitcode/BitcodeWriter.h index fa3229533c838bd7cfcb7ff5073b930cd6d32908..0010cf6c0544265335bcb49ca4bd66bc5bd868a4 100644 --- a/include/llvm/Bitcode/BitcodeWriter.h +++ b/include/llvm/Bitcode/BitcodeWriter.h @@ -105,7 +105,7 @@ class raw_ostream; const std::map *ModuleToSummariesForIndex); }; - /// \brief Write the specified module to the specified raw output stream. + /// Write the specified module to the specified raw output stream. /// /// For streams where it matters, the given stream should be in "binary" /// mode. diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h index 9ac6fba16b96958da49b334e672974fed599f27d..05044c9ae11c2e48698a118661a841a48ad2d90d 100644 --- a/include/llvm/Bitcode/BitcodeWriterPass.h +++ b/include/llvm/Bitcode/BitcodeWriterPass.h @@ -21,9 +21,10 @@ namespace llvm { class Module; class ModulePass; +class Pass; class raw_ostream; -/// \brief Create and return a pass that writes the module to the specified +/// Create and return a pass that writes the module to the specified /// ostream. Note that this pass is designed for use with the legacy pass /// manager. /// @@ -40,7 +41,10 @@ ModulePass *createBitcodeWriterPass(raw_ostream &Str, bool EmitSummaryIndex = false, bool EmitModuleHash = false); -/// \brief Pass for writing a module of IR out to a bitcode file. +/// Check whether a pass is a BitcodeWriterPass. +bool isBitcodeWriterPass(Pass *P); + +/// Pass for writing a module of IR out to a bitcode file. /// /// Note that this is intended for use with the new pass manager. To construct /// a pass for the legacy pass manager, use the function above. @@ -51,7 +55,7 @@ class BitcodeWriterPass : public PassInfoMixin { bool EmitModuleHash; public: - /// \brief Construct a bitcode writer pass around a particular output stream. + /// Construct a bitcode writer pass around a particular output stream. /// /// If \c ShouldPreserveUseListOrder, encode use-list order so it can be /// reproduced when deserialized. @@ -65,7 +69,7 @@ public: : OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {} - /// \brief Run the bitcode writer pass, and output the module to the selected + /// Run the bitcode writer pass, and output the module to the selected /// output stream. PreservedAnalyses run(Module &M, ModuleAnalysisManager &); }; diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index e276db5f92f66416441a84a7058ae6a375dedd49..c854769e06229692c33e98ff7b99b7efceebf423 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -90,10 +90,10 @@ public: assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance"); } - /// \brief Retrieve the current position in the stream, in bits. + /// Retrieve the current position in the stream, in bits. uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } - /// \brief Retrieve the number of bits currently used to encode an abbrev ID. + /// Retrieve the number of bits currently used to encode an abbrev ID. unsigned GetAbbrevIDWidth() const { return CurCodeSize; } //===--------------------------------------------------------------------===// diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index f3500e13c5f79706be167924a080cffb1410a7a6..6723cf42dd2ce55ee9c8e3b25e2868777fd12d8b 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -310,6 +310,7 @@ enum MetadataCodes { METADATA_GLOBAL_VAR_EXPR = 37, // [distinct, var, expr] METADATA_INDEX_OFFSET = 38, // [offset] METADATA_INDEX = 39, // [bitpos] + METADATA_LABEL = 40, // [distinct, scope, name, file, line] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each @@ -589,6 +590,7 @@ enum AttributeKindCodes { ATTR_KIND_SANITIZE_HWADDRESS = 55, ATTR_KIND_NOCF_CHECK = 56, ATTR_KIND_OPT_FOR_FUZZING = 57, + ATTR_KIND_SHADOWCALLSTACK = 58, }; enum ComdatSelectionKindCodes { diff --git a/include/llvm/CodeGen/AccelTable.h b/include/llvm/CodeGen/AccelTable.h index ec850a87c5991e9b8747a06b0a156984cd4fa64f..d5088b3ce1404c128bf6afa31ede3e05f454d633 100644 --- a/include/llvm/CodeGen/AccelTable.h +++ b/include/llvm/CodeGen/AccelTable.h @@ -108,6 +108,8 @@ namespace llvm { class AsmPrinter; +class DwarfCompileUnit; +class DwarfDebug; /// Interface which the different types of accelerator table data have to /// conform. It serves as a base class for different values of the template @@ -244,6 +246,28 @@ public: static uint32_t hash(StringRef Buffer) { return djbHash(Buffer); } }; +/// The Data class implementation for DWARF v5 accelerator table. Unlike the +/// Apple Data classes, this class is just a DIE wrapper, and does not know to +/// serialize itself. The complete serialization logic is in the +/// emitDWARF5AccelTable function. +class DWARF5AccelTableData : public AccelTableData { +public: + static uint32_t hash(StringRef Name) { return caseFoldingDjbHash(Name); } + + DWARF5AccelTableData(const DIE &Die) : Die(Die) {} + +#ifndef NDEBUG + void print(raw_ostream &OS) const override; +#endif + + const DIE &getDie() const { return Die; } + +protected: + const DIE &Die; + + uint64_t order() const override { return Die.getOffset(); } +}; + void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, StringRef Prefix, const MCSymbol *SecBegin, ArrayRef Atoms); @@ -258,6 +282,11 @@ void emitAppleAccelTable(AsmPrinter *Asm, AccelTable &Contents, emitAppleAccelTableImpl(Asm, Contents, Prefix, SecBegin, DataT::Atoms); } +void emitDWARF5AccelTable(AsmPrinter *Asm, + AccelTable &Contents, + const DwarfDebug &DD, + ArrayRef> CUs); + /// Accelerator table data implementation for simple Apple accelerator tables /// with just a DIE reference. class AppleAccelTableOffsetData : public AppleAccelTableData { diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index ba88f1f78fb836717ef05493d97a10f43d7b989c..d77aee66ed764068630a3d50427aa52759ae94c7 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -36,7 +36,7 @@ class SDValue; class SelectionDAG; struct EVT; -/// \brief Compute the linearized index of a member in a nested +/// Compute the linearized index of a member in a nested /// aggregate/struct/array. /// /// Given an LLVM IR aggregate type and a sequence of insertvalue or @@ -124,7 +124,7 @@ bool returnTypeIsEligibleForTailCall(const Function *F, const Instruction *I, const TargetLoweringBase &TLI); DenseMap -getFuncletMembership(const MachineFunction &MF); +getEHScopeMembership(const MachineFunction &MF); } // End llvm namespace diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 3d3bd3affcce60f88d45247e9f2607822c0e27e0..182154103523edb0fecd112e6f5f0860f4387761 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -50,6 +50,7 @@ class GlobalValue; class GlobalVariable; class MachineBasicBlock; class MachineConstantPoolValue; +class MachineDominatorTree; class MachineFunction; class MachineInstr; class MachineJumpTableInfo; @@ -92,11 +93,17 @@ public: std::unique_ptr OutStreamer; /// The current machine function. - const MachineFunction *MF = nullptr; + MachineFunction *MF = nullptr; /// This is a pointer to the current MachineModuleInfo. MachineModuleInfo *MMI = nullptr; + /// This is a pointer to the current MachineLoopInfo. + MachineDominatorTree *MDT = nullptr; + + /// This is a pointer to the current MachineLoopInfo. + MachineLoopInfo *MLI = nullptr; + /// Optimization remark emitter. MachineOptimizationRemarkEmitter *ORE; @@ -130,9 +137,6 @@ private: static char ID; - /// If VerboseAsm is set, a pointer to the loop info for this function. - MachineLoopInfo *LI = nullptr; - struct HandlerInfo { AsmPrinterHandler *Handler; const char *TimerName; @@ -161,6 +165,12 @@ public: }; private: + /// If generated on the fly this own the instance. + std::unique_ptr OwnedMDT; + + /// If generated on the fly this own the instance. + std::unique_ptr OwnedMLI; + /// Structure for generating diagnostics for inline assembly. Only initialised /// when necessary. mutable std::unique_ptr DiagInfo; @@ -228,6 +238,7 @@ public: TAIL_CALL = 2, LOG_ARGS_ENTER = 3, CUSTOM_EVENT = 4, + TYPED_EVENT = 5, }; // The table will contain these structs that point to the sled, the function @@ -332,10 +343,10 @@ public: /// Lower the specified LLVM Constant to an MCExpr. virtual const MCExpr *lowerConstant(const Constant *CV); - /// \brief Print a general LLVM constant to the .s file. + /// Print a general LLVM constant to the .s file. void EmitGlobalConstant(const DataLayout &DL, const Constant *CV); - /// \brief Unnamed constant global variables solely contaning a pointer to + /// Unnamed constant global variables solely contaning a pointer to /// another globals variable act like a global variable "proxy", or GOT /// equivalents, i.e., it's only used to hold the address of the latter. One /// optimization is to replace accesses to these proxies by using the GOT @@ -345,7 +356,7 @@ public: /// accesses to GOT entries. void computeGlobalGOTEquivs(Module &M); - /// \brief Constant expressions using GOT equivalent globals may not be + /// Constant expressions using GOT equivalent globals may not be /// eligible for PC relative GOT entry conversion, in such cases we need to /// emit the proxies we previously omitted in EmitGlobalVariable. void emitGlobalGOTEquivs(); @@ -452,6 +463,9 @@ public: /// Emit a long directive and value. void emitInt32(int Value) const; + /// Emit a long long directive and value. + void emitInt64(uint64_t Value) const; + /// Emit something like ".long Hi-Lo" where the size in bytes of the directive /// is specified by Size and Hi/Lo specify the labels. This implicitly uses /// .set if it is available. @@ -530,10 +544,10 @@ public: // Dwarf Lowering Routines //===------------------------------------------------------------------===// - /// \brief Emit frame instruction to describe the layout of the frame. + /// Emit frame instruction to describe the layout of the frame. void emitCFIInstruction(const MCCFIInstruction &Inst) const; - /// \brief Emit Dwarf abbreviation table. + /// Emit Dwarf abbreviation table. template void emitDwarfAbbrevs(const T &Abbrevs) const { // For each abbreviation. for (const auto &Abbrev : Abbrevs) @@ -545,7 +559,7 @@ public: void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const; - /// \brief Recursively emit Dwarf DIE tree. + /// Recursively emit Dwarf DIE tree. void emitDwarfDIE(const DIE &Die) const; //===------------------------------------------------------------------===// @@ -634,8 +648,7 @@ private: GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C); /// Emit GlobalAlias or GlobalIFunc. - void emitGlobalIndirectSymbol(Module &M, - const GlobalIndirectSymbol& GIS); + void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS); void setupCodePaddingContext(const MachineBasicBlock &MBB, MCCodePaddingContext &Context) const; }; diff --git a/include/llvm/CodeGen/AtomicExpandUtils.h b/include/llvm/CodeGen/AtomicExpandUtils.h index 1f9c96b18e1b4542958787a17789b9c9b659a5ee..7fcbd46c0d9b807052e159aac9fb5ebea4aac0ef 100644 --- a/include/llvm/CodeGen/AtomicExpandUtils.h +++ b/include/llvm/CodeGen/AtomicExpandUtils.h @@ -26,7 +26,7 @@ using CreateCmpXchgInstFun = function_ref &, Value *, Value *, Value *, AtomicOrdering, Value *&, Value *&)>; -/// \brief Expand an atomic RMW instruction into a loop utilizing +/// Expand an atomic RMW instruction into a loop utilizing /// cmpxchg. You'll want to make sure your target machine likes cmpxchg /// instructions in the first place and that there isn't another, better, /// transformation available (for example AArch32/AArch64 have linked loads). diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index 9096263d9e6bdba7e72905dd667526929127352c..4db2a9fe62d5d379e751740ab63912c50e9df22c 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -65,7 +65,7 @@ class TargetMachine; extern cl::opt PartialUnrollingThreshold; -/// \brief Base class which can be used to help build a TTI implementation. +/// Base class which can be used to help build a TTI implementation. /// /// This class provides as much implementation of the TTI interface as is /// possible using the target independent parts of the code generator. @@ -101,12 +101,12 @@ private: return Cost; } - /// \brief Local query method delegates up to T which *must* implement this! + /// Local query method delegates up to T which *must* implement this! const TargetSubtargetInfo *getST() const { return static_cast(this)->getST(); } - /// \brief Local query method delegates up to T which *must* implement this! + /// Local query method delegates up to T which *must* implement this! const TargetLoweringBase *getTLI() const { return static_cast(this)->getTLI(); } @@ -553,11 +553,15 @@ public: unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, Type *SubTp) { - if (Kind == TTI::SK_Alternate || Kind == TTI::SK_PermuteTwoSrc || - Kind == TTI::SK_PermuteSingleSrc) { + switch (Kind) { + case TTI::SK_Alternate: + case TTI::SK_Transpose: + case TTI::SK_PermuteSingleSrc: + case TTI::SK_PermuteTwoSrc: return getPermuteShuffleOverhead(Tp); + default: + return 1; } - return 1; } unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, @@ -1200,7 +1204,7 @@ public: return SingleCallCost; } - /// \brief Compute a cost of the given call instruction. + /// Compute a cost of the given call instruction. /// /// Compute the cost of calling function F with return type RetTy and /// argument types Tys. F might be nullptr, in this case the cost of an @@ -1361,7 +1365,7 @@ public: /// @} }; -/// \brief Concrete BasicTTIImpl that can be used if no further customization +/// Concrete BasicTTIImpl that can be used if no further customization /// is needed. class BasicTTIImpl : public BasicTTIImplBase { using BaseT = BasicTTIImplBase; diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index d9e8206408a7843d8a3d536dcf2d55ca81a18db1..f85767f1fc119641085a66a54f777313590c8b61 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -22,7 +22,7 @@ class MachineFunction; class MachineLoopInfo; class VirtRegMap; - /// \brief Normalize the spill weight of a live interval + /// Normalize the spill weight of a live interval /// /// The spill weight of a live interval is computed as: /// @@ -42,7 +42,7 @@ class VirtRegMap; return UseDefFreq / (Size + 25*SlotIndex::InstrDist); } - /// \brief Calculate auxiliary information for a virtual register such as its + /// Calculate auxiliary information for a virtual register such as its /// spill weight and allocation hint. class VirtRegAuxInfo { public: @@ -64,10 +64,10 @@ class VirtRegMap; NormalizingFn norm = normalizeSpillWeight) : MF(mf), LIS(lis), VRM(vrm), Loops(loops), MBFI(mbfi), normalize(norm) {} - /// \brief (re)compute li's spill weight and allocation hint. + /// (re)compute li's spill weight and allocation hint. void calculateSpillWeightAndHint(LiveInterval &li); - /// \brief Compute future expected spill weight of a split artifact of li + /// Compute future expected spill weight of a split artifact of li /// that will span between start and end slot indexes. /// \param li The live interval to be split. /// \param start The expected begining of the split artifact. Instructions @@ -78,7 +78,7 @@ class VirtRegMap; /// negative weight for unspillable li. float futureWeight(LiveInterval &li, SlotIndex start, SlotIndex end); - /// \brief Helper function for weight calculations. + /// Helper function for weight calculations. /// (Re)compute li's spill weight and allocation hint, or, for non null /// start and end - compute future expected spill weight of a split /// artifact of li that will span between start and end slot indexes. @@ -94,7 +94,7 @@ class VirtRegMap; SlotIndex *end = nullptr); }; - /// \brief Compute spill weights and allocation hints for all virtual register + /// Compute spill weights and allocation hints for all virtual register /// live intervals. void calculateSpillWeightsAndHints(LiveIntervals &LIS, MachineFunction &MF, VirtRegMap *VRM, diff --git a/include/llvm/CodeGen/CommandFlags.def b/include/llvm/CodeGen/CommandFlags.inc similarity index 99% rename from include/llvm/CodeGen/CommandFlags.def rename to include/llvm/CodeGen/CommandFlags.inc index 3708c044decd46bc36de59dc57a34e031fbf3d1c..8373b3b46ca80c1c3b44f68edc717a3079376e74 100644 --- a/include/llvm/CodeGen/CommandFlags.def +++ b/include/llvm/CodeGen/CommandFlags.inc @@ -17,7 +17,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" -#include "llvm/MC/MCTargetOptionsCommandFlags.def" +#include "llvm/MC/MCTargetOptionsCommandFlags.inc" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" @@ -349,7 +349,7 @@ LLVM_ATTRIBUTE_UNUSED static std::vector getFeatureList() { return Features.getFeatures(); } -/// \brief Set function attributes of functions in Module M based on CPU, +/// Set function attributes of functions in Module M based on CPU, /// Features, and command line flags. LLVM_ATTRIBUTE_UNUSED static void setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) { diff --git a/include/llvm/CodeGen/CostTable.h b/include/llvm/CodeGen/CostTable.h index 0fc16d39aa281c22a7a2a645489a3009bb3fd12d..48ad76971520db0ae6cd8f8641f6634c7e2c7017 100644 --- a/include/llvm/CodeGen/CostTable.h +++ b/include/llvm/CodeGen/CostTable.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Cost tables and simple lookup functions +/// Cost tables and simple lookup functions /// //===----------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index f809fc97fe593981f1e53471c6f8e5272ecbcd5b..c76d3114edf71c8d62ef8c42222bbde71830ef2d 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -136,7 +136,7 @@ class DIEAbbrevSet { /// The bump allocator to use when creating DIEAbbrev objects in the uniqued /// storage container. BumpPtrAllocator &Alloc; - /// \brief FoldingSet that uniques the abbreviations. + /// FoldingSet that uniques the abbreviations. FoldingSet AbbreviationsSet; /// A list of all the unique abbreviations in use. std::vector Abbreviations; diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 772bd6c6042f66cc64f4619574acb4c9e342387d..3d351fd20a3879290249c8fae7036ebb429b3aa7 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -61,7 +61,7 @@ class Type; class User; class Value; -/// \brief This is a fast-path instruction selection class that generates poor +/// This is a fast-path instruction selection class that generates poor /// code and doesn't support illegal types or non-trivial lowering, but runs /// quickly. class FastISel { @@ -78,7 +78,7 @@ public: bool IsReturnValueUsed : 1; bool IsPatchPoint : 1; - // \brief IsTailCall Should be modified by implementations of FastLowerCall + // IsTailCall Should be modified by implementations of FastLowerCall // that perform tail call conversions. bool IsTailCall = false; @@ -215,70 +215,74 @@ protected: const TargetLibraryInfo *LibInfo; bool SkipTargetIndependentISel; - /// \brief The position of the last instruction for materializing constants + /// The position of the last instruction for materializing constants /// for use in the current block. It resets to EmitStartPt when it makes sense /// (for example, it's usually profitable to avoid function calls between the /// definition and the use) MachineInstr *LastLocalValue; - /// \brief The top most instruction in the current block that is allowed for + /// The top most instruction in the current block that is allowed for /// emitting local variables. LastLocalValue resets to EmitStartPt when it /// makes sense (for example, on function calls) MachineInstr *EmitStartPt; + /// Last local value flush point. On a subsequent flush, no local value will + /// sink past this point. + MachineBasicBlock::iterator LastFlushPoint; + public: virtual ~FastISel(); - /// \brief Return the position of the last instruction emitted for + /// Return the position of the last instruction emitted for /// materializing constants for use in the current block. MachineInstr *getLastLocalValue() { return LastLocalValue; } - /// \brief Update the position of the last instruction emitted for + /// Update the position of the last instruction emitted for /// materializing constants for use in the current block. void setLastLocalValue(MachineInstr *I) { EmitStartPt = I; LastLocalValue = I; } - /// \brief Set the current block to which generated machine instructions will + /// Set the current block to which generated machine instructions will /// be appended. void startNewBlock(); /// Flush the local value map and sink local values if possible. void finishBasicBlock(); - /// \brief Return current debug location information. + /// Return current debug location information. DebugLoc getCurDebugLoc() const { return DbgLoc; } - /// \brief Do "fast" instruction selection for function arguments and append + /// Do "fast" instruction selection for function arguments and append /// the machine instructions to the current block. Returns true when /// successful. bool lowerArguments(); - /// \brief Do "fast" instruction selection for the given LLVM IR instruction + /// Do "fast" instruction selection for the given LLVM IR instruction /// and append the generated machine instructions to the current block. /// Returns true if selection was successful. bool selectInstruction(const Instruction *I); - /// \brief Do "fast" instruction selection for the given LLVM IR operator + /// Do "fast" instruction selection for the given LLVM IR operator /// (Instruction or ConstantExpr), and append generated machine instructions /// to the current block. Return true if selection was successful. bool selectOperator(const User *I, unsigned Opcode); - /// \brief Create a virtual register and arrange for it to be assigned the + /// Create a virtual register and arrange for it to be assigned the /// value for the given LLVM value. unsigned getRegForValue(const Value *V); - /// \brief Look up the value to see if its value is already cached in a + /// Look up the value to see if its value is already cached in a /// register. It may be defined by instructions across blocks or defined /// locally. unsigned lookUpRegForValue(const Value *V); - /// \brief This is a wrapper around getRegForValue that also takes care of + /// This is a wrapper around getRegForValue that also takes care of /// truncating or sign-extending the given getelementptr index value. std::pair getRegForGEPIndex(const Value *V); - /// \brief We're checking to see if we can fold \p LI into \p FoldInst. Note + /// We're checking to see if we can fold \p LI into \p FoldInst. Note /// that we could have a sequence where multiple LLVM IR instructions are /// folded into the same machineinstr. For example we could have: /// @@ -292,7 +296,7 @@ public: /// If we succeed folding, return true. bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst); - /// \brief The specified machine instr operand is a vreg, and that vreg is + /// The specified machine instr operand is a vreg, and that vreg is /// being provided by the specified load instruction. If possible, try to /// fold the load as an operand to the instruction, returning true if /// possible. @@ -303,11 +307,11 @@ public: return false; } - /// \brief Reset InsertPt to prepare for inserting instructions into the + /// Reset InsertPt to prepare for inserting instructions into the /// current block. void recomputeInsertPt(); - /// \brief Remove all dead instructions between the I and E. + /// Remove all dead instructions between the I and E. void removeDeadCode(MachineBasicBlock::iterator I, MachineBasicBlock::iterator E); @@ -316,11 +320,11 @@ public: DebugLoc DL; }; - /// \brief Prepare InsertPt to begin inserting instructions into the local + /// Prepare InsertPt to begin inserting instructions into the local /// value area and return the old insert position. SavePoint enterLocalValueArea(); - /// \brief Reset InsertPt to the given old insert position. + /// Reset InsertPt to the given old insert position. void leaveLocalValueArea(SavePoint Old); protected: @@ -328,45 +332,45 @@ protected: const TargetLibraryInfo *LibInfo, bool SkipTargetIndependentISel = false); - /// \brief This method is called by target-independent code when the normal + /// This method is called by target-independent code when the normal /// FastISel process fails to select an instruction. This gives targets a /// chance to emit code for anything that doesn't fit into FastISel's /// framework. It returns true if it was successful. virtual bool fastSelectInstruction(const Instruction *I) = 0; - /// \brief This method is called by target-independent code to do target- + /// This method is called by target-independent code to do target- /// specific argument lowering. It returns true if it was successful. virtual bool fastLowerArguments(); - /// \brief This method is called by target-independent code to do target- + /// This method is called by target-independent code to do target- /// specific call lowering. It returns true if it was successful. virtual bool fastLowerCall(CallLoweringInfo &CLI); - /// \brief This method is called by target-independent code to do target- + /// This method is called by target-independent code to do target- /// specific intrinsic lowering. It returns true if it was successful. virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type and opcode be emitted. virtual unsigned fastEmit_(MVT VT, MVT RetVT, unsigned Opcode); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type, opcode, and register operand be emitted. virtual unsigned fastEmit_r(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0, bool Op0IsKill); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type, opcode, and register operands be emitted. virtual unsigned fastEmit_rr(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type, opcode, and register and immediate /// operands be emitted. virtual unsigned fastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0, bool Op0IsKill, uint64_t Imm); - /// \brief This method is a wrapper of fastEmit_ri. + /// This method is a wrapper of fastEmit_ri. /// /// It first tries to emit an instruction with an immediate operand using /// fastEmit_ri. If that fails, it materializes the immediate into a register @@ -374,80 +378,80 @@ protected: unsigned fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, bool Op0IsKill, uint64_t Imm, MVT ImmType); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type, opcode, and immediate operand be emitted. virtual unsigned fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm); - /// \brief This method is called by target-independent code to request that an + /// This method is called by target-independent code to request that an /// instruction with the given type, opcode, and floating-point immediate /// operand be emitted. virtual unsigned fastEmit_f(MVT VT, MVT RetVT, unsigned Opcode, const ConstantFP *FPImm); - /// \brief Emit a MachineInstr with no operands and a result register in the + /// Emit a MachineInstr with no operands and a result register in the /// given register class. unsigned fastEmitInst_(unsigned MachineInstOpcode, const TargetRegisterClass *RC); - /// \brief Emit a MachineInstr with one register operand and a result register + /// Emit a MachineInstr with one register operand and a result register /// in the given register class. unsigned fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill); - /// \brief Emit a MachineInstr with two register operands and a result + /// Emit a MachineInstr with two register operands and a result /// register in the given register class. unsigned fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); - /// \brief Emit a MachineInstr with three register operands and a result + /// Emit a MachineInstr with three register operands and a result /// register in the given register class. unsigned fastEmitInst_rrr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill, unsigned Op2, bool Op2IsKill); - /// \brief Emit a MachineInstr with a register operand, an immediate, and a + /// Emit a MachineInstr with a register operand, an immediate, and a /// result register in the given register class. unsigned fastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm); - /// \brief Emit a MachineInstr with one register operand and two immediate + /// Emit a MachineInstr with one register operand and two immediate /// operands. unsigned fastEmitInst_rii(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm1, uint64_t Imm2); - /// \brief Emit a MachineInstr with a floating point immediate, and a result + /// Emit a MachineInstr with a floating point immediate, and a result /// register in the given register class. unsigned fastEmitInst_f(unsigned MachineInstOpcode, const TargetRegisterClass *RC, const ConstantFP *FPImm); - /// \brief Emit a MachineInstr with two register operands, an immediate, and a + /// Emit a MachineInstr with two register operands, an immediate, and a /// result register in the given register class. unsigned fastEmitInst_rri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill, uint64_t Imm); - /// \brief Emit a MachineInstr with a single immediate operand, and a result + /// Emit a MachineInstr with a single immediate operand, and a result /// register in the given register class. unsigned fastEmitInst_i(unsigned MachineInstrOpcode, const TargetRegisterClass *RC, uint64_t Imm); - /// \brief Emit a MachineInstr for an extract_subreg from a specified index of + /// Emit a MachineInstr for an extract_subreg from a specified index of /// a superregister to a specified type. unsigned fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill, uint32_t Idx); - /// \brief Emit MachineInstrs to compute the value of Op with all but the + /// Emit MachineInstrs to compute the value of Op with all but the /// least significant bit set to zero. unsigned fastEmitZExtFromI1(MVT VT, unsigned Op0, bool Op0IsKill); - /// \brief Emit an unconditional branch to the given block, unless it is the + /// Emit an unconditional branch to the given block, unless it is the /// immediate (fall-through) successor, and update the CFG. void fastEmitBranch(MachineBasicBlock *MBB, const DebugLoc &DL); @@ -456,7 +460,7 @@ protected: void finishCondBranch(const BasicBlock *BranchBB, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB); - /// \brief Update the value map to include the new mapping for this + /// Update the value map to include the new mapping for this /// instruction, or insert an extra copy to get the result in a previous /// determined register. /// @@ -467,26 +471,26 @@ protected: unsigned createResultReg(const TargetRegisterClass *RC); - /// \brief Try to constrain Op so that it is usable by argument OpNum of the + /// Try to constrain Op so that it is usable by argument OpNum of the /// provided MCInstrDesc. If this fails, create a new virtual register in the /// correct class and COPY the value there. unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned Op, unsigned OpNum); - /// \brief Emit a constant in a register using target-specific logic, such as + /// Emit a constant in a register using target-specific logic, such as /// constant pool loads. virtual unsigned fastMaterializeConstant(const Constant *C) { return 0; } - /// \brief Emit an alloca address in a register using target-specific logic. + /// Emit an alloca address in a register using target-specific logic. virtual unsigned fastMaterializeAlloca(const AllocaInst *C) { return 0; } - /// \brief Emit the floating-point constant +0.0 in a register using target- + /// Emit the floating-point constant +0.0 in a register using target- /// specific logic. virtual unsigned fastMaterializeFloatZero(const ConstantFP *CF) { return 0; } - /// \brief Check if \c Add is an add that can be safely folded into \c GEP. + /// Check if \c Add is an add that can be safely folded into \c GEP. /// /// \c Add can be folded into \c GEP if: /// - \c Add is an add, @@ -495,10 +499,10 @@ protected: /// - \c Add has a constant operand. bool canFoldAddIntoGEP(const User *GEP, const Value *Add); - /// \brief Test whether the given value has exactly one use. + /// Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V); - /// \brief Create a machine mem operand from the given instruction. + /// Create a machine mem operand from the given instruction. MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const; CmpInst::Predicate optimizeCmpPredicate(const CmpInst *CI) const; @@ -521,7 +525,7 @@ protected: } bool lowerCall(const CallInst *I); - /// \brief Select and emit code for a binary operator instruction, which has + /// Select and emit code for a binary operator instruction, which has /// an opcode which directly corresponds to the given ISD opcode. bool selectBinaryOp(const User *I, unsigned ISDOpcode); bool selectFNeg(const User *I); @@ -535,9 +539,10 @@ protected: bool selectExtractValue(const User *I); bool selectInsertValue(const User *I); bool selectXRayCustomEvent(const CallInst *II); + bool selectXRayTypedEvent(const CallInst *II); private: - /// \brief Handle PHI nodes in successor blocks. + /// Handle PHI nodes in successor blocks. /// /// Emit code to ensure constants are copied into registers when needed. /// Remember the virtual registers that need to be added to the Machine PHI @@ -546,21 +551,21 @@ private: /// correspond to a different MBB than the end. bool handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); - /// \brief Helper for materializeRegForValue to materialize a constant in a + /// Helper for materializeRegForValue to materialize a constant in a /// target-independent way. unsigned materializeConstant(const Value *V, MVT VT); - /// \brief Helper for getRegForVale. This function is called when the value + /// Helper for getRegForVale. This function is called when the value /// isn't already available in a register and must be materialized with new /// instructions. unsigned materializeRegForValue(const Value *V, MVT VT); - /// \brief Clears LocalValueMap and moves the area for the new local variables + /// Clears LocalValueMap and moves the area for the new local variables /// to the beginning of the block. It helps to avoid spilling cached variables /// across heavy instructions like calls. void flushLocalValueMap(); - /// \brief Removes dead local value instructions after SavedLastLocalvalue. + /// Removes dead local value instructions after SavedLastLocalvalue. void removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue); struct InstOrderMap { @@ -568,7 +573,8 @@ private: MachineInstr *FirstTerminator = nullptr; unsigned FirstTerminatorOrder = std::numeric_limits::max(); - void initialize(MachineBasicBlock *MBB); + void initialize(MachineBasicBlock *MBB, + MachineBasicBlock::iterator LastFlushPoint); }; /// Sinks the local value materialization instruction LocalMI to its first use @@ -576,10 +582,10 @@ private: void sinkLocalValueMaterialization(MachineInstr &LocalMI, unsigned DefReg, InstOrderMap &OrderMap); - /// \brief Insertion point before trying to select the current instruction. + /// Insertion point before trying to select the current instruction. MachineBasicBlock::iterator SavedInsertPt; - /// \brief Add a stackmap or patchpoint intrinsic call's live variable + /// Add a stackmap or patchpoint intrinsic call's live variable /// operands to a stackmap or patchpoint machine instruction. bool addStackMapLiveVars(SmallVectorImpl &Ops, const CallInst *CI, unsigned StartIdx); diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h index 16168e785f812b9a73e7724e4266ccfa9a799582..91604fd2df87205557f3eb40233777f40afd89c0 100644 --- a/include/llvm/CodeGen/GCStrategy.h +++ b/include/llvm/CodeGen/GCStrategy.h @@ -105,12 +105,12 @@ public: /// By default, write barriers are replaced with simple store /// instructions. If true, you must provide a custom pass to lower - /// calls to @llvm.gcwrite. + /// calls to \@llvm.gcwrite. bool customWriteBarrier() const { return CustomWriteBarriers; } /// By default, read barriers are replaced with simple load /// instructions. If true, you must provide a custom pass to lower - /// calls to @llvm.gcread. + /// calls to \@llvm.gcread. bool customReadBarrier() const { return CustomReadBarriers; } /// Returns true if this strategy is expecting the use of gc.statepoints, @@ -147,7 +147,7 @@ public: /// By default, roots are left for the code generator so it can generate a /// stack map. If true, you must provide a custom pass to lower - /// calls to @llvm.gcroot. + /// calls to \@llvm.gcroot. bool customRoots() const { return CustomRoots; } /// If set, gcroot intrinsics should initialize their allocas to null diff --git a/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h b/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..8d61f9a68279829f6d07b651639e71abe4186398 --- /dev/null +++ b/include/llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h @@ -0,0 +1,134 @@ +//===-- llvm/CodeGen/GlobalISel/ConstantFoldingMIRBuilder.h --*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements a version of MachineIRBuilder which does trivial +/// constant folding. +//===----------------------------------------------------------------------===// +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/GlobalISel/Utils.h" + +namespace llvm { + +static Optional ConstantFoldBinOp(unsigned Opcode, const unsigned Op1, + const unsigned Op2, + const MachineRegisterInfo &MRI) { + auto MaybeOp1Cst = getConstantVRegVal(Op1, MRI); + auto MaybeOp2Cst = getConstantVRegVal(Op2, MRI); + if (MaybeOp1Cst && MaybeOp2Cst) { + LLT Ty = MRI.getType(Op1); + APInt C1(Ty.getSizeInBits(), *MaybeOp1Cst, true); + APInt C2(Ty.getSizeInBits(), *MaybeOp2Cst, true); + switch (Opcode) { + default: + break; + case TargetOpcode::G_ADD: + return C1 + C2; + case TargetOpcode::G_AND: + return C1 & C2; + case TargetOpcode::G_ASHR: + return C1.ashr(C2); + case TargetOpcode::G_LSHR: + return C1.lshr(C2); + case TargetOpcode::G_MUL: + return C1 * C2; + case TargetOpcode::G_OR: + return C1 | C2; + case TargetOpcode::G_SHL: + return C1 << C2; + case TargetOpcode::G_SUB: + return C1 - C2; + case TargetOpcode::G_XOR: + return C1 ^ C2; + case TargetOpcode::G_UDIV: + if (!C2.getBoolValue()) + break; + return C1.udiv(C2); + case TargetOpcode::G_SDIV: + if (!C2.getBoolValue()) + break; + return C1.sdiv(C2); + case TargetOpcode::G_UREM: + if (!C2.getBoolValue()) + break; + return C1.urem(C2); + case TargetOpcode::G_SREM: + if (!C2.getBoolValue()) + break; + return C1.srem(C2); + } + } + return None; +} + +/// An MIRBuilder which does trivial constant folding of binary ops. +/// Calls to buildInstr will also try to constant fold binary ops. +class ConstantFoldingMIRBuilder + : public FoldableInstructionsBuilder { +public: + // Pull in base class constructors. + using FoldableInstructionsBuilder< + ConstantFoldingMIRBuilder>::FoldableInstructionsBuilder; + // Unhide buildInstr + using FoldableInstructionsBuilder::buildInstr; + + // Implement buildBinaryOp required by FoldableInstructionsBuilder which + // tries to constant fold. + MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Dst, + unsigned Src0, unsigned Src1) { + validateBinaryOp(Dst, Src0, Src1); + auto MaybeCst = ConstantFoldBinOp(Opcode, Src0, Src1, getMF().getRegInfo()); + if (MaybeCst) + return buildConstant(Dst, MaybeCst->getSExtValue()); + return buildInstr(Opcode).addDef(Dst).addUse(Src0).addUse(Src1); + } + + template + MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, UseArg1Ty &&Arg1, + UseArg2Ty &&Arg2) { + unsigned Dst = getDestFromArg(Ty); + return buildInstr(Opc, Dst, getRegFromArg(std::forward(Arg1)), + getRegFromArg(std::forward(Arg2))); + } + + // Try to provide an overload for buildInstr for binary ops in order to + // constant fold. + MachineInstrBuilder buildInstr(unsigned Opc, unsigned Dst, unsigned Src0, + unsigned Src1) { + switch (Opc) { + default: + break; + case TargetOpcode::G_ADD: + case TargetOpcode::G_AND: + case TargetOpcode::G_ASHR: + case TargetOpcode::G_LSHR: + case TargetOpcode::G_MUL: + case TargetOpcode::G_OR: + case TargetOpcode::G_SHL: + case TargetOpcode::G_SUB: + case TargetOpcode::G_XOR: + case TargetOpcode::G_UDIV: + case TargetOpcode::G_SDIV: + case TargetOpcode::G_UREM: + case TargetOpcode::G_SREM: { + return buildBinaryOp(Opc, Dst, Src0, Src1); + } + } + return buildInstr(Opc).addDef(Dst).addUse(Src0).addUse(Src1); + } + + // Fallback implementation of buildInstr. + template + MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, + UseArgsTy &&... Args) { + auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty)); + addUsesFromArgs(MIB, std::forward(Args)...); + return MIB; + } +}; +} // namespace llvm diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 7061c014d9b7f9358a255157d76d732080df0979..65f23b23dd8e2d0fc5d21de635c78ed878abbb1b 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -24,6 +24,7 @@ #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Types.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Support/Allocator.h" #include "llvm/IR/Intrinsics.h" #include #include @@ -63,9 +64,83 @@ private: /// Interface used to lower the everything related to calls. const CallLowering *CLI; - /// Mapping of the values of the current LLVM IR function - /// to the related virtual registers. - ValueToVReg ValToVReg; + /// This class contains the mapping between the Values to vreg related data. + class ValueToVRegInfo { + public: + ValueToVRegInfo() = default; + + using VRegListT = SmallVector; + using OffsetListT = SmallVector; + + using const_vreg_iterator = + DenseMap::const_iterator; + using const_offset_iterator = + DenseMap::const_iterator; + + inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); } + + VRegListT *getVRegs(const Value &V) { + auto It = ValToVRegs.find(&V); + if (It != ValToVRegs.end()) + return It->second; + + return insertVRegs(V); + } + + OffsetListT *getOffsets(const Value &V) { + auto It = TypeToOffsets.find(V.getType()); + if (It != TypeToOffsets.end()) + return It->second; + + return insertOffsets(V); + } + + const_vreg_iterator findVRegs(const Value &V) const { + return ValToVRegs.find(&V); + } + + bool contains(const Value &V) const { + return ValToVRegs.find(&V) != ValToVRegs.end(); + } + + void reset() { + ValToVRegs.clear(); + TypeToOffsets.clear(); + VRegAlloc.DestroyAll(); + OffsetAlloc.DestroyAll(); + } + + private: + VRegListT *insertVRegs(const Value &V) { + assert(ValToVRegs.find(&V) == ValToVRegs.end() && "Value already exists"); + + // We placement new using our fast allocator since we never try to free + // the vectors until translation is finished. + auto *VRegList = new (VRegAlloc.Allocate()) VRegListT(); + ValToVRegs[&V] = VRegList; + return VRegList; + } + + OffsetListT *insertOffsets(const Value &V) { + assert(TypeToOffsets.find(V.getType()) == TypeToOffsets.end() && + "Type already exists"); + + auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT(); + TypeToOffsets[V.getType()] = OffsetList; + return OffsetList; + } + SpecificBumpPtrAllocator VRegAlloc; + SpecificBumpPtrAllocator OffsetAlloc; + + // We store pointers to vectors here since references may be invalidated + // while we hold them if we stored the vectors directly. + DenseMap ValToVRegs; + DenseMap TypeToOffsets; + }; + + /// Mapping of the values of the current LLVM IR function to the related + /// virtual registers and offsets. + ValueToVRegInfo VMap; // N.b. it's not completely obvious that this will be sufficient for every // LLVM IR construct (with "invoke" being the obvious candidate to mess up our @@ -82,7 +157,8 @@ private: // List of stubbed PHI instructions, for values and basic blocks to be filled // in once all MachineBasicBlocks have been created. - SmallVector, 4> PendingPHIs; + SmallVector>, 4> + PendingPHIs; /// Record of what frame index has been allocated to specified allocas for /// this function. @@ -99,7 +175,7 @@ private: /// The general algorithm is: /// 1. Look for a virtual register for each operand or /// create one. - /// 2 Update the ValToVReg accordingly. + /// 2 Update the VMap accordingly. /// 2.alt. For constant arguments, if they are compile time constants, /// produce an immediate in the right operand and do not touch /// ValToReg. Actually we will go with a virtual register for each @@ -146,6 +222,19 @@ private: bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder); + // FIXME: temporary function to expose previous interface to call lowering + // until it is refactored. + /// Combines all component registers of \p V into a single scalar with size + /// "max(Offsets) + last size". + unsigned packRegs(const Value &V, MachineIRBuilder &MIRBuilder); + + void unpackRegs(const Value &V, unsigned Src, MachineIRBuilder &MIRBuilder); + + /// Returns true if the value should be split into multiple LLTs. + /// If \p Offsets is given then the split type's offsets will be stored in it. + bool valueIsSplit(const Value &V, + SmallVectorImpl *Offsets = nullptr); + /// Translate call instruction. /// \pre \p U is a call instruction. bool translateCall(const User &U, MachineIRBuilder &MIRBuilder); @@ -381,9 +470,24 @@ private: // * Clear the different maps. void finalizeFunction(); - /// Get the VReg that represents \p Val. - /// If such VReg does not exist, it is created. - unsigned getOrCreateVReg(const Value &Val); + /// Get the VRegs that represent \p Val. + /// Non-aggregate types have just one corresponding VReg and the list can be + /// used as a single "unsigned". Aggregates get flattened. If such VRegs do + /// not exist, they are created. + ArrayRef getOrCreateVRegs(const Value &Val); + + unsigned getOrCreateVReg(const Value &Val) { + auto Regs = getOrCreateVRegs(Val); + if (Regs.empty()) + return 0; + assert(Regs.size() == 1 && + "attempt to get single VReg for aggregate or void"); + return Regs[0]; + } + + /// Allocate some vregs and offsets in the VMap. Then populate just the + /// offsets while leaving the vregs empty. + ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val); /// Get the frame index that represents \p Val. /// If such VReg does not exist, it is created. diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index eacd13582dc6b8bb16c4090dc424c920d50ee2ca..a44fd1586ebba002813fc8dbdf22cefffc652791 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -20,6 +20,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CodeGenCoverage.h" +#include "llvm/Support/LowLevelTypeImpl.h" #include #include #include @@ -31,7 +32,6 @@ namespace llvm { class APInt; class APFloat; -class LLT; class MachineInstr; class MachineInstrBuilder; class MachineFunction; @@ -81,6 +81,23 @@ enum { /// failed match. GIM_Try, + /// Switch over the opcode on the specified instruction + /// - InsnID - Instruction ID + /// - LowerBound - numerically minimum opcode supported + /// - UpperBound - numerically maximum + 1 opcode supported + /// - Default - failure jump target + /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets + GIM_SwitchOpcode, + + /// Switch over the LLT on the specified instruction operand + /// - InsnID - Instruction ID + /// - OpIdx - Operand index + /// - LowerBound - numerically minimum Type ID supported + /// - UpperBound - numerically maximum + 1 Type ID supported + /// - Default - failure jump target + /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets + GIM_SwitchType, + /// Record the specified instruction /// - NewInsnID - Instruction ID to define /// - InsnID - Instruction ID @@ -117,6 +134,19 @@ enum { GIM_CheckAtomicOrdering, GIM_CheckAtomicOrderingOrStrongerThan, GIM_CheckAtomicOrderingWeakerThan, + /// Check the size of the memory access for the given machine memory operand. + /// - InsnID - Instruction ID + /// - MMOIdx - MMO index + /// - Size - The size in bytes of the memory access + GIM_CheckMemorySizeEqualTo, + /// Check the size of the memory access for the given machine memory operand + /// against the size of an operand. + /// - InsnID - Instruction ID + /// - MMOIdx - MMO index + /// - OpIdx - The operand index to compare the MMO against + GIM_CheckMemorySizeEqualToLLT, + GIM_CheckMemorySizeLessThanLLT, + GIM_CheckMemorySizeGreaterThanLLT, /// Check the type for the specified operand /// - InsnID - Instruction ID @@ -133,12 +163,14 @@ enum { /// - OpIdx - Operand index /// - Expected register bank (specified as a register class) GIM_CheckRegBankForClass, + /// Check the operand matches a complex predicate /// - InsnID - Instruction ID /// - OpIdx - Operand index /// - RendererID - The renderer to hold the result /// - Complex predicate ID GIM_CheckComplexPattern, + /// Check the operand is a specific integer /// - InsnID - Instruction ID /// - OpIdx - Operand index @@ -155,6 +187,7 @@ enum { /// - OpIdx - Operand index /// - Expected Intrinsic ID GIM_CheckIntrinsicID, + /// Check the specified operand is an MBB /// - InsnID - Instruction ID /// - OpIdx - Operand index @@ -183,6 +216,7 @@ enum { /// - OldInsnID - Instruction ID to mutate /// - NewOpcode - The new opcode to use GIR_MutateOpcode, + /// Build a new instruction /// - InsnID - Instruction ID to define /// - Opcode - The new opcode to use @@ -193,6 +227,7 @@ enum { /// - OldInsnID - Instruction ID to copy from /// - OpIdx - The operand to copy GIR_Copy, + /// Copy an operand to the specified instruction or add a zero register if the /// operand is a zero immediate. /// - NewInsnID - Instruction ID to modify @@ -206,6 +241,7 @@ enum { /// - OpIdx - The operand to copy /// - SubRegIdx - The subregister to copy GIR_CopySubReg, + /// Add an implicit register def to the specified instruction /// - InsnID - Instruction ID to modify /// - RegNum - The register to add @@ -218,10 +254,13 @@ enum { /// - InsnID - Instruction ID to modify /// - RegNum - The register to add GIR_AddRegister, + /// Add a temporary register to the specified instruction /// - InsnID - Instruction ID to modify /// - TempRegID - The temporary register ID to add + /// - TempRegFlags - The register flags to set GIR_AddTempRegister, + /// Add an immediate to the specified instruction /// - InsnID - Instruction ID to modify /// - Imm - The immediate to add @@ -230,6 +269,7 @@ enum { /// - InsnID - Instruction ID to modify /// - RendererID - The renderer to call GIR_ComplexRenderer, + /// Render sub-operands of complex operands to the specified instruction /// - InsnID - Instruction ID to modify /// - RendererID - The renderer to call @@ -247,24 +287,34 @@ enum { /// The operand index is implicitly 1. GIR_CopyConstantAsSImm, + /// Render a G_FCONSTANT operator as a sign-extended immediate. + /// - NewInsnID - Instruction ID to modify + /// - OldInsnID - Instruction ID to copy from + /// The operand index is implicitly 1. + GIR_CopyFConstantAsFPImm, + /// Constrain an instruction operand to a register class. /// - InsnID - Instruction ID to modify /// - OpIdx - Operand index /// - RCEnum - Register class enumeration value GIR_ConstrainOperandRC, + /// Constrain an instructions operands according to the instruction /// description. /// - InsnID - Instruction ID to modify GIR_ConstrainSelectedInstOperands, + /// Merge all memory operands into instruction. /// - InsnID - Instruction ID to modify /// - MergeInsnID... - One or more Instruction ID to merge into the result. /// - GIU_MergeMemOperands_EndOfList - Terminates the list of instructions to /// merge. GIR_MergeMemOperands, + /// Erase from parent. /// - InsnID - Instruction ID to erase GIR_EraseFromParent, + /// Create a new temporary register that's not constrained. /// - TempRegID - The temporary register ID to initialize. /// - Expected type @@ -276,6 +326,9 @@ enum { /// Increment the rule coverage counter. /// - RuleID - The ID of the rule that was covered. GIR_Coverage, + + /// Keeping track of the number of the GI opcodes. Must be the last entry. + GIU_NumOpcodes, }; enum { @@ -319,10 +372,24 @@ public: template struct ISelInfoTy { + ISelInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, + const PredicateBitset *FeatureBitsets, + const ComplexMatcherMemFn *ComplexPredicates, + const CustomRendererFn *CustomRenderers) + : TypeObjects(TypeObjects), + FeatureBitsets(FeatureBitsets), + ComplexPredicates(ComplexPredicates), + CustomRenderers(CustomRenderers) { + + for (size_t I = 0; I < NumTypeObjects; ++I) + TypeIDMap[TypeObjects[I]] = I; + } const LLT *TypeObjects; const PredicateBitset *FeatureBitsets; const ComplexMatcherMemFn *ComplexPredicates; const CustomRendererFn *CustomRenderers; + + SmallDenseMap TypeIDMap; }; protected: @@ -341,6 +408,10 @@ protected: const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, CodeGenCoverage &CoverageInfo) const; + virtual const int64_t *getMatchTable() const { + llvm_unreachable("Should have been overridden by tablegen if used"); + } + virtual bool testImmPredicate_I64(unsigned, int64_t) const { llvm_unreachable("Subclasses must override this to use tablegen"); } diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h index f7593ba6ef28d57139e6fdc0814648ff08660cc9..525fb68a0fff6de4d0b7f305c818ae10f92e2038 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -53,8 +53,9 @@ bool InstructionSelector::executeMatchTable( MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, CodeGenCoverage &CoverageInfo) const { + uint64_t CurrentIdx = 0; - SmallVector OnFailResumeAt; + SmallVector OnFailResumeAt; enum RejectAction { RejectAndGiveUp, RejectAndResume }; auto handleReject = [&]() -> RejectAction { @@ -62,8 +63,7 @@ bool InstructionSelector::executeMatchTable( dbgs() << CurrentIdx << ": Rejected\n"); if (OnFailResumeAt.empty()) return RejectAndGiveUp; - CurrentIdx = OnFailResumeAt.back(); - OnFailResumeAt.pop_back(); + CurrentIdx = OnFailResumeAt.pop_back_val(); DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " (" << OnFailResumeAt.size() << " try-blocks remain)\n"); @@ -72,7 +72,8 @@ bool InstructionSelector::executeMatchTable( while (true) { assert(CurrentIdx != ~0u && "Invalid MatchTable index"); - switch (MatchTable[CurrentIdx++]) { + int64_t MatcherOpcode = MatchTable[CurrentIdx++]; + switch (MatcherOpcode) { case GIM_Try: { DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << CurrentIdx << ": Begin try-block\n"); @@ -138,12 +139,13 @@ bool InstructionSelector::executeMatchTable( int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Expected = MatchTable[CurrentIdx++]; + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); unsigned Opcode = State.MIs[InsnID]->getOpcode(); + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID << "], ExpectedOpcode=" << Expected << ") // Got=" << Opcode << "\n"); - assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); if (Opcode != Expected) { if (handleReject() == RejectAndGiveUp) return false; @@ -151,6 +153,77 @@ bool InstructionSelector::executeMatchTable( break; } + case GIM_SwitchOpcode: { + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t LowerBound = MatchTable[CurrentIdx++]; + int64_t UpperBound = MatchTable[CurrentIdx++]; + int64_t Default = MatchTable[CurrentIdx++]; + + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + const int64_t Opcode = State.MIs[InsnID]->getOpcode(); + + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { + dbgs() << CurrentIdx << ": GIM_SwitchOpcode(MIs[" << InsnID << "], [" + << LowerBound << ", " << UpperBound << "), Default=" << Default + << ", JumpTable...) // Got=" << Opcode << "\n"; + }); + if (Opcode < LowerBound || UpperBound <= Opcode) { + CurrentIdx = Default; + break; + } + CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)]; + if (!CurrentIdx) { + CurrentIdx = Default; + break; + } + OnFailResumeAt.push_back(Default); + break; + } + + case GIM_SwitchType: { + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t OpIdx = MatchTable[CurrentIdx++]; + int64_t LowerBound = MatchTable[CurrentIdx++]; + int64_t UpperBound = MatchTable[CurrentIdx++]; + int64_t Default = MatchTable[CurrentIdx++]; + + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); + + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), { + dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID + << "]->getOperand(" << OpIdx << "), [" << LowerBound << ", " + << UpperBound << "), Default=" << Default + << ", JumpTable...) // Got="; + if (!MO.isReg()) + dbgs() << "Not a VReg\n"; + else + dbgs() << MRI.getType(MO.getReg()) << "\n"; + }); + if (!MO.isReg()) { + CurrentIdx = Default; + break; + } + const LLT Ty = MRI.getType(MO.getReg()); + const auto TyI = ISelInfo.TypeIDMap.find(Ty); + if (TyI == ISelInfo.TypeIDMap.end()) { + CurrentIdx = Default; + break; + } + const int64_t TypeID = TyI->second; + if (TypeID < LowerBound || UpperBound <= TypeID) { + CurrentIdx = Default; + break; + } + CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)]; + if (!CurrentIdx) { + CurrentIdx = Default; + break; + } + OnFailResumeAt.push_back(Default); + break; + } + case GIM_CheckNumOperands: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t Expected = MatchTable[CurrentIdx++]; @@ -196,7 +269,8 @@ bool InstructionSelector::executeMatchTable( << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs[" << InsnID << "], Predicate=" << Predicate << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - assert(State.MIs[InsnID]->getOpcode() && "Expected G_CONSTANT"); + assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && + "Expected G_CONSTANT"); assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate"); APInt Value; if (State.MIs[InsnID]->getOperand(1).isCImm()) @@ -235,7 +309,6 @@ bool InstructionSelector::executeMatchTable( dbgs() << CurrentIdx << ": GIM_CheckAtomicOrdering(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - if (!State.MIs[InsnID]->hasOneMemOperand()) if (handleReject() == RejectAndGiveUp) return false; @@ -254,7 +327,6 @@ bool InstructionSelector::executeMatchTable( << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - if (!State.MIs[InsnID]->hasOneMemOperand()) if (handleReject() == RejectAndGiveUp) return false; @@ -273,7 +345,6 @@ bool InstructionSelector::executeMatchTable( << ": GIM_CheckAtomicOrderingWeakerThan(MIs[" << InsnID << "], " << (uint64_t)Ordering << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - if (!State.MIs[InsnID]->hasOneMemOperand()) if (handleReject() == RejectAndGiveUp) return false; @@ -284,6 +355,87 @@ bool InstructionSelector::executeMatchTable( return false; break; } + case GIM_CheckMemorySizeEqualTo: { + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t MMOIdx = MatchTable[CurrentIdx++]; + uint64_t Size = MatchTable[CurrentIdx++]; + + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << CurrentIdx + << ": GIM_CheckMemorySizeEqual(MIs[" << InsnID + << "]->memoperands() + " << MMOIdx + << ", Size=" << Size << ")\n"); + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + + if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { + if (handleReject() == RejectAndGiveUp) + return false; + break; + } + + MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << MMO->getSize() << " bytes vs " << Size + << " bytes\n"); + if (MMO->getSize() != Size) + if (handleReject() == RejectAndGiveUp) + return false; + + break; + } + case GIM_CheckMemorySizeEqualToLLT: + case GIM_CheckMemorySizeLessThanLLT: + case GIM_CheckMemorySizeGreaterThanLLT: { + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t MMOIdx = MatchTable[CurrentIdx++]; + int64_t OpIdx = MatchTable[CurrentIdx++]; + + DEBUG_WITH_TYPE( + TgtInstructionSelector::getName(), + dbgs() << CurrentIdx << ": GIM_CheckMemorySize" + << (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT + ? "EqualTo" + : MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT + ? "GreaterThan" + : "LessThan") + << "LLT(MIs[" << InsnID << "]->memoperands() + " << MMOIdx + << ", OpIdx=" << OpIdx << ")\n"); + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + + MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); + if (!MO.isReg()) { + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << CurrentIdx << ": Not a register\n"); + if (handleReject() == RejectAndGiveUp) + return false; + break; + } + + if (State.MIs[InsnID]->getNumMemOperands() <= MMOIdx) { + if (handleReject() == RejectAndGiveUp) + return false; + break; + } + + MachineMemOperand *MMO = *(State.MIs[InsnID]->memoperands_begin() + MMOIdx); + + unsigned Size = MRI.getType(MO.getReg()).getSizeInBits(); + if (MatcherOpcode == GIM_CheckMemorySizeEqualToLLT && + MMO->getSize() * 8 != Size) { + if (handleReject() == RejectAndGiveUp) + return false; + } else if (MatcherOpcode == GIM_CheckMemorySizeLessThanLLT && + MMO->getSize() * 8 >= Size) { + if (handleReject() == RejectAndGiveUp) + return false; + } else if (MatcherOpcode == GIM_CheckMemorySizeGreaterThanLLT && + MMO->getSize() * 8 <= Size) + if (handleReject() == RejectAndGiveUp) + return false; + + break; + } case GIM_CheckType: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; @@ -293,7 +445,6 @@ bool InstructionSelector::executeMatchTable( << "]->getOperand(" << OpIdx << "), TypeID=" << TypeID << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (!MO.isReg() || MRI.getType(MO.getReg()) != ISelInfo.TypeObjects[TypeID]) { @@ -312,7 +463,6 @@ bool InstructionSelector::executeMatchTable( << InsnID << "]->getOperand(" << OpIdx << "), SizeInBits=" << SizeInBits << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - // iPTR must be looked up in the target. if (SizeInBits == 0) { MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent(); @@ -384,7 +534,6 @@ bool InstructionSelector::executeMatchTable( << InsnID << "]->getOperand(" << OpIdx << "), Value=" << Value << ")\n"); assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); if (MO.isReg()) { // isOperandImmEqual() will sign-extend to 64-bits, so should we. @@ -480,7 +629,7 @@ bool InstructionSelector::executeMatchTable( } case GIM_Reject: DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIM_Reject"); + dbgs() << CurrentIdx << ": GIM_Reject\n"); if (handleReject() == RejectAndGiveUp) return false; break; @@ -662,6 +811,23 @@ bool InstructionSelector::executeMatchTable( break; } + // TODO: Needs a test case once we have a pattern that uses this. + case GIR_CopyFConstantAsFPImm: { + int64_t NewInsnID = MatchTable[CurrentIdx++]; + int64_t OldInsnID = MatchTable[CurrentIdx++]; + assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction"); + assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_FCONSTANT && "Expected G_FCONSTANT"); + if (State.MIs[OldInsnID]->getOperand(1).isFPImm()) + OutMIs[NewInsnID].addFPImm( + State.MIs[OldInsnID]->getOperand(1).getFPImm()); + else + llvm_unreachable("Expected FPImm operand"); + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << CurrentIdx << ": GIR_CopyFPConstantAsFPImm(OutMIs[" + << NewInsnID << "], MIs[" << OldInsnID << "])\n"); + break; + } + case GIR_CustomRenderer: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OldInsnID = MatchTable[CurrentIdx++]; @@ -755,7 +921,7 @@ bool InstructionSelector::executeMatchTable( case GIR_Done: DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), - dbgs() << CurrentIdx << ": GIR_Done"); + dbgs() << CurrentIdx << ": GIR_Done\n"); return true; default: diff --git a/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h index a1f564bf3dbcfcfa6f5419c13aa5561d040325a7..873587651efda04580dc633c446a6fec78edb7a9 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -38,7 +38,7 @@ public: return false; if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_TRUNC, MI.getOperand(1).getReg(), MRI)) { - DEBUG(dbgs() << ".. Combine MI: " << MI;); + LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); unsigned DstReg = MI.getOperand(0).getReg(); unsigned SrcReg = DefMI->getOperand(1).getReg(); Builder.setInstr(MI); @@ -62,7 +62,7 @@ public: if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) || isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}})) return false; - DEBUG(dbgs() << ".. Combine MI: " << MI;); + LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); Builder.setInstr(MI); unsigned ZExtSrc = MI.getOperand(1).getReg(); LLT ZExtSrcTy = MRI.getType(ZExtSrc); @@ -91,7 +91,7 @@ public: isInstUnsupported({TargetOpcode::G_ASHR, {DstTy}}) || isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}})) return false; - DEBUG(dbgs() << ".. Combine MI: " << MI;); + LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); Builder.setInstr(MI); unsigned SExtSrc = MI.getOperand(1).getReg(); LLT SExtSrcTy = MRI.getType(SExtSrc); @@ -123,7 +123,7 @@ public: LLT DstTy = MRI.getType(DstReg); if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) return false; - DEBUG(dbgs() << ".. Combine EXT(IMPLICIT_DEF) " << MI;); + LLVM_DEBUG(dbgs() << ".. Combine EXT(IMPLICIT_DEF) " << MI;); Builder.setInstr(MI); Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, DstReg); markInstAndDefDead(MI, *DefMI, DeadInsts); @@ -139,9 +139,9 @@ public: return false; unsigned NumDefs = MI.getNumOperands() - 1; - unsigned SrcReg = MI.getOperand(NumDefs).getReg(); - MachineInstr *MergeI = MRI.getVRegDef(SrcReg); - if (!MergeI || (MergeI->getOpcode() != TargetOpcode::G_MERGE_VALUES)) + MachineInstr *MergeI = getOpcodeDef(TargetOpcode::G_MERGE_VALUES, + MI.getOperand(NumDefs).getReg(), MRI); + if (!MergeI) return false; const unsigned NumMergeRegs = MergeI->getNumOperands() - 1; @@ -253,11 +253,8 @@ private: // and as a result, %3, %2, %1 are dead. MachineInstr *PrevMI = &MI; while (PrevMI != &DefMI) { - // If we're dealing with G_UNMERGE_VALUES, tryCombineMerges doesn't really try - // to fold copies in between and we can ignore them here. - if (PrevMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) - break; - unsigned PrevRegSrc = PrevMI->getOperand(1).getReg(); + unsigned PrevRegSrc = + PrevMI->getOperand(PrevMI->getNumOperands() - 1).getReg(); MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc); if (MRI.hasOneUse(PrevRegSrc)) { if (TmpDef != &DefMI) { @@ -269,9 +266,7 @@ private: break; PrevMI = TmpDef; } - if ((PrevMI == &DefMI || - DefMI.getOpcode() == TargetOpcode::G_MERGE_VALUES) && - MRI.hasOneUse(DefMI.getOperand(0).getReg())) + if (PrevMI == &DefMI && MRI.hasOneUse(DefMI.getOperand(0).getReg())) DeadInsts.push_back(&DefMI); } diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 8bd8a9dcd0e24faebedd8d21b2becfc78ba7471b..b78fa20e75e7f4e2b67bbd47873bb680c1139f10 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -93,6 +93,18 @@ public: const LegalizerInfo &getLegalizerInfo() const { return LI; } private: + /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a + /// Use by extending the operand's type to \p WideTy using the specified \p + /// ExtOpcode for the extension instruction, and replacing the vreg of the + /// operand in place. + void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx, + unsigned ExtOpcode); + + /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a + /// Def by extending the operand's type to \p WideTy and truncating it back + /// with the \p TruncOpcode, and replacing the vreg of the operand in place. + void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0, + unsigned TruncOpcode = TargetOpcode::G_TRUNC); /// Helper function to split a wide generic register into bitwise blocks with /// the given Type (which implies the number of blocks needed). The generic diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index 117c791d299f4a5829ce2f97b6e650a024483903..547176289a21ca2b95cef31e3bd2186adea3d1ee 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -19,6 +19,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/TargetOpcodes.h" @@ -37,6 +38,7 @@ extern cl::opt DisableGISelLegalityCheck; class MachineInstr; class MachineIRBuilder; class MachineRegisterInfo; +class MCInstrInfo; namespace LegalizeActions { enum LegalizeAction : std::uint8_t { @@ -118,6 +120,20 @@ struct LegalityQuery { unsigned Opcode; ArrayRef Types; + struct MemDesc { + uint64_t Size; + }; + + /// Operations which require memory can use this to place requirements on the + /// memory type for each MMO. + ArrayRef MMODescrs; + + constexpr LegalityQuery(unsigned Opcode, const ArrayRef Types, + const ArrayRef MMODescrs) + : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {} + constexpr LegalityQuery(unsigned Opcode, const ArrayRef Types) + : LegalityQuery(Opcode, Types, {}) {} + raw_ostream &print(raw_ostream &OS) const; }; @@ -147,6 +163,17 @@ using LegalizeMutation = std::function(const LegalityQuery &)>; namespace LegalityPredicates { +struct TypePairAndMemSize { + LLT Type0; + LLT Type1; + uint64_t MemSize; + + bool operator==(const TypePairAndMemSize &Other) const { + return Type0 == Other.Type0 && Type1 == Other.Type1 && + MemSize == Other.MemSize; + } +}; + /// True iff P0 and P1 are true. LegalityPredicate all(LegalityPredicate P0, LegalityPredicate P1); /// True iff the given type index is one of the specified types. @@ -157,6 +184,11 @@ LegalityPredicate typeInSet(unsigned TypeIdx, LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list> TypesInit); +/// True iff the given types for the given pair of type indexes is one of the +/// specified type pairs. +LegalityPredicate typePairAndMemSizeInSet( + unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, + std::initializer_list TypesAndMemSizeInit); /// True iff the specified type index is a scalar. LegalityPredicate isScalar(unsigned TypeIdx); /// True iff the specified type index is a scalar that's narrower than the given @@ -168,6 +200,8 @@ LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar whose size is not a power of /// 2. LegalityPredicate sizeNotPow2(unsigned TypeIdx); +/// True iff the specified MMO index has a size that is not a power of 2 +LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx); /// True iff the specified type index is a vector whose element count is not a /// power of 2. LegalityPredicate numElementsNotPow2(unsigned TypeIdx); @@ -176,6 +210,8 @@ LegalityPredicate numElementsNotPow2(unsigned TypeIdx); namespace LegalizeMutations { /// Select this specific type for the given type index. LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty); +/// Keep the same type as the given type index. +LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx); /// Widen the type for the given type index to the next power of 2. LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0); /// Add more elements to the type for the given type index to the next power of @@ -219,6 +255,33 @@ class LegalizeRuleSet { bool IsAliasedByAnother; SmallVector Rules; +#ifndef NDEBUG + /// If bit I is set, this rule set contains a rule that may handle (predicate + /// or perform an action upon (or both)) the type index I. The uncertainty + /// comes from free-form rules executing user-provided lambda functions. We + /// conservatively assume such rules do the right thing and cover all type + /// indices. The bitset is intentionally 1 bit wider than it absolutely needs + /// to be to distinguish such cases from the cases where all type indices are + /// individually handled. + SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC - + MCOI::OPERAND_FIRST_GENERIC + 2}; +#endif + + unsigned typeIdx(unsigned TypeIdx) { + assert(TypeIdx <= + (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) && + "Type Index is out of bounds"); +#ifndef NDEBUG + TypeIdxsCovered.set(TypeIdx); +#endif + return TypeIdx; + } + void markAllTypeIdxsAsCovered() { +#ifndef NDEBUG + TypeIdxsCovered.set(); +#endif + } + void add(const LegalizeRule &Rule) { assert(AliasOf == 0 && "RuleSet is aliased, change the representative opcode instead"); @@ -235,7 +298,7 @@ class LegalizeRuleSet { return *this; } /// Use the given action when the predicate is true. - /// Action should not be an action that requires mutation. + /// Action should be an action that requires mutation. LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate, LegalizeMutation Mutation) { add({Predicate, Action, Mutation}); @@ -246,16 +309,33 @@ class LegalizeRuleSet { LegalizeRuleSet &actionFor(LegalizeAction Action, std::initializer_list Types) { using namespace LegalityPredicates; - return actionIf(Action, typeInSet(0, Types)); + return actionIf(Action, typeInSet(typeIdx(0), Types)); + } + /// Use the given action when type index 0 is any type in the given list. + /// Action should be an action that requires mutation. + LegalizeRuleSet &actionFor(LegalizeAction Action, + std::initializer_list Types, + LegalizeMutation Mutation) { + using namespace LegalityPredicates; + return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation); } /// Use the given action when type indexes 0 and 1 is any type pair in the /// given list. /// Action should not be an action that requires mutation. - LegalizeRuleSet & - actionFor(LegalizeAction Action, - std::initializer_list> Types) { + LegalizeRuleSet &actionFor(LegalizeAction Action, + std::initializer_list> Types) { + using namespace LegalityPredicates; + return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types)); + } + /// Use the given action when type indexes 0 and 1 is any type pair in the + /// given list. + /// Action should be an action that requires mutation. + LegalizeRuleSet &actionFor(LegalizeAction Action, + std::initializer_list> Types, + LegalizeMutation Mutation) { using namespace LegalityPredicates; - return actionIf(Action, typePairInSet(0, 1, Types)); + return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types), + Mutation); } /// Use the given action when type indexes 0 and 1 are both in the given list. /// That is, the type pair is in the cartesian product of the list. @@ -263,10 +343,11 @@ class LegalizeRuleSet { LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action, std::initializer_list Types) { using namespace LegalityPredicates; - return actionIf(Action, all(typeInSet(0, Types), typeInSet(1, Types))); + return actionIf(Action, all(typeInSet(typeIdx(0), Types), + typeInSet(typeIdx(1), Types))); } - /// Use the given action when type indexes 0 and 1 are both their respective - /// lists. + /// Use the given action when type indexes 0 and 1 are both in their + /// respective lists. /// That is, the type pair is in the cartesian product of the lists /// Action should not be an action that requires mutation. LegalizeRuleSet & @@ -274,7 +355,20 @@ class LegalizeRuleSet { std::initializer_list Types0, std::initializer_list Types1) { using namespace LegalityPredicates; - return actionIf(Action, all(typeInSet(0, Types0), typeInSet(1, Types1))); + return actionIf(Action, all(typeInSet(typeIdx(0), Types0), + typeInSet(typeIdx(1), Types1))); + } + /// Use the given action when type indexes 0, 1, and 2 are all in their + /// respective lists. + /// That is, the type triple is in the cartesian product of the lists + /// Action should not be an action that requires mutation. + LegalizeRuleSet &actionForCartesianProduct( + LegalizeAction Action, std::initializer_list Types0, + std::initializer_list Types1, std::initializer_list Types2) { + using namespace LegalityPredicates; + return actionIf(Action, all(typeInSet(typeIdx(0), Types0), + all(typeInSet(typeIdx(1), Types1), + typeInSet(typeIdx(2), Types2)))); } public: @@ -292,6 +386,9 @@ public: /// The instruction is legal if predicate is true. LegalizeRuleSet &legalIf(LegalityPredicate Predicate) { + // We have no choice but conservatively assume that the free-form + // user-provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::Legal, Predicate); } /// The instruction is legal when type index 0 is any type in the given list. @@ -303,6 +400,15 @@ public: LegalizeRuleSet &legalFor(std::initializer_list> Types) { return actionFor(LegalizeAction::Legal, Types); } + /// The instruction is legal when type indexes 0 and 1 along with the memory + /// size is any type and size tuple in the given list. + LegalizeRuleSet &legalForTypesWithMemSize( + std::initializer_list + TypesAndMemSize) { + return actionIf(LegalizeAction::Legal, + LegalityPredicates::typePairAndMemSizeInSet( + typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemSize)); + } /// The instruction is legal when type indexes 0 and 1 are both in the given /// list. That is, the type pair is in the cartesian product of the list. LegalizeRuleSet &legalForCartesianProduct(std::initializer_list Types) { @@ -315,8 +421,77 @@ public: return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1); } + /// The instruction is lowered. + LegalizeRuleSet &lower() { + using namespace LegalizeMutations; + // We have no choice but conservatively assume that predicate-less lowering + // properly handles all type indices by design: + markAllTypeIdxsAsCovered(); + return actionIf(LegalizeAction::Lower, always); + } + /// The instruction is lowered if predicate is true. Keep type index 0 as the + /// same type. + LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) { + using namespace LegalizeMutations; + // We have no choice but conservatively assume that lowering with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); + return actionIf(LegalizeAction::Lower, Predicate); + } + /// The instruction is lowered if predicate is true. + LegalizeRuleSet &lowerIf(LegalityPredicate Predicate, + LegalizeMutation Mutation) { + // We have no choice but conservatively assume that lowering with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); + return actionIf(LegalizeAction::Lower, Predicate, Mutation); + } + /// The instruction is lowered when type index 0 is any type in the given + /// list. Keep type index 0 as the same type. + LegalizeRuleSet &lowerFor(std::initializer_list Types) { + return actionFor(LegalizeAction::Lower, Types, + LegalizeMutations::changeTo(0, 0)); + } + /// The instruction is lowered when type index 0 is any type in the given + /// list. + LegalizeRuleSet &lowerFor(std::initializer_list Types, + LegalizeMutation Mutation) { + return actionFor(LegalizeAction::Lower, Types, Mutation); + } + /// The instruction is lowered when type indexes 0 and 1 is any type pair in + /// the given list. Keep type index 0 as the same type. + LegalizeRuleSet &lowerFor(std::initializer_list> Types) { + return actionFor(LegalizeAction::Lower, Types, + LegalizeMutations::changeTo(0, 0)); + } + /// The instruction is lowered when type indexes 0 and 1 is any type pair in + /// the given list. + LegalizeRuleSet &lowerFor(std::initializer_list> Types, + LegalizeMutation Mutation) { + return actionFor(LegalizeAction::Lower, Types, Mutation); + } + /// The instruction is lowered when type indexes 0 and 1 are both in their + /// respective lists. + LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list Types0, + std::initializer_list Types1) { + using namespace LegalityPredicates; + return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1); + } + /// The instruction is lowered when when type indexes 0, 1, and 2 are all in + /// their respective lists. + LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list Types0, + std::initializer_list Types1, + std::initializer_list Types2) { + using namespace LegalityPredicates; + return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1, + Types2); + } + /// Like legalIf, but for the Libcall action. LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) { + // We have no choice but conservatively assume that a libcall with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::Libcall, Predicate); } LegalizeRuleSet &libcallFor(std::initializer_list Types) { @@ -340,12 +515,18 @@ public: /// true. LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation) { + // We have no choice but conservatively assume that an action with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation); } /// Narrow the scalar to the one selected by the mutation if the predicate is /// true. LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation) { + // We have no choice but conservatively assume that an action with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation); } @@ -353,12 +534,18 @@ public: /// predicate is true. LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation) { + // We have no choice but conservatively assume that an action with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::MoreElements, Predicate, Mutation); } /// Remove elements to reach the type selected by the mutation if the /// predicate is true. LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation) { + // We have no choice but conservatively assume that an action with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::FewerElements, Predicate, Mutation); } @@ -369,8 +556,15 @@ public: LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) { return actionIf(LegalizeAction::Unsupported, Predicate); } + LegalizeRuleSet &unsupportedIfMemSizeNotPow2() { + return actionIf(LegalizeAction::Unsupported, + LegalityPredicates::memSizeInBytesNotPow2(0)); + } LegalizeRuleSet &customIf(LegalityPredicate Predicate) { + // We have no choice but conservatively assume that a custom action with a + // free-form user provided Predicate properly handles all type indices: + markAllTypeIdxsAsCovered(); return actionIf(LegalizeAction::Custom, Predicate); } LegalizeRuleSet &customFor(std::initializer_list Types) { @@ -387,54 +581,57 @@ public: /// Widen the scalar to the next power of two that is at least MinSize. /// No effect if the type is not a scalar or is a power of two. - LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize = 0) { + LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx, + unsigned MinSize = 0) { using namespace LegalityPredicates; - return widenScalarIf( - sizeNotPow2(TypeIdx), - LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize)); + return actionIf(LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)), + LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize)); } LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) { using namespace LegalityPredicates; - return narrowScalarIf(isScalar(TypeIdx), Mutation); + return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)), + Mutation); } /// Ensure the scalar is at least as wide as Ty. LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) { using namespace LegalityPredicates; using namespace LegalizeMutations; - return widenScalarIf(narrowerThan(TypeIdx, Ty.getSizeInBits()), - changeTo(TypeIdx, Ty)); + return actionIf(LegalizeAction::WidenScalar, + narrowerThan(TypeIdx, Ty.getSizeInBits()), + changeTo(typeIdx(TypeIdx), Ty)); } /// Ensure the scalar is at most as wide as Ty. LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) { using namespace LegalityPredicates; using namespace LegalizeMutations; - return narrowScalarIf(widerThan(TypeIdx, Ty.getSizeInBits()), - changeTo(TypeIdx, Ty)); + return actionIf(LegalizeAction::NarrowScalar, + widerThan(TypeIdx, Ty.getSizeInBits()), + changeTo(typeIdx(TypeIdx), Ty)); } /// Conditionally limit the maximum size of the scalar. /// For example, when the maximum size of one type depends on the size of /// another such as extracting N bits from an M bit container. - LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT &Ty) { + LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, + const LLT &Ty) { using namespace LegalityPredicates; using namespace LegalizeMutations; - return narrowScalarIf( - [=](const LegalityQuery &Query) { - return widerThan(TypeIdx, Ty.getSizeInBits()) && - Predicate(Query); - }, - changeTo(TypeIdx, Ty)); + return actionIf(LegalizeAction::NarrowScalar, + [=](const LegalityQuery &Query) { + return widerThan(TypeIdx, Ty.getSizeInBits()) && + Predicate(Query); + }, + changeTo(typeIdx(TypeIdx), Ty)); } /// Limit the range of scalar sizes to MinTy and MaxTy. - LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy) { + LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy, + const LLT &MaxTy) { assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types"); - - return minScalar(TypeIdx, MinTy) - .maxScalar(TypeIdx, MaxTy); + return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy); } /// Add more elements to the vector to reach the next power of two. @@ -442,17 +639,21 @@ public: /// two. LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) { using namespace LegalityPredicates; - return moreElementsIf(numElementsNotPow2(TypeIdx), - LegalizeMutations::moreElementsToNextPow2(TypeIdx)); + return actionIf(LegalizeAction::MoreElements, + numElementsNotPow2(typeIdx(TypeIdx)), + LegalizeMutations::moreElementsToNextPow2(TypeIdx)); } /// Limit the number of elements in EltTy vectors to at least MinElements. LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy, unsigned MinElements) { - return moreElementsIf( + // Mark the type index as covered: + typeIdx(TypeIdx); + return actionIf( + LegalizeAction::MoreElements, [=](const LegalityQuery &Query) { LLT VecTy = Query.Types[TypeIdx]; - return VecTy.getElementType() == EltTy && + return VecTy.isVector() && VecTy.getElementType() == EltTy && VecTy.getNumElements() < MinElements; }, [=](const LegalityQuery &Query) { @@ -464,10 +665,13 @@ public: /// Limit the number of elements in EltTy vectors to at most MaxElements. LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy, unsigned MaxElements) { - return fewerElementsIf( + // Mark the type index as covered: + typeIdx(TypeIdx); + return actionIf( + LegalizeAction::FewerElements, [=](const LegalityQuery &Query) { LLT VecTy = Query.Types[TypeIdx]; - return VecTy.getElementType() == EltTy && + return VecTy.isVector() && VecTy.getElementType() == EltTy && VecTy.getNumElements() > MaxElements; }, [=](const LegalityQuery &Query) { @@ -499,6 +703,11 @@ public: return *this; } + /// Check if there is no type index which is obviously not handled by the + /// LegalizeRuleSet in any way at all. + /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set. + bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const; + /// Apply the ruleset to the given LegalityQuery. LegalizeActionStep apply(const LegalityQuery &Query) const; }; @@ -516,6 +725,10 @@ public: /// before any query is made or incorrect results may be returned. void computeTables(); + /// Perform simple self-diagnostic and assert if there is anything obviously + /// wrong with the actions set up. + void verify(const MCInstrInfo &MII) const; + static bool needsLegalizingToDifferentSize(const LegalizeAction Action) { using namespace LegalizeActions; switch (Action) { diff --git a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index 797f5e542fb6cd78d400696f60b66400fefaaef7..f77f9a8df7ee4bd6641955d605607ae161a3d1af 100644 --- a/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -221,6 +221,12 @@ m_GFMul(const LHS &L, const RHS &R) { return BinaryOp_match(L, R); } +template +inline BinaryOp_match +m_GFSub(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); +} + template inline BinaryOp_match m_GAnd(const LHS &L, const RHS &R) { @@ -304,6 +310,11 @@ inline UnaryOp_match m_GFabs(const SrcTy &Src) { return UnaryOp_match(Src); } +template +inline UnaryOp_match m_GFNeg(const SrcTy &Src) { + return UnaryOp_match(Src); +} + template inline UnaryOp_match m_Copy(SrcTy &&Src) { return UnaryOp_match(std::forward(Src)); diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index ef4e0ad86d2d41023fce538eab8017da2a5faf37..98695e85037d40c816388da546a51e1b06a53f41 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -31,11 +31,10 @@ class MachineFunction; class MachineInstr; class TargetInstrInfo; -/// Helper class to build MachineInstr. -/// It keeps internally the insertion point and debug location for all -/// the new instructions we want to create. -/// This information can be modify via the related setters. -class MachineIRBuilder { +/// Class which stores all the state required in a MachineIRBuilder. +/// Since MachineIRBuilders will only store state in this object, it allows +/// to transfer BuilderState between different kinds of MachineIRBuilders. +struct MachineIRBuilderState { /// MachineFunction under construction. MachineFunction *MF; /// Information used to access the description of the opcodes. @@ -52,15 +51,23 @@ class MachineIRBuilder { /// @} std::function InsertedInstr; +}; +/// Helper class to build MachineInstr. +/// It keeps internally the insertion point and debug location for all +/// the new instructions we want to create. +/// This information can be modify via the related setters. +class MachineIRBuilderBase { + + MachineIRBuilderState State; const TargetInstrInfo &getTII() { - assert(TII && "TargetInstrInfo is not set"); - return *TII; + assert(State.TII && "TargetInstrInfo is not set"); + return *State.TII; } void validateTruncExt(unsigned Dst, unsigned Src, bool IsExtend); - MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Res, unsigned Op0, unsigned Op1); +protected: unsigned getDestFromArg(unsigned Reg) { return Reg; } unsigned getDestFromArg(LLT Ty) { return getMF().getRegInfo().createGenericVirtualRegister(Ty); @@ -88,30 +95,41 @@ class MachineIRBuilder { return MIB->getOperand(0).getReg(); } + void validateBinaryOp(unsigned Dst, unsigned Src0, unsigned Src1); + public: /// Some constructors for easy use. - MachineIRBuilder() = default; - MachineIRBuilder(MachineFunction &MF) { setMF(MF); } - MachineIRBuilder(MachineInstr &MI) : MachineIRBuilder(*MI.getMF()) { + MachineIRBuilderBase() = default; + MachineIRBuilderBase(MachineFunction &MF) { setMF(MF); } + MachineIRBuilderBase(MachineInstr &MI) : MachineIRBuilderBase(*MI.getMF()) { setInstr(MI); } + MachineIRBuilderBase(const MachineIRBuilderState &BState) : State(BState) {} + /// Getter for the function we currently build. MachineFunction &getMF() { - assert(MF && "MachineFunction is not set"); - return *MF; + assert(State.MF && "MachineFunction is not set"); + return *State.MF; } + /// Getter for DebugLoc + const DebugLoc &getDL() { return State.DL; } + + /// Getter for MRI + MachineRegisterInfo *getMRI() { return State.MRI; } + + /// Getter for the State + MachineIRBuilderState &getState() { return State; } + /// Getter for the basic block we currently build. MachineBasicBlock &getMBB() { - assert(MBB && "MachineBasicBlock is not set"); - return *MBB; + assert(State.MBB && "MachineBasicBlock is not set"); + return *State.MBB; } /// Current insertion point for new instructions. - MachineBasicBlock::iterator getInsertPt() { - return II; - } + MachineBasicBlock::iterator getInsertPt() { return State.II; } /// Set the insertion point before the specified position. /// \pre MBB must be in getMF(). @@ -136,15 +154,16 @@ public: /// \name Control where instructions we create are recorded (typically for /// visiting again later during legalization). /// @{ + void recordInsertion(MachineInstr *InsertedInstr) const; void recordInsertions(std::function InsertedInstr); void stopRecordingInsertions(); /// @} /// Set the debug location to \p DL for all the next build instructions. - void setDebugLoc(const DebugLoc &DL) { this->DL = DL; } + void setDebugLoc(const DebugLoc &DL) { this->State.DL = DL; } /// Get the current instruction's debug location. - DebugLoc getDebugLoc() { return DL; } + DebugLoc getDebugLoc() { return State.DL; } /// Build and insert = \p Opcode . /// The insertion point is the one set by the last call of either @@ -155,20 +174,6 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildInstr(unsigned Opcode); - /// DAG like Generic method for building arbitrary instructions as above. - /// \Opc opcode for the instruction. - /// \Ty Either LLT/TargetRegisterClass/unsigned types for Dst - /// \Args Variadic list of uses of types(unsigned/MachineInstrBuilder) - /// Uses of type MachineInstrBuilder will perform - /// getOperand(0).getReg() to convert to register. - template - MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, - UseArgsTy &&... Args) { - auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty)); - addUsesFromArgs(MIB, std::forward(Args)...); - return MIB; - } - /// Build but don't insert = \p Opcode . /// /// \pre setMF, setBasicBlock or setMI must have been called. @@ -226,59 +231,6 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildGlobalValue(unsigned Res, const GlobalValue *GV); - /// Build and insert \p Res = G_ADD \p Op0, \p Op1 - /// - /// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p Op1, - /// truncated to their width. - /// - /// \pre setBasicBlock or setMI must have been called. - /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers - /// with the same (scalar or vector) type). - /// - /// \return a MachineInstrBuilder for the newly created instruction. - MachineInstrBuilder buildAdd(unsigned Res, unsigned Op0, - unsigned Op1); - template - MachineInstrBuilder buildAdd(DstTy &&Ty, UseArgsTy &&... UseArgs) { - unsigned Res = getDestFromArg(Ty); - return buildAdd(Res, (getRegFromArg(UseArgs))...); - } - - /// Build and insert \p Res = G_SUB \p Op0, \p Op1 - /// - /// G_SUB sets \p Res to the sum of integer parameters \p Op0 and \p Op1, - /// truncated to their width. - /// - /// \pre setBasicBlock or setMI must have been called. - /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers - /// with the same (scalar or vector) type). - /// - /// \return a MachineInstrBuilder for the newly created instruction. - template - MachineInstrBuilder buildSub(DstTy &&Ty, UseArgsTy &&... UseArgs) { - unsigned Res = getDestFromArg(Ty); - return buildSub(Res, (getRegFromArg(UseArgs))...); - } - MachineInstrBuilder buildSub(unsigned Res, unsigned Op0, - unsigned Op1); - - /// Build and insert \p Res = G_MUL \p Op0, \p Op1 - /// - /// G_MUL sets \p Res to the sum of integer parameters \p Op0 and \p Op1, - /// truncated to their width. - /// - /// \pre setBasicBlock or setMI must have been called. - /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers - /// with the same (scalar or vector) type). - /// - /// \return a MachineInstrBuilder for the newly created instruction. - template - MachineInstrBuilder buildMul(DstTy &&Ty, UseArgsTy &&... UseArgs) { - unsigned Res = getDestFromArg(Ty); - return buildMul(Res, (getRegFromArg(UseArgs))...); - } - MachineInstrBuilder buildMul(unsigned Res, unsigned Op0, - unsigned Op1); /// Build and insert \p Res = G_GEP \p Op0, \p Op1 /// @@ -347,38 +299,6 @@ public: MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0, unsigned Op1, unsigned CarryIn); - /// Build and insert \p Res = G_AND \p Op0, \p Op1 - /// - /// G_AND sets \p Res to the bitwise and of integer parameters \p Op0 and \p - /// Op1. - /// - /// \pre setBasicBlock or setMI must have been called. - /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers - /// with the same (scalar or vector) type). - /// - /// \return a MachineInstrBuilder for the newly created instruction. - template - MachineInstrBuilder buildAnd(DstTy &&Dst, UseArgsTy &&... UseArgs) { - return buildAnd(getDestFromArg(Dst), getRegFromArg(UseArgs)...); - } - MachineInstrBuilder buildAnd(unsigned Res, unsigned Op0, - unsigned Op1); - - /// Build and insert \p Res = G_OR \p Op0, \p Op1 - /// - /// G_OR sets \p Res to the bitwise or of integer parameters \p Op0 and \p - /// Op1. - /// - /// \pre setBasicBlock or setMI must have been called. - /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers - /// with the same (scalar or vector) type). - /// - /// \return a MachineInstrBuilder for the newly created instruction. - template - MachineInstrBuilder buildOr(DstTy &&Dst, UseArgsTy &&... UseArgs) { - return buildOr(getDestFromArg(Dst), getRegFromArg(UseArgs)...); - } - MachineInstrBuilder buildOr(unsigned Res, unsigned Op0, unsigned Op1); /// Build and insert \p Res = G_ANYEXT \p Op0 /// @@ -602,6 +522,18 @@ public: MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO); + /// Build and insert `Res = Addr, MMO`. + /// + /// Loads the value stored at \p Addr. Puts the result in \p Res. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res must be a generic virtual register. + /// \pre \p Addr must be a generic virtual register with pointer type. + /// + /// \return a MachineInstrBuilder for the newly created instruction. + MachineInstrBuilder buildLoadInstr(unsigned Opcode, unsigned Res, + unsigned Addr, MachineMemOperand &MMO); + /// Build and insert `G_STORE Val, Addr, MMO`. /// /// Stores the value \p Val to \p Addr. @@ -804,5 +736,140 @@ public: MachineMemOperand &MMO); }; +/// A CRTP class that contains methods for building instructions that can +/// be constant folded. MachineIRBuilders that want to inherit from this will +/// need to implement buildBinaryOp (for constant folding binary ops). +/// Alternatively, they can implement buildInstr(Opc, Dst, Uses...) to perform +/// additional folding for Opc. +template +class FoldableInstructionsBuilder : public MachineIRBuilderBase { + Base &base() { return static_cast(*this); } + +public: + using MachineIRBuilderBase::MachineIRBuilderBase; + /// Build and insert \p Res = G_ADD \p Op0, \p Op1 + /// + /// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p Op1, + /// truncated to their width. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers + /// with the same (scalar or vector) type). + /// + /// \return a MachineInstrBuilder for the newly created instruction. + + MachineInstrBuilder buildAdd(unsigned Dst, unsigned Src0, unsigned Src1) { + return base().buildBinaryOp(TargetOpcode::G_ADD, Dst, Src0, Src1); + } + template + MachineInstrBuilder buildAdd(DstTy &&Ty, UseArgsTy &&... UseArgs) { + unsigned Res = base().getDestFromArg(Ty); + return base().buildAdd(Res, (base().getRegFromArg(UseArgs))...); + } + + /// Build and insert \p Res = G_SUB \p Op0, \p Op1 + /// + /// G_SUB sets \p Res to the sum of integer parameters \p Op0 and \p Op1, + /// truncated to their width. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers + /// with the same (scalar or vector) type). + /// + /// \return a MachineInstrBuilder for the newly created instruction. + + MachineInstrBuilder buildSub(unsigned Dst, unsigned Src0, unsigned Src1) { + return base().buildBinaryOp(TargetOpcode::G_SUB, Dst, Src0, Src1); + } + template + MachineInstrBuilder buildSub(DstTy &&Ty, UseArgsTy &&... UseArgs) { + unsigned Res = base().getDestFromArg(Ty); + return base().buildSub(Res, (base().getRegFromArg(UseArgs))...); + } + + /// Build and insert \p Res = G_MUL \p Op0, \p Op1 + /// + /// G_MUL sets \p Res to the sum of integer parameters \p Op0 and \p Op1, + /// truncated to their width. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers + /// with the same (scalar or vector) type). + /// + /// \return a MachineInstrBuilder for the newly created instruction. + MachineInstrBuilder buildMul(unsigned Dst, unsigned Src0, unsigned Src1) { + return base().buildBinaryOp(TargetOpcode::G_MUL, Dst, Src0, Src1); + } + template + MachineInstrBuilder buildMul(DstTy &&Ty, UseArgsTy &&... UseArgs) { + unsigned Res = base().getDestFromArg(Ty); + return base().buildMul(Res, (base().getRegFromArg(UseArgs))...); + } + + /// Build and insert \p Res = G_AND \p Op0, \p Op1 + /// + /// G_AND sets \p Res to the bitwise and of integer parameters \p Op0 and \p + /// Op1. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers + /// with the same (scalar or vector) type). + /// + /// \return a MachineInstrBuilder for the newly created instruction. + + MachineInstrBuilder buildAnd(unsigned Dst, unsigned Src0, unsigned Src1) { + return base().buildBinaryOp(TargetOpcode::G_AND, Dst, Src0, Src1); + } + template + MachineInstrBuilder buildAnd(DstTy &&Ty, UseArgsTy &&... UseArgs) { + unsigned Res = base().getDestFromArg(Ty); + return base().buildAnd(Res, (base().getRegFromArg(UseArgs))...); + } + + /// Build and insert \p Res = G_OR \p Op0, \p Op1 + /// + /// G_OR sets \p Res to the bitwise or of integer parameters \p Op0 and \p + /// Op1. + /// + /// \pre setBasicBlock or setMI must have been called. + /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers + /// with the same (scalar or vector) type). + /// + /// \return a MachineInstrBuilder for the newly created instruction. + MachineInstrBuilder buildOr(unsigned Dst, unsigned Src0, unsigned Src1) { + return base().buildBinaryOp(TargetOpcode::G_OR, Dst, Src0, Src1); + } + template + MachineInstrBuilder buildOr(DstTy &&Ty, UseArgsTy &&... UseArgs) { + unsigned Res = base().getDestFromArg(Ty); + return base().buildOr(Res, (base().getRegFromArg(UseArgs))...); + } +}; + +class MachineIRBuilder : public FoldableInstructionsBuilder { +public: + using FoldableInstructionsBuilder< + MachineIRBuilder>::FoldableInstructionsBuilder; + MachineInstrBuilder buildBinaryOp(unsigned Opcode, unsigned Dst, + unsigned Src0, unsigned Src1) { + validateBinaryOp(Dst, Src0, Src1); + return buildInstr(Opcode).addDef(Dst).addUse(Src0).addUse(Src1); + } + using FoldableInstructionsBuilder::buildInstr; + /// DAG like Generic method for building arbitrary instructions as above. + /// \Opc opcode for the instruction. + /// \Ty Either LLT/TargetRegisterClass/unsigned types for Dst + /// \Args Variadic list of uses of types(unsigned/MachineInstrBuilder) + /// Uses of type MachineInstrBuilder will perform + /// getOperand(0).getReg() to convert to register. + template + MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, + UseArgsTy &&... Args) { + auto MIB = buildInstr(Opc).addDef(getDestFromArg(Ty)); + addUsesFromArgs(MIB, std::forward(Args)...); + return MIB; + } +}; + } // End namespace llvm. #endif // LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index ea94871d931555f17cee9d80eb656046176a65df..df0dcb1cf041de4567887f78e87a3b900a80c52a 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -424,7 +424,8 @@ namespace ISD { /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but /// op #2 is a boolean indicating if there is an incoming carry. This /// operator checks the result of "LHS - RHS - Carry", and can be used to - /// compare two wide integers: (setcce lhshi rhshi (subc lhslo rhslo) cc). + /// compare two wide integers: + /// (setcccarry lhshi rhshi (subcarry lhslo rhslo) cc). /// Only valid for integers. SETCCCARRY, @@ -495,7 +496,8 @@ namespace ISD { ZERO_EXTEND_VECTOR_INREG, /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned - /// integer. + /// integer. These have the same semantics as fptosi and fptoui in IR. If + /// the FP value cannot fit in the integer type, the results are undefined. FP_TO_SINT, FP_TO_UINT, diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h index 988e6d6cb3a3c94e08e87983bbd500b2ccda1e7f..de06491d8c573f6af3110d25f97963e0fc81abd7 100644 --- a/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -17,6 +17,7 @@ #define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Config/llvm-config.h" namespace llvm { class LatencyPriorityQueue; @@ -83,6 +84,10 @@ namespace llvm { void remove(SUnit *SU) override; +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + LLVM_DUMP_METHOD void dump(ScheduleDAG *DAG) const override; +#endif + // scheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make diff --git a/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h b/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h index 848ee1dc0dc6013ca49999e40afc1339d0e0a042..221f16a03f1672889b17a6354bfe6a9cd83e8f59 100644 --- a/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h +++ b/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h @@ -23,7 +23,7 @@ #include "llvm/CodeGen/MachineLoopInfo.h" namespace llvm { -/// \brief This is an alternative analysis pass to MachineBlockFrequencyInfo. +/// This is an alternative analysis pass to MachineBlockFrequencyInfo. /// The difference is that with this pass, the block frequencies are not /// computed when the analysis pass is executed but rather when the BFI result /// is explicitly requested by the analysis client. @@ -49,7 +49,7 @@ private: /// The function. MachineFunction *MF = nullptr; - /// \brief Calculate MBFI and all other analyses that's not available and + /// Calculate MBFI and all other analyses that's not available and /// required by BFI. MachineBlockFrequencyInfo &calculateIfNotAvailable() const; @@ -58,10 +58,10 @@ public: LazyMachineBlockFrequencyInfoPass(); - /// \brief Compute and return the block frequencies. + /// Compute and return the block frequencies. MachineBlockFrequencyInfo &getBFI() { return calculateIfNotAvailable(); } - /// \brief Compute and return the block frequencies. + /// Compute and return the block frequencies. const MachineBlockFrequencyInfo &getBFI() const { return calculateIfNotAvailable(); } diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index f4fa872c7f5bb8a65da474ad2c5b71ae259b3dee..defa0cf22916d4a4766a09793ac3fdedf7e43a06 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -609,7 +609,7 @@ namespace llvm { void print(raw_ostream &OS) const; void dump() const; - /// \brief Walk the range and assert if any invariants fail to hold. + /// Walk the range and assert if any invariants fail to hold. /// /// Note that this is a no-op when asserts are disabled. #ifdef NDEBUG @@ -802,7 +802,7 @@ namespace llvm { void print(raw_ostream &OS) const; void dump() const; - /// \brief Walks the interval and assert if any invariants fail to hold. + /// Walks the interval and assert if any invariants fail to hold. /// /// Note that this is a no-op when asserts are disabled. #ifdef NDEBUG diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h index f9aab0d09e1f78ce6acd6fc0f57d4ec78b3f7ab0..1300f60213fd378c35586cea31e615273effdee2 100644 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ b/include/llvm/CodeGen/LivePhysRegs.h @@ -44,7 +44,7 @@ class MachineOperand; class MachineRegisterInfo; class raw_ostream; -/// \brief A set of physical registers with utility functions to track liveness +/// A set of physical registers with utility functions to track liveness /// when walking backward/forward through a basic block. class LivePhysRegs { const TargetRegisterInfo *TRI = nullptr; @@ -84,7 +84,7 @@ public: LiveRegs.insert(*SubRegs); } - /// \brief Removes a physical register, all its sub-registers, and all its + /// Removes a physical register, all its sub-registers, and all its /// super-registers from the set. void removeReg(unsigned Reg) { assert(TRI && "LivePhysRegs is not initialized."); @@ -98,7 +98,7 @@ public: SmallVectorImpl> *Clobbers = nullptr); - /// \brief Returns true if register \p Reg is contained in the set. This also + /// Returns true if register \p Reg is contained in the set. This also /// works if only the super register of \p Reg has been defined, because /// addReg() always adds all sub-registers to the set as well. /// Note: Returns false if just some sub registers are live, use available() @@ -155,7 +155,7 @@ public: void dump() const; private: - /// \brief Adds live-in registers from basic block \p MBB, taking associated + /// Adds live-in registers from basic block \p MBB, taking associated /// lane masks into consideration. void addBlockLiveIns(const MachineBasicBlock &MBB); @@ -169,7 +169,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const LivePhysRegs& LR) { return OS; } -/// \brief Computes registers live-in to \p MBB assuming all of its successors +/// Computes registers live-in to \p MBB assuming all of its successors /// live-in lists are up-to-date. Puts the result into the given LivePhysReg /// instance \p LiveRegs. void computeLiveIns(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB); diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h index 82b1f0b0de71303160a6a7c97b600d47847f755c..53830297c525c0074fd175e81f4f75065b3ea65e 100644 --- a/include/llvm/CodeGen/LiveRangeEdit.h +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -117,7 +117,7 @@ private: /// registers are created. void MRI_NoteNewVirtualRegister(unsigned VReg) override; - /// \brief Check if MachineOperand \p MO is a last use/kill either in the + /// Check if MachineOperand \p MO is a last use/kill either in the /// main live range of \p LI or in one of the matching subregister ranges. bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const; diff --git a/include/llvm/CodeGen/LiveRegUnits.h b/include/llvm/CodeGen/LiveRegUnits.h index dc4956da9637cc8d009a618f585aa77ca625c536..249545906e01d10c11215aa355783b9cd6956aac 100644 --- a/include/llvm/CodeGen/LiveRegUnits.h +++ b/include/llvm/CodeGen/LiveRegUnits.h @@ -16,6 +16,7 @@ #define LLVM_CODEGEN_LIVEREGUNITS_H #include "llvm/ADT/BitVector.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCRegisterInfo.h" @@ -40,6 +41,36 @@ public: init(TRI); } + /// For a machine instruction \p MI, adds all register units used in + /// \p UsedRegUnits and defined or clobbered in \p ModifiedRegUnits. This is + /// useful when walking over a range of instructions to track registers + /// used or defined seperately. + static void accumulateUsedDefed(const MachineInstr &MI, + LiveRegUnits &ModifiedRegUnits, + LiveRegUnits &UsedRegUnits, + const TargetRegisterInfo *TRI) { + for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { + if (O->isRegMask()) + ModifiedRegUnits.addRegsInMask(O->getRegMask()); + if (!O->isReg()) + continue; + unsigned Reg = O->getReg(); + if (!TargetRegisterInfo::isPhysicalRegister(Reg)) + continue; + if (O->isDef()) { + // Some architectures (e.g. AArch64 XZR/WZR) have registers that are + // constant and may be used as destinations to indicate the generated + // value is discarded. No need to track such case as a def. + if (!TRI->isConstantPhysReg(Reg)) + ModifiedRegUnits.addReg(Reg); + } else { + assert(O->isUse() && "Reg operand not a def and not a use"); + UsedRegUnits.addReg(Reg); + } + } + return; + } + /// Initialize and clear the set. void init(const TargetRegisterInfo &TRI) { this->TRI = &TRI; @@ -59,7 +90,7 @@ public: Units.set(*Unit); } - /// \brief Adds register units covered by physical register \p Reg that are + /// Adds register units covered by physical register \p Reg that are /// part of the lanemask \p Mask. void addRegMasked(unsigned Reg, LaneBitmask Mask) { for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) { diff --git a/include/llvm/CodeGen/LoopTraversal.h b/include/llvm/CodeGen/LoopTraversal.h index a816f6dd07bdfba695910daecc673878355a42a2..750da0143c0df3892447522a7b76ccbf2b4154e8 100644 --- a/include/llvm/CodeGen/LoopTraversal.h +++ b/include/llvm/CodeGen/LoopTraversal.h @@ -101,7 +101,7 @@ public: }; LoopTraversal() {} - /// \brief Identifies basic blocks that are part of loops and should to be + /// Identifies basic blocks that are part of loops and should to be /// visited twice and returns efficient traversal order for all the blocks. typedef SmallVector TraversalOrder; TraversalOrder traverse(MachineFunction &MF); diff --git a/include/llvm/CodeGen/MIRParser/MIRParser.h b/include/llvm/CodeGen/MIRParser/MIRParser.h index b631a8c0122a290f4ce30572d6e28d4394e23879..e199a1f69ad7078a5dfeaade4c7e3086095d66ce 100644 --- a/include/llvm/CodeGen/MIRParser/MIRParser.h +++ b/include/llvm/CodeGen/MIRParser/MIRParser.h @@ -45,7 +45,7 @@ public: /// \returns nullptr if a parsing error occurred. std::unique_ptr parseIRModule(); - /// \brief Parses MachineFunctions in the MIR file and add them to the given + /// Parses MachineFunctions in the MIR file and add them to the given /// MachineModuleInfo \p MMI. /// /// \returns true if an error occurred. diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index b75f9c8a693c9867b8f5e275b9760ce3ff96db68..7f46406c47894393f30a4abb3779f43d15a8d36d 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -258,11 +258,11 @@ template <> struct MappingTraits { YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored, true); YamlIO.mapOptional("local-offset", Object.LocalOffset, Optional()); - YamlIO.mapOptional("di-variable", Object.DebugVar, + YamlIO.mapOptional("debug-info-variable", Object.DebugVar, StringValue()); // Don't print it out when it's empty. - YamlIO.mapOptional("di-expression", Object.DebugExpr, + YamlIO.mapOptional("debug-info-expression", Object.DebugExpr, StringValue()); // Don't print it out when it's empty. - YamlIO.mapOptional("di-location", Object.DebugLoc, + YamlIO.mapOptional("debug-info-location", Object.DebugLoc, StringValue()); // Don't print it out when it's empty. } @@ -283,6 +283,9 @@ struct FixedMachineStackObject { bool IsAliased = false; StringValue CalleeSavedRegister; bool CalleeSavedRestored = true; + StringValue DebugVar; + StringValue DebugExpr; + StringValue DebugLoc; bool operator==(const FixedMachineStackObject &Other) const { return ID == Other.ID && Type == Other.Type && Offset == Other.Offset && @@ -290,7 +293,9 @@ struct FixedMachineStackObject { StackID == Other.StackID && IsImmutable == Other.IsImmutable && IsAliased == Other.IsAliased && CalleeSavedRegister == Other.CalleeSavedRegister && - CalleeSavedRestored == Other.CalleeSavedRestored; + CalleeSavedRestored == Other.CalleeSavedRestored && + DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr + && DebugLoc == Other.DebugLoc; } }; @@ -321,6 +326,12 @@ template <> struct MappingTraits { StringValue()); // Don't print it out when it's empty. YamlIO.mapOptional("callee-saved-restored", Object.CalleeSavedRestored, true); + YamlIO.mapOptional("debug-info-variable", Object.DebugVar, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("debug-info-expression", Object.DebugExpr, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("debug-info-location", Object.DebugLoc, + StringValue()); // Don't print it out when it's empty. } static const bool flow = true; @@ -417,6 +428,7 @@ struct MachineFrameInfo { bool HasOpaqueSPAdjustment = false; bool HasVAStart = false; bool HasMustTailInVarArgFunc = false; + unsigned LocalFrameSize = 0; StringValue SavePoint; StringValue RestorePoint; @@ -434,6 +446,7 @@ struct MachineFrameInfo { HasOpaqueSPAdjustment == Other.HasOpaqueSPAdjustment && HasVAStart == Other.HasVAStart && HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc && + LocalFrameSize == Other.LocalFrameSize && SavePoint == Other.SavePoint && RestorePoint == Other.RestorePoint; } }; @@ -457,6 +470,7 @@ template <> struct MappingTraits { YamlIO.mapOptional("hasVAStart", MFI.HasVAStart, false); YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc, false); + YamlIO.mapOptional("localFrameSize", MFI.LocalFrameSize, (unsigned)0); YamlIO.mapOptional("savePoint", MFI.SavePoint, StringValue()); // Don't print it out when it's empty. YamlIO.mapOptional("restorePoint", MFI.RestorePoint, diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 8dc83442c30d5925e5b30ed870dbb2cdbcee5970..c351b7228c91d40fde4275382e1d4f5ceed942d8 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -115,13 +115,18 @@ private: /// branch. bool AddressTaken = false; + /// Indicate that this basic block is the entry block of an EH scope, i.e., + /// the block that used to have a catchpad or cleanuppad instruction in the + /// LLVM IR. + bool IsEHScopeEntry = false; + /// Indicate that this basic block is the entry block of an EH funclet. bool IsEHFuncletEntry = false; /// Indicate that this basic block is the entry block of a cleanup funclet. bool IsCleanupFuncletEntry = false; - /// \brief since getSymbol is a relatively heavy-weight operation, the symbol + /// since getSymbol is a relatively heavy-weight operation, the symbol /// is only computed once and is cached. mutable MCSymbol *CachedMCSymbol = nullptr; @@ -375,6 +380,14 @@ public: bool hasEHPadSuccessor() const; + /// Returns true if this is the entry block of an EH scope, i.e., the block + /// that used to have a catchpad or cleanuppad instruction in the LLVM IR. + bool isEHScopeEntry() const { return IsEHScopeEntry; } + + /// Indicates if this is the entry block of an EH scope, i.e., the block that + /// that used to have a catchpad or cleanuppad instruction in the LLVM IR. + void setIsEHScopeEntry(bool V = true) { IsEHScopeEntry = V; } + /// Returns true if this is the entry block of an EH funclet. bool isEHFuncletEntry() const { return IsEHFuncletEntry; } @@ -457,6 +470,13 @@ public: /// Replace successor OLD with NEW and update probability info. void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New); + /// Copy a successor (and any probability info) from original block to this + /// block's. Uses an iterator into the original blocks successors. + /// + /// This is useful when doing a partial clone of successors. Afterward, the + /// probabilities may need to be normalized. + void copySuccessor(MachineBasicBlock *Orig, succ_iterator I); + /// Transfers all the successors from MBB to this machine basic block (i.e., /// copies all the successors FromMBB and remove all the successors from /// FromMBB). @@ -693,7 +713,7 @@ public: bool IsCond); /// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE - /// instructions. Return UnknownLoc if there is none. + /// and DBG_LABEL instructions. Return UnknownLoc if there is none. DebugLoc findDebugLoc(instr_iterator MBBI); DebugLoc findDebugLoc(iterator MBBI) { return findDebugLoc(MBBI.getInstrIterator()); @@ -890,7 +910,7 @@ public: /// const_instr_iterator} and the respective reverse iterators. template inline IterT skipDebugInstructionsForward(IterT It, IterT End) { - while (It != End && It->isDebugValue()) + while (It != End && It->isDebugInstr()) It++; return It; } @@ -901,7 +921,7 @@ inline IterT skipDebugInstructionsForward(IterT It, IterT End) { /// const_instr_iterator} and the respective reverse iterators. template inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin) { - while (It != Begin && It->isDebugValue()) + while (It != Begin && It->isDebugInstr()) It--; return It; } diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 1705a0f7e59b3cc7e3ccaaf715e64986eaa0b0e5..b0b5420a884b6213358a060690c532d8067c1c88 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -63,7 +63,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, /// This class is a data container for one entry in a MachineConstantPool. /// It contains a pointer to the value and an offset from the start of /// the constant pool. -/// @brief An entry in a MachineConstantPool +/// An entry in a MachineConstantPool class MachineConstantPoolEntry { public: /// The constant itself. @@ -117,7 +117,7 @@ public: /// the use of MO_ConstantPoolIndex values. When emitting assembly or machine /// code, these virtual address references are converted to refer to the /// address of the function constant pool values. -/// @brief The machine constant pool. +/// The machine constant pool. class MachineConstantPool { unsigned PoolAlignment; ///< The alignment for the pool. std::vector Constants; ///< The pool of constants. @@ -128,7 +128,7 @@ class MachineConstantPool { const DataLayout &getDataLayout() const { return DL; } public: - /// @brief The only constructor. + /// The only constructor. explicit MachineConstantPool(const DataLayout &DL) : PoolAlignment(1), DL(DL) {} ~MachineConstantPool(); diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index af642d9cfc95a8e82a00ed93864c77e0a75991bd..e3d3d169db9769c4521c9c3176d7bf81a371b0f8 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -45,7 +45,7 @@ using MachineDomTreeNode = DomTreeNodeBase; /// compute a normal dominator tree. /// class MachineDominatorTree : public MachineFunctionPass { - /// \brief Helper structure used to hold all the basic blocks + /// Helper structure used to hold all the basic blocks /// involved in the split of a critical edge. struct CriticalEdge { MachineBasicBlock *FromBB; @@ -53,12 +53,12 @@ class MachineDominatorTree : public MachineFunctionPass { MachineBasicBlock *NewBB; }; - /// \brief Pile up all the critical edges to be split. + /// Pile up all the critical edges to be split. /// The splitting of a critical edge is local and thus, it is possible /// to apply several of those changes at the same time. mutable SmallVector CriticalEdgesToSplit; - /// \brief Remember all the basic blocks that are inserted during + /// Remember all the basic blocks that are inserted during /// edge splitting. /// Invariant: NewBBs == all the basic blocks contained in the NewBB /// field of all the elements of CriticalEdgesToSplit. @@ -69,7 +69,7 @@ class MachineDominatorTree : public MachineFunctionPass { /// The DominatorTreeBase that is used to compute a normal dominator tree std::unique_ptr> DT; - /// \brief Apply all the recorded critical edges to the DT. + /// Apply all the recorded critical edges to the DT. /// This updates the underlying DT information in a way that uses /// the fast query path of DT as much as possible. /// @@ -228,7 +228,7 @@ public: void print(raw_ostream &OS, const Module*) const override; - /// \brief Record that the critical edge (FromBB, ToBB) has been + /// Record that the critical edge (FromBB, ToBB) has been /// split with NewBB. /// This is best to use this method instead of directly update the /// underlying information, because this helps mitigating the diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index f887517217e1874bf8431c049a187e8ac3255bca..91b506c1524524f9f79f4a2cc40f7c7905a1b0ad 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -85,7 +85,7 @@ public: /// stack offsets of the object, eliminating all MO_FrameIndex operands from /// the program. /// -/// @brief Abstract Stack Frame Information +/// Abstract Stack Frame Information class MachineFrameInfo { // Represent a single object allocated on the stack. diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 7d8b7ebe8d6295c46bde9b2118e7d486d11e924d..fd0906770ba51528ace0af1172987cc85e4fae29 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -96,7 +96,7 @@ template <> struct ilist_callback_traits { struct MachineFunctionInfo { virtual ~MachineFunctionInfo(); - /// \brief Factory function: default behavior is to call new using the + /// Factory function: default behavior is to call new using the /// supplied allocator. /// /// This function can be overridden in a derive class. @@ -319,6 +319,7 @@ class MachineFunction { bool CallsEHReturn = false; bool CallsUnwindInit = false; + bool HasEHScopes = false; bool HasEHFunclets = false; /// List of C++ TypeInfo used. @@ -349,11 +350,12 @@ public: struct VariableDbgInfo { const DILocalVariable *Var; const DIExpression *Expr; - unsigned Slot; + // The Slot can be negative for fixed stack objects. + int Slot; const DILocation *Loc; VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, - unsigned Slot, const DILocation *Loc) + int Slot, const DILocation *Loc) : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} }; using VariableDbgInfoMapTy = SmallVector; @@ -609,7 +611,7 @@ public: //===--------------------------------------------------------------------===// // Internal functions used to automatically number MachineBasicBlocks - /// \brief Adds the MBB to the internal numbering. Returns the unique number + /// Adds the MBB to the internal numbering. Returns the unique number /// assigned to the MBB. unsigned addToMBBNumbering(MachineBasicBlock *MBB) { MBBNumbering.push_back(MBB); @@ -695,7 +697,7 @@ public: OperandRecycler.deallocate(Cap, Array); } - /// \brief Allocate and initialize a register mask with @p NumRegister bits. + /// Allocate and initialize a register mask with @p NumRegister bits. uint32_t *allocateRegisterMask(unsigned NumRegister) { unsigned Size = (NumRegister + 31) / 32; uint32_t *Mask = Allocator.Allocate(Size); @@ -759,6 +761,9 @@ public: bool callsUnwindInit() const { return CallsUnwindInit; } void setCallsUnwindInit(bool b) { CallsUnwindInit = b; } + bool hasEHScopes() const { return HasEHScopes; } + void setHasEHScopes(bool V) { HasEHScopes = V; } + bool hasEHFunclets() const { return HasEHFunclets; } void setHasEHFunclets(bool V) { HasEHFunclets = V; } @@ -860,7 +865,7 @@ public: /// Collect information used to emit debugging information of a variable. void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, - unsigned Slot, const DILocation *Loc) { + int Slot, const DILocation *Loc) { VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc); } diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index ea94be02797d5fcc205bb7eee651e33949c5ed7e..91705aff2c1015f53e8a0d2f2f36ffd5e985d913 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -80,7 +80,21 @@ public: FrameDestroy = 1 << 1, // Instruction is used as a part of // function frame destruction code. BundledPred = 1 << 2, // Instruction has bundled predecessors. - BundledSucc = 1 << 3 // Instruction has bundled successors. + BundledSucc = 1 << 3, // Instruction has bundled successors. + FmNoNans = 1 << 4, // Instruction does not support Fast + // math nan values. + FmNoInfs = 1 << 5, // Instruction does not support Fast + // math infinity values. + FmNsz = 1 << 6, // Instruction is not required to retain + // signed zero values. + FmArcp = 1 << 7, // Instruction supports Fast math + // reciprocal approximations. + FmContract = 1 << 8, // Instruction supports Fast math + // contraction operations like fma. + FmAfn = 1 << 9, // Instruction may map to Fast math + // instrinsic approximation. + FmReassoc = 1 << 10 // Instruction supports Fast math + // reassociation of operand order. }; private: @@ -93,7 +107,7 @@ private: using OperandCapacity = ArrayRecycler::Capacity; OperandCapacity CapOperands; // Capacity of the Operands array. - uint8_t Flags = 0; // Various bits of additional + uint16_t Flags = 0; // Various bits of additional // information about machine // instruction. @@ -186,7 +200,7 @@ public: /// Set a MI flag. void setFlag(MIFlag Flag) { - Flags |= (uint8_t)Flag; + Flags |= (uint16_t)Flag; } void setFlags(unsigned flags) { @@ -197,7 +211,7 @@ public: /// clearFlag - Clear a MI flag. void clearFlag(MIFlag Flag) { - Flags &= ~((uint8_t)Flag); + Flags &= ~((uint16_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). @@ -278,6 +292,10 @@ public: /// this DBG_VALUE instruction. const DIExpression *getDebugExpression() const; + /// Return the debug label referenced by + /// this DBG_LABEL instruction. + const DILabel *getDebugLabel() const; + /// Emit an error referring to the source location of this instruction. /// This should only be used for inline assembly that is somehow /// impossible to compile. Other errors should have been handled much @@ -529,6 +547,12 @@ public: return hasProperty(MCID::MoveImm, Type); } + /// Return true if this instruction is a register move. + /// (including moving values from subreg to reg) + bool isMoveReg(QueryType Type = IgnoreBundle) const { + return hasProperty(MCID::MoveReg, Type); + } + /// Return true if this instruction is a bitcast instruction. bool isBitcast(QueryType Type = IgnoreBundle) const { return hasProperty(MCID::Bitcast, Type); @@ -576,7 +600,7 @@ public: return hasProperty(MCID::FoldableAsLoad, Type); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic REG_SEQUENCE instructions. /// E.g., on ARM, /// dX VMOVDRR rY, rZ @@ -590,7 +614,7 @@ public: return hasProperty(MCID::RegSequence, Type); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic EXTRACT_SUBREG instructions. /// E.g., on ARM, /// rX, rY VMOVRRD dZ @@ -605,7 +629,7 @@ public: return hasProperty(MCID::ExtractSubreg, Type); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic INSERT_SUBREG instructions. /// E.g., on ARM, /// dX = VSETLNi32 dY, rZ, Imm @@ -817,6 +841,8 @@ public: bool isPosition() const { return isLabel() || isCFIInstruction(); } bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } + bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } + bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); } /// A DBG_VALUE is indirect iff the first operand is a register and /// the second operand is an immediate. @@ -893,6 +919,7 @@ public: case TargetOpcode::EH_LABEL: case TargetOpcode::GC_LABEL: case TargetOpcode::DBG_VALUE: + case TargetOpcode::DBG_LABEL: case TargetOpcode::LIFETIME_START: case TargetOpcode::LIFETIME_END: return true; @@ -1049,7 +1076,7 @@ public: const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; - /// \brief Applies the constraints (def/use) implied by this MI on \p Reg to + /// Applies the constraints (def/use) implied by this MI on \p Reg to /// the given \p CurRC. /// If \p ExploreBundle is set and MI is part of a bundle, all the /// instructions inside the bundle will be taken into account. In other words, @@ -1066,7 +1093,7 @@ public: const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, bool ExploreBundle = false) const; - /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand + /// Applies the constraints (def/use) implied by the \p OpIdx operand /// to the given \p CurRC. /// /// Returns the register class that satisfies both \p CurRC and the @@ -1244,10 +1271,11 @@ public: /// \p TII is used to print the opcode name. If it's not present, but the /// MI is in a function, the opcode will be printed using the function's TII. void print(raw_ostream &OS, bool IsStandalone = true, bool SkipOpers = false, - bool SkipDebugLoc = false, + bool SkipDebugLoc = false, bool AddNewLine = true, const TargetInstrInfo *TII = nullptr) const; void print(raw_ostream &OS, ModuleSlotTracker &MST, bool IsStandalone = true, bool SkipOpers = false, bool SkipDebugLoc = false, + bool AddNewLine = true, const TargetInstrInfo *TII = nullptr) const; void dump() const; /// @} @@ -1362,7 +1390,7 @@ private: /// Slow path for hasProperty when we're dealing with a bundle. bool hasPropertyInBundle(unsigned Mask, QueryType Type) const; - /// \brief Implements the logic of getRegClassConstraintEffectForVReg for the + /// Implements the logic of getRegClassConstraintEffectForVReg for the /// this MI and the given operand index \p OpIdx. /// If the related operand does not constrained Reg, this returns CurRC. const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl( diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 2df89b15dd52ffe4dcc7d71eccb990373887fa14..d507c558f419c4276afceed24a15a06aaa9f5301 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -220,6 +220,9 @@ public: assert((MI->isDebugValue() ? static_cast(MI->getDebugVariable()) : true) && "first MDNode argument of a DBG_VALUE not a variable"); + assert((MI->isDebugLabel() ? static_cast(MI->getDebugLabel()) + : true) && + "first MDNode argument of a DBG_LABEL not a label"); return *this; } diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 104655e4552468ad92348d2991607baac45ec7e6..917fb90380f50b3a4c8589ff83bffeaa20d8e3d7 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -54,7 +54,7 @@ public: /// that contains the header. MachineBasicBlock *getBottomBlock(); - /// \brief Find the block that contains the loop control variable and the + /// Find the block that contains the loop control variable and the /// loop test. This will return the latch block if it's one of the exiting /// blocks. Otherwise, return the exiting block. Return 'null' when /// multiple exiting blocks are present. @@ -97,7 +97,7 @@ public: LoopInfoBase& getBase() { return LI; } - /// \brief Find the block that either is the loop preheader, or could + /// Find the block that either is the loop preheader, or could /// speculatively be used as the preheader. This is e.g. useful to place /// loop setup code. Code that cannot be speculated should not be placed /// here. SpeculativePreheader is controlling whether it also tries to diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index dea0d8002f7dfa3b95b44ab843af9a2b5d47ec4c..515340bfc1981a98415207907bb68fa1cb538307 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -184,7 +184,7 @@ public: /// atomic operations the atomic ordering requirements when store does not /// occur must also be specified. MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, uint64_t s, - unsigned base_alignment, + uint64_t base_alignment, const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System, diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 4f0db1c2ebccaad198ed663c00ac1e4b51ea5849..dc210e0f45e1b79337f7f3f4add1773ce3af7f1f 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -295,6 +295,12 @@ public: unsigned TiedOperandIdx, const TargetRegisterInfo *TRI, const TargetIntrinsicInfo *IntrinsicInfo) const; + /// Same as print(os, TRI, IntrinsicInfo), but allows to specify the low-level + /// type to be printed the same way the full version of print(...) does it. + void print(raw_ostream &os, LLT TypeToPrint, + const TargetRegisterInfo *TRI = nullptr, + const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const; + void dump() const; //===--------------------------------------------------------------------===// @@ -630,6 +636,11 @@ public: Contents.ImmVal = immVal; } + void setCImm(const ConstantInt *CI) { + assert(isCImm() && "Wrong MachineOperand mutator"); + Contents.CI = CI; + } + void setFPImm(const ConstantFP *CFP) { assert(isFPImm() && "Wrong MachineOperand mutator"); Contents.CFP = CFP; @@ -677,7 +688,7 @@ public: /// should stay in sync with the hash_value overload below. bool isIdenticalTo(const MachineOperand &Other) const; - /// \brief MachineOperand hash_value overload. + /// MachineOperand hash_value overload. /// /// Note that this includes the same information in the hash that /// isIdenticalTo uses for comparison. It is thus suited for use in hash diff --git a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h index 2fdefbed37ce05a0d4a0da34020c5afe9631a9e4..a7ce870400c2d01fb24e9f9316e1ac342be00c7e 100644 --- a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h +++ b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h @@ -24,7 +24,7 @@ class MachineBasicBlock; class MachineBlockFrequencyInfo; class MachineInstr; -/// \brief Common features for diagnostics dealing with optimization remarks +/// Common features for diagnostics dealing with optimization remarks /// that are used by machine passes. class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase { public: @@ -151,7 +151,7 @@ public: /// Emit an optimization remark. void emit(DiagnosticInfoOptimizationBase &OptDiag); - /// \brief Whether we allow for extra compile-time budget to perform more + /// Whether we allow for extra compile-time budget to perform more /// analysis to be more informative. /// /// This is useful to enable additional missed optimizations to be reported @@ -164,7 +164,7 @@ public: .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName)); } - /// \brief Take a lambda that returns a remark which will be emitted. Second + /// Take a lambda that returns a remark which will be emitted. Second /// argument is only used to restrict this to functions. template void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) { @@ -192,7 +192,7 @@ private: /// Similar but use value from \p OptDiag and update hotness there. void computeHotness(DiagnosticInfoMIROptimization &Remark); - /// \brief Only allow verbose messages if we know we're filtering by hotness + /// Only allow verbose messages if we know we're filtering by hotness /// (BFI is only set in this case). bool shouldEmitVerbose() { return MBFI != nullptr; } }; diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index b0dfd028d41962b7565b4f74106706dbf1a23503..5bf4a49c8b3bab2602fa6fbabf6f12d765af6a6f 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -136,9 +136,9 @@ private: /// started. BitVector ReservedRegs; - using VRegToTypeMap = DenseMap; - /// Map generic virtual registers to their actual size. - mutable std::unique_ptr VRegToType; + using VRegToTypeMap = IndexedMap; + /// Map generic virtual registers to their low-level type. + VRegToTypeMap VRegToType; /// Keep track of the physical registers that are live in to the function. /// Live in values are typically arguments in registers. LiveIn values are @@ -714,26 +714,23 @@ public: /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. - unsigned createVirtualRegister(const TargetRegisterClass *RegClass); + unsigned createVirtualRegister(const TargetRegisterClass *RegClass, + StringRef Name = ""); - /// Accessor for VRegToType. This accessor should only be used - /// by global-isel related work. - VRegToTypeMap &getVRegToType() const { - if (!VRegToType) - VRegToType.reset(new VRegToTypeMap); - return *VRegToType.get(); - } - - /// Get the low-level type of \p VReg or LLT{} if VReg is not a generic + /// Get the low-level type of \p Reg or LLT{} if Reg is not a generic /// (target independent) virtual register. - LLT getType(unsigned VReg) const; + LLT getType(unsigned Reg) const { + if (TargetRegisterInfo::isVirtualRegister(Reg) && VRegToType.inBounds(Reg)) + return VRegToType[Reg]; + return LLT{}; + } /// Set the low-level type of \p VReg to \p Ty. void setType(unsigned VReg, LLT Ty); /// Create and return a new generic virtual register with low-level /// type \p Ty. - unsigned createGenericVirtualRegister(LLT Ty); + unsigned createGenericVirtualRegister(LLT Ty, StringRef Name = ""); /// Remove all types associated to virtual registers (after instruction /// selection and constraining of all generic virtual registers). diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index e327881de13aac598839bc9a735b0a9f5fe3e325..85ffa4eda2b89cbf5d9b6777a805d6418733ade6 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -237,7 +237,7 @@ public: /// be scheduled at the bottom. virtual SUnit *pickNode(bool &IsTopNode) = 0; - /// \brief Scheduler callback to notify that a new subtree is scheduled. + /// Scheduler callback to notify that a new subtree is scheduled. virtual void scheduleTree(unsigned SubtreeID) {} /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an @@ -318,11 +318,11 @@ public: Mutations.push_back(std::move(Mutation)); } - /// \brief True if an edge can be added from PredSU to SuccSU without creating + /// True if an edge can be added from PredSU to SuccSU without creating /// a cycle. bool canAddEdge(SUnit *SuccSU, SUnit *PredSU); - /// \brief Add a DAG edge to the given SU with the given predecessor + /// Add a DAG edge to the given SU with the given predecessor /// dependence data. /// /// \returns true if the edge may be added without creating a cycle OR if an @@ -374,7 +374,7 @@ protected: /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues. void placeDebugValues(); - /// \brief dump the scheduled Sequence. + /// dump the scheduled Sequence. void dumpSchedule() const; // Lesser helpers... @@ -445,7 +445,7 @@ public: /// Return true if this DAG supports VReg liveness and RegPressure. bool hasVRegLiveness() const override { return true; } - /// \brief Return true if register pressure tracking is enabled. + /// Return true if register pressure tracking is enabled. bool isTrackingPressure() const { return ShouldTrackPressure; } /// Get current register pressure for the top scheduled instructions. @@ -897,6 +897,28 @@ protected: #endif }; +// Utility functions used by heuristics in tryCandidate(). +bool tryLess(int TryVal, int CandVal, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason); +bool tryGreater(int TryVal, int CandVal, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason); +bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + SchedBoundary &Zone); +bool tryPressure(const PressureChange &TryP, + const PressureChange &CandP, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason, + const TargetRegisterInfo *TRI, + const MachineFunction &MF); +unsigned getWeakLeft(const SUnit *SU, bool isTop); +int biasPhysRegCopy(const SUnit *SU, bool isTop); + /// GenericScheduler shrinks the unscheduled zone using heuristics to balance /// the schedule. class GenericScheduler : public GenericSchedulerBase { @@ -963,9 +985,8 @@ protected: const RegPressureTracker &RPTracker, RegPressureTracker &TempTracker); - void tryCandidate(SchedCandidate &Cand, - SchedCandidate &TryCand, - SchedBoundary *Zone); + virtual void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, + SchedBoundary *Zone) const; SUnit *pickNodeBidirectional(bool &IsTopNode); diff --git a/include/llvm/CodeGen/MacroFusion.h b/include/llvm/CodeGen/MacroFusion.h index dc105fdc68fd8e71463812b57b09a49ff3a601f1..a77226ddaf33ad2a0e09fdbb0ff960c214332798 100644 --- a/include/llvm/CodeGen/MacroFusion.h +++ b/include/llvm/CodeGen/MacroFusion.h @@ -25,7 +25,7 @@ class ScheduleDAGMutation; class TargetInstrInfo; class TargetSubtargetInfo; -/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused +/// Check if the instr pair, FirstMI and SecondMI, should be fused /// together. Given SecondMI, when FirstMI is unspecified, then check if /// SecondMI may be part of a fused pair at all. using ShouldSchedulePredTy = std::function; -/// \brief Create a DAG scheduling mutation to pair instructions back to back +/// Create a DAG scheduling mutation to pair instructions back to back /// for instructions that benefit according to the target-specific /// shouldScheduleAdjacent predicate function. std::unique_ptr createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); -/// \brief Create a DAG scheduling mutation to pair branch instructions with one +/// Create a DAG scheduling mutation to pair branch instructions with one /// of their predecessors back to back for instructions that benefit according /// to the target-specific shouldScheduleAdjacent predicate function. std::unique_ptr diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index e94878ced10dc9a1dfe2458c8a62fb062f9361bf..a6d88b057dcb51da30a19d2dfaa8b216633493ef 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -29,12 +29,12 @@ namespace PBQP { using NodeId = unsigned; using EdgeId = unsigned; - /// @brief Returns a value representing an invalid (non-existent) node. + /// Returns a value representing an invalid (non-existent) node. static NodeId invalidNodeId() { return std::numeric_limits::max(); } - /// @brief Returns a value representing an invalid (non-existent) edge. + /// Returns a value representing an invalid (non-existent) edge. static EdgeId invalidEdgeId() { return std::numeric_limits::max(); } @@ -338,19 +338,19 @@ namespace PBQP { const NodeEntry &NE; }; - /// @brief Construct an empty PBQP graph. + /// Construct an empty PBQP graph. Graph() = default; - /// @brief Construct an empty PBQP graph with the given graph metadata. + /// Construct an empty PBQP graph with the given graph metadata. Graph(GraphMetadata Metadata) : Metadata(std::move(Metadata)) {} - /// @brief Get a reference to the graph metadata. + /// Get a reference to the graph metadata. GraphMetadata& getMetadata() { return Metadata; } - /// @brief Get a const-reference to the graph metadata. + /// Get a const-reference to the graph metadata. const GraphMetadata& getMetadata() const { return Metadata; } - /// @brief Lock this graph to the given solver instance in preparation + /// Lock this graph to the given solver instance in preparation /// for running the solver. This method will call solver.handleAddNode for /// each node in the graph, and handleAddEdge for each edge, to give the /// solver an opportunity to set up any requried metadata. @@ -363,13 +363,13 @@ namespace PBQP { Solver->handleAddEdge(EId); } - /// @brief Release from solver instance. + /// Release from solver instance. void unsetSolver() { assert(Solver && "Solver not set."); Solver = nullptr; } - /// @brief Add a node with the given costs. + /// Add a node with the given costs. /// @param Costs Cost vector for the new node. /// @return Node iterator for the added node. template @@ -382,7 +382,7 @@ namespace PBQP { return NId; } - /// @brief Add a node bypassing the cost allocator. + /// Add a node bypassing the cost allocator. /// @param Costs Cost vector ptr for the new node (must be convertible to /// VectorPtr). /// @return Node iterator for the added node. @@ -401,7 +401,7 @@ namespace PBQP { return NId; } - /// @brief Add an edge between the given nodes with the given costs. + /// Add an edge between the given nodes with the given costs. /// @param N1Id First node. /// @param N2Id Second node. /// @param Costs Cost matrix for new edge. @@ -419,7 +419,7 @@ namespace PBQP { return EId; } - /// @brief Add an edge bypassing the cost allocator. + /// Add an edge bypassing the cost allocator. /// @param N1Id First node. /// @param N2Id Second node. /// @param Costs Cost matrix for new edge. @@ -444,7 +444,7 @@ namespace PBQP { return EId; } - /// @brief Returns true if the graph is empty. + /// Returns true if the graph is empty. bool empty() const { return NodeIdSet(*this).empty(); } NodeIdSet nodeIds() const { return NodeIdSet(*this); } @@ -452,15 +452,15 @@ namespace PBQP { AdjEdgeIdSet adjEdgeIds(NodeId NId) { return AdjEdgeIdSet(getNode(NId)); } - /// @brief Get the number of nodes in the graph. + /// Get the number of nodes in the graph. /// @return Number of nodes in the graph. unsigned getNumNodes() const { return NodeIdSet(*this).size(); } - /// @brief Get the number of edges in the graph. + /// Get the number of edges in the graph. /// @return Number of edges in the graph. unsigned getNumEdges() const { return EdgeIdSet(*this).size(); } - /// @brief Set a node's cost vector. + /// Set a node's cost vector. /// @param NId Node to update. /// @param Costs New costs to set. template @@ -471,7 +471,7 @@ namespace PBQP { getNode(NId).Costs = AllocatedCosts; } - /// @brief Get a VectorPtr to a node's cost vector. Rarely useful - use + /// Get a VectorPtr to a node's cost vector. Rarely useful - use /// getNodeCosts where possible. /// @param NId Node id. /// @return VectorPtr to node cost vector. @@ -483,7 +483,7 @@ namespace PBQP { return getNode(NId).Costs; } - /// @brief Get a node's cost vector. + /// Get a node's cost vector. /// @param NId Node id. /// @return Node cost vector. const Vector& getNodeCosts(NodeId NId) const { @@ -502,7 +502,7 @@ namespace PBQP { return getNode(NId).getAdjEdgeIds().size(); } - /// @brief Update an edge's cost matrix. + /// Update an edge's cost matrix. /// @param EId Edge id. /// @param Costs New cost matrix. template @@ -513,7 +513,7 @@ namespace PBQP { getEdge(EId).Costs = AllocatedCosts; } - /// @brief Get a MatrixPtr to a node's cost matrix. Rarely useful - use + /// Get a MatrixPtr to a node's cost matrix. Rarely useful - use /// getEdgeCosts where possible. /// @param EId Edge id. /// @return MatrixPtr to edge cost matrix. @@ -525,7 +525,7 @@ namespace PBQP { return getEdge(EId).Costs; } - /// @brief Get an edge's cost matrix. + /// Get an edge's cost matrix. /// @param EId Edge id. /// @return Edge cost matrix. const Matrix& getEdgeCosts(EdgeId EId) const { @@ -540,21 +540,21 @@ namespace PBQP { return getEdge(EId).Metadata; } - /// @brief Get the first node connected to this edge. + /// Get the first node connected to this edge. /// @param EId Edge id. /// @return The first node connected to the given edge. NodeId getEdgeNode1Id(EdgeId EId) const { return getEdge(EId).getN1Id(); } - /// @brief Get the second node connected to this edge. + /// Get the second node connected to this edge. /// @param EId Edge id. /// @return The second node connected to the given edge. NodeId getEdgeNode2Id(EdgeId EId) const { return getEdge(EId).getN2Id(); } - /// @brief Get the "other" node connected to this edge. + /// Get the "other" node connected to this edge. /// @param EId Edge id. /// @param NId Node id for the "given" node. /// @return The iterator for the "other" node connected to this edge. @@ -566,7 +566,7 @@ namespace PBQP { return E.getN1Id(); } - /// @brief Get the edge connecting two nodes. + /// Get the edge connecting two nodes. /// @param N1Id First node id. /// @param N2Id Second node id. /// @return An id for edge (N1Id, N2Id) if such an edge exists, @@ -581,7 +581,7 @@ namespace PBQP { return invalidEdgeId(); } - /// @brief Remove a node from the graph. + /// Remove a node from the graph. /// @param NId Node id. void removeNode(NodeId NId) { if (Solver) @@ -598,7 +598,7 @@ namespace PBQP { FreeNodeIds.push_back(NId); } - /// @brief Disconnect an edge from the given node. + /// Disconnect an edge from the given node. /// /// Removes the given edge from the adjacency list of the given node. /// This operation leaves the edge in an 'asymmetric' state: It will no @@ -631,14 +631,14 @@ namespace PBQP { E.disconnectFrom(*this, NId); } - /// @brief Convenience method to disconnect all neighbours from the given + /// Convenience method to disconnect all neighbours from the given /// node. void disconnectAllNeighborsFromNode(NodeId NId) { for (auto AEId : adjEdgeIds(NId)) disconnectEdge(AEId, getEdgeOtherNodeId(AEId, NId)); } - /// @brief Re-attach an edge to its nodes. + /// Re-attach an edge to its nodes. /// /// Adds an edge that had been previously disconnected back into the /// adjacency set of the nodes that the edge connects. @@ -649,7 +649,7 @@ namespace PBQP { Solver->handleReconnectEdge(EId, NId); } - /// @brief Remove an edge from the graph. + /// Remove an edge from the graph. /// @param EId Edge id. void removeEdge(EdgeId EId) { if (Solver) @@ -660,7 +660,7 @@ namespace PBQP { Edges[EId].invalidate(); } - /// @brief Remove all nodes and edges from the graph. + /// Remove all nodes and edges from the graph. void clear() { Nodes.clear(); FreeNodeIds.clear(); diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h index ba405e816d1076438e9f226a542516f7fa835750..d1432a3053c4369c764f4771c997460dcf04f636 100644 --- a/include/llvm/CodeGen/PBQP/Math.h +++ b/include/llvm/CodeGen/PBQP/Math.h @@ -22,34 +22,34 @@ namespace PBQP { using PBQPNum = float; -/// \brief PBQP Vector class. +/// PBQP Vector class. class Vector { friend hash_code hash_value(const Vector &); public: - /// \brief Construct a PBQP vector of the given size. + /// Construct a PBQP vector of the given size. explicit Vector(unsigned Length) : Length(Length), Data(llvm::make_unique(Length)) {} - /// \brief Construct a PBQP vector with initializer. + /// Construct a PBQP vector with initializer. Vector(unsigned Length, PBQPNum InitVal) : Length(Length), Data(llvm::make_unique(Length)) { std::fill(Data.get(), Data.get() + Length, InitVal); } - /// \brief Copy construct a PBQP vector. + /// Copy construct a PBQP vector. Vector(const Vector &V) : Length(V.Length), Data(llvm::make_unique(Length)) { std::copy(V.Data.get(), V.Data.get() + Length, Data.get()); } - /// \brief Move construct a PBQP vector. + /// Move construct a PBQP vector. Vector(Vector &&V) : Length(V.Length), Data(std::move(V.Data)) { V.Length = 0; } - /// \brief Comparison operator. + /// Comparison operator. bool operator==(const Vector &V) const { assert(Length != 0 && Data && "Invalid vector"); if (Length != V.Length) @@ -57,27 +57,27 @@ public: return std::equal(Data.get(), Data.get() + Length, V.Data.get()); } - /// \brief Return the length of the vector + /// Return the length of the vector unsigned getLength() const { assert(Length != 0 && Data && "Invalid vector"); return Length; } - /// \brief Element access. + /// Element access. PBQPNum& operator[](unsigned Index) { assert(Length != 0 && Data && "Invalid vector"); assert(Index < Length && "Vector element access out of bounds."); return Data[Index]; } - /// \brief Const element access. + /// Const element access. const PBQPNum& operator[](unsigned Index) const { assert(Length != 0 && Data && "Invalid vector"); assert(Index < Length && "Vector element access out of bounds."); return Data[Index]; } - /// \brief Add another vector to this one. + /// Add another vector to this one. Vector& operator+=(const Vector &V) { assert(Length != 0 && Data && "Invalid vector"); assert(Length == V.Length && "Vector length mismatch."); @@ -86,7 +86,7 @@ public: return *this; } - /// \brief Returns the index of the minimum value in this vector + /// Returns the index of the minimum value in this vector unsigned minIndex() const { assert(Length != 0 && Data && "Invalid vector"); return std::min_element(Data.get(), Data.get() + Length) - Data.get(); @@ -97,14 +97,14 @@ private: std::unique_ptr Data; }; -/// \brief Return a hash_value for the given vector. +/// Return a hash_value for the given vector. inline hash_code hash_value(const Vector &V) { unsigned *VBegin = reinterpret_cast(V.Data.get()); unsigned *VEnd = reinterpret_cast(V.Data.get() + V.Length); return hash_combine(V.Length, hash_combine_range(VBegin, VEnd)); } -/// \brief Output a textual representation of the given vector on the given +/// Output a textual representation of the given vector on the given /// output stream. template OStream& operator<<(OStream &OS, const Vector &V) { @@ -118,18 +118,18 @@ OStream& operator<<(OStream &OS, const Vector &V) { return OS; } -/// \brief PBQP Matrix class +/// PBQP Matrix class class Matrix { private: friend hash_code hash_value(const Matrix &); public: - /// \brief Construct a PBQP Matrix with the given dimensions. + /// Construct a PBQP Matrix with the given dimensions. Matrix(unsigned Rows, unsigned Cols) : Rows(Rows), Cols(Cols), Data(llvm::make_unique(Rows * Cols)) { } - /// \brief Construct a PBQP Matrix with the given dimensions and initial + /// Construct a PBQP Matrix with the given dimensions and initial /// value. Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal) : Rows(Rows), Cols(Cols), @@ -137,20 +137,20 @@ public: std::fill(Data.get(), Data.get() + (Rows * Cols), InitVal); } - /// \brief Copy construct a PBQP matrix. + /// Copy construct a PBQP matrix. Matrix(const Matrix &M) : Rows(M.Rows), Cols(M.Cols), Data(llvm::make_unique(Rows * Cols)) { std::copy(M.Data.get(), M.Data.get() + (Rows * Cols), Data.get()); } - /// \brief Move construct a PBQP matrix. + /// Move construct a PBQP matrix. Matrix(Matrix &&M) : Rows(M.Rows), Cols(M.Cols), Data(std::move(M.Data)) { M.Rows = M.Cols = 0; } - /// \brief Comparison operator. + /// Comparison operator. bool operator==(const Matrix &M) const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); if (Rows != M.Rows || Cols != M.Cols) @@ -158,33 +158,33 @@ public: return std::equal(Data.get(), Data.get() + (Rows * Cols), M.Data.get()); } - /// \brief Return the number of rows in this matrix. + /// Return the number of rows in this matrix. unsigned getRows() const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); return Rows; } - /// \brief Return the number of cols in this matrix. + /// Return the number of cols in this matrix. unsigned getCols() const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); return Cols; } - /// \brief Matrix element access. + /// Matrix element access. PBQPNum* operator[](unsigned R) { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); assert(R < Rows && "Row out of bounds."); return Data.get() + (R * Cols); } - /// \brief Matrix element access. + /// Matrix element access. const PBQPNum* operator[](unsigned R) const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); assert(R < Rows && "Row out of bounds."); return Data.get() + (R * Cols); } - /// \brief Returns the given row as a vector. + /// Returns the given row as a vector. Vector getRowAsVector(unsigned R) const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); Vector V(Cols); @@ -193,7 +193,7 @@ public: return V; } - /// \brief Returns the given column as a vector. + /// Returns the given column as a vector. Vector getColAsVector(unsigned C) const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); Vector V(Rows); @@ -202,7 +202,7 @@ public: return V; } - /// \brief Matrix transpose. + /// Matrix transpose. Matrix transpose() const { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); Matrix M(Cols, Rows); @@ -212,7 +212,7 @@ public: return M; } - /// \brief Add the given matrix to this one. + /// Add the given matrix to this one. Matrix& operator+=(const Matrix &M) { assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix"); assert(Rows == M.Rows && Cols == M.Cols && @@ -234,7 +234,7 @@ private: std::unique_ptr Data; }; -/// \brief Return a hash_code for the given matrix. +/// Return a hash_code for the given matrix. inline hash_code hash_value(const Matrix &M) { unsigned *MBegin = reinterpret_cast(M.Data.get()); unsigned *MEnd = @@ -242,7 +242,7 @@ inline hash_code hash_value(const Matrix &M) { return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd)); } -/// \brief Output a textual representation of the given matrix on the given +/// Output a textual representation of the given matrix on the given /// output stream. template OStream& operator<<(OStream &OS, const Matrix &M) { diff --git a/include/llvm/CodeGen/PBQP/ReductionRules.h b/include/llvm/CodeGen/PBQP/ReductionRules.h index 8aeb5193676084137c376426eb8e42c57ef7fb28..21b99027970da085123e13d66aa4b2e1cf9f600e 100644 --- a/include/llvm/CodeGen/PBQP/ReductionRules.h +++ b/include/llvm/CodeGen/PBQP/ReductionRules.h @@ -23,7 +23,7 @@ namespace llvm { namespace PBQP { - /// \brief Reduce a node of degree one. + /// Reduce a node of degree one. /// /// Propagate costs from the given node, which must be of degree one, to its /// neighbor. Notify the problem domain. @@ -166,7 +166,7 @@ namespace PBQP { } #endif - // \brief Find a solution to a fully reduced graph by backpropagation. + // Find a solution to a fully reduced graph by backpropagation. // // Given a graph and a reduction order, pop each node from the reduction // order and greedily compute a minimum solution based on the node costs, and diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h index 6a247277fdfab67d420f13de7e11aab77fa5c5ef..4d4379fbc2c2178d83eead0d091d71df28527ce1 100644 --- a/include/llvm/CodeGen/PBQP/Solution.h +++ b/include/llvm/CodeGen/PBQP/Solution.h @@ -21,7 +21,7 @@ namespace llvm { namespace PBQP { - /// \brief Represents a solution to a PBQP problem. + /// Represents a solution to a PBQP problem. /// /// To get the selection for each node in the problem use the getSelection method. class Solution { @@ -30,17 +30,17 @@ namespace PBQP { SelectionsMap selections; public: - /// \brief Initialise an empty solution. + /// Initialise an empty solution. Solution() = default; - /// \brief Set the selection for a given node. + /// Set the selection for a given node. /// @param nodeId Node id. /// @param selection Selection for nodeId. void setSelection(GraphBase::NodeId nodeId, unsigned selection) { selections[nodeId] = selection; } - /// \brief Get a node's selection. + /// Get a node's selection. /// @param nodeId Node id. /// @return The selection for nodeId; unsigned getSelection(GraphBase::NodeId nodeId) const { diff --git a/include/llvm/CodeGen/PBQPRAConstraint.h b/include/llvm/CodeGen/PBQPRAConstraint.h index 269b7a7b3a35d5cae61f651a7c5258628beccd72..995467dc56d8672711c059eb9fc0c4315970b06a 100644 --- a/include/llvm/CodeGen/PBQPRAConstraint.h +++ b/include/llvm/CodeGen/PBQPRAConstraint.h @@ -33,7 +33,7 @@ class PBQPRAGraph; using PBQPRAGraph = PBQP::RegAlloc::PBQPRAGraph; -/// @brief Abstract base for classes implementing PBQP register allocation +/// Abstract base for classes implementing PBQP register allocation /// constraints (e.g. Spill-costs, interference, coalescing). class PBQPRAConstraint { public: @@ -44,7 +44,7 @@ private: virtual void anchor(); }; -/// @brief PBQP register allocation constraint composer. +/// PBQP register allocation constraint composer. /// /// Constraints added to this list will be applied, in the order that they are /// added, to the PBQP graph. diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 68fd04b292ef227c8284ac08c23a87a9b5f280d4..52fc147572fa8a61eea6c402af5bc6242c2728e9 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -301,7 +301,7 @@ namespace llvm { /// StackSlotColoring - This pass performs stack slot coloring. extern char &StackSlotColoringID; - /// \brief This pass lays out funclets contiguously. + /// This pass lays out funclets contiguously. extern char &FuncletLayoutID; /// This pass inserts the XRay instrumentation sleds if they are supported by @@ -311,7 +311,7 @@ namespace llvm { /// This pass inserts FEntry calls extern char &FEntryInserterID; - /// \brief This pass implements the "patchable-function" attribute. + /// This pass implements the "patchable-function" attribute. extern char &PatchableFunctionID; /// createStackProtectorPass - This pass adds stack protectors to functions. @@ -329,13 +329,17 @@ namespace llvm { /// createWinEHPass - Prepares personality functions used by MSVC on Windows, /// in addition to the Itanium LSDA based personalities. - FunctionPass *createWinEHPass(); + FunctionPass *createWinEHPass(bool DemoteCatchSwitchPHIOnly = false); /// createSjLjEHPreparePass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. /// FunctionPass *createSjLjEHPreparePass(); + /// createWasmEHPass - This pass adapts exception handling code to use + /// WebAssembly's exception handling scheme. + FunctionPass *createWasmEHPass(); + /// LocalStackSlotAllocation - This pass assigns local frame indices to stack /// slots relative to one another and allocates base registers to access them /// when it is estimated by the target to be out of range of normal frame @@ -380,7 +384,7 @@ namespace llvm { /// ModulePass *createLowerEmuTLSPass(); - /// This pass lowers the @llvm.load.relative intrinsic to instructions. + /// This pass lowers the \@llvm.load.relative intrinsic to instructions. /// This is unsafe to do earlier because a pass may combine the constant /// initializer into the load, which may result in an overflowing evaluation. ModulePass *createPreISelIntrinsicLoweringPass(); @@ -419,7 +423,7 @@ namespace llvm { /// This pass performs outlining on machine instructions directly before /// printing assembly. - ModulePass *createMachineOutlinerPass(bool OutlineFromLinkOnceODRs = false); + ModulePass *createMachineOutlinerPass(); /// This pass expands the experimental reduction intrinsics into sequences of /// shuffles. @@ -434,6 +438,9 @@ namespace llvm { // This pass expands indirectbr instructions. FunctionPass *createIndirectBrExpandPass(); + /// Creates CFI Instruction Inserter pass. \see CFIInstrInserter.cpp + FunctionPass *createCFIInstrInserter(); + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index 5b342863eb50de45ab445c61767298aaa0f4dbf1..ba9763077d09b044f6e453cdb4dce652e1cae8c8 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -43,10 +43,10 @@ class raw_ostream; namespace PBQP { namespace RegAlloc { -/// @brief Spill option index. +/// Spill option index. inline unsigned getSpillOptionIdx() { return 0; } -/// \brief Metadata to speed allocatability test. +/// Metadata to speed allocatability test. /// /// Keeps track of the number of infinities in each row and column. class MatrixMetadata { @@ -89,7 +89,7 @@ private: std::unique_ptr UnsafeCols; }; -/// \brief Holds a vector of the allowed physical regs for a vreg. +/// Holds a vector of the allowed physical regs for a vreg. class AllowedRegVector { friend hash_code hash_value(const AllowedRegVector &); @@ -127,7 +127,7 @@ inline hash_code hash_value(const AllowedRegVector &OptRegs) { hash_combine_range(OStart, OEnd)); } -/// \brief Holds graph-level metadata relevant to PBQP RA problems. +/// Holds graph-level metadata relevant to PBQP RA problems. class GraphMetadata { private: using AllowedRegVecPool = ValuePool; @@ -164,7 +164,7 @@ private: AllowedRegVecPool AllowedRegVecs; }; -/// \brief Holds solver state and other metadata relevant to each PBQP RA node. +/// Holds solver state and other metadata relevant to each PBQP RA node. class NodeMetadata { public: using AllowedRegVector = RegAlloc::AllowedRegVector; @@ -505,14 +505,14 @@ private: public: PBQPRAGraph(GraphMetadata Metadata) : BaseT(std::move(Metadata)) {} - /// @brief Dump this graph to dbgs(). + /// Dump this graph to dbgs(). void dump() const; - /// @brief Dump this graph to an output stream. + /// Dump this graph to an output stream. /// @param OS Output stream to print on. void dump(raw_ostream &OS) const; - /// @brief Print a representation of this graph in DOT format. + /// Print a representation of this graph in DOT format. /// @param OS Output stream to print on. void printDot(raw_ostream &OS) const; }; @@ -527,7 +527,7 @@ inline Solution solve(PBQPRAGraph& G) { } // end namespace RegAlloc } // end namespace PBQP -/// @brief Create a PBQP register allocator instance. +/// Create a PBQP register allocator instance. FunctionPass * createPBQPRegisterAllocator(char *customPassID = nullptr); diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h index 2b14b78d621d780e730c806db7f20bf9a02d1598..79054b9e33b783cbf1fe2896c6c25ea36f5752e6 100644 --- a/include/llvm/CodeGen/RegisterPressure.h +++ b/include/llvm/CodeGen/RegisterPressure.h @@ -171,10 +171,10 @@ class RegisterOperands { public: /// List of virtual registers and register units read by the instruction. SmallVector Uses; - /// \brief List of virtual registers and register units defined by the + /// List of virtual registers and register units defined by the /// instruction which are not dead. SmallVector Defs; - /// \brief List of virtual registers and register units defined by the + /// List of virtual registers and register units defined by the /// instruction but dead. SmallVector DeadDefs; @@ -219,7 +219,7 @@ public: return const_cast(this)->operator[](Idx); } - /// \brief Record pressure difference induced by the given operand list to + /// Record pressure difference induced by the given operand list to /// node with index \p Idx. void addInstruction(unsigned Idx, const RegisterOperands &RegOpers, const MachineRegisterInfo &MRI); @@ -546,7 +546,7 @@ protected: /// Add Reg to the live in set and increase max pressure. void discoverLiveIn(RegisterMaskPair Pair); - /// \brief Get the SlotIndex for the first nondebug instruction including or + /// Get the SlotIndex for the first nondebug instruction including or /// after the current position. SlotIndex getCurrSlot() const; diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index f3f2f05b877da7b3b378ed74546ece99acbfebdb..6e3ba5c83667c4355dc379d68f9094ba50f695de 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -76,7 +76,7 @@ class TargetRegisterInfo; }; private: - /// \brief A pointer to the depending/depended-on SUnit, and an enum + /// A pointer to the depending/depended-on SUnit, and an enum /// indicating the kind of the dependency. PointerIntPair Dep; @@ -137,7 +137,7 @@ class TargetRegisterInfo; return !operator==(Other); } - /// \brief Returns the latency value for this edge, which roughly means the + /// Returns the latency value for this edge, which roughly means the /// minimum number of cycles that must elapse between the predecessor and /// the successor, given that they have this edge between them. unsigned getLatency() const { @@ -163,7 +163,7 @@ class TargetRegisterInfo; return getKind() != Data; } - /// \brief Tests if this is an Order dependence between two memory accesses + /// Tests if this is an Order dependence between two memory accesses /// where both sides of the dependence access memory in non-volatile and /// fully modeled ways. bool isNormalMemory() const { @@ -181,7 +181,7 @@ class TargetRegisterInfo; return (isNormalMemory() || isBarrier()); } - /// \brief Tests if this is an Order dependence that is marked as + /// Tests if this is an Order dependence that is marked as /// "must alias", meaning that the SUnits at either end of the edge have a /// memory dependence on a known memory location. bool isMustAlias() const { @@ -196,13 +196,13 @@ class TargetRegisterInfo; return getKind() == Order && Contents.OrdKind >= Weak; } - /// \brief Tests if this is an Order dependence that is marked as + /// Tests if this is an Order dependence that is marked as /// "artificial", meaning it isn't necessary for correctness. bool isArtificial() const { return getKind() == Order && Contents.OrdKind == Artificial; } - /// \brief Tests if this is an Order dependence that is marked as "cluster", + /// Tests if this is an Order dependence that is marked as "cluster", /// meaning it is artificial and wants to be adjacent. bool isCluster() const { return getKind() == Order && Contents.OrdKind == Cluster; @@ -308,7 +308,7 @@ class TargetRegisterInfo; nullptr; ///< Is a special copy node if != nullptr. const TargetRegisterClass *CopySrcRC = nullptr; - /// \brief Constructs an SUnit for pre-regalloc scheduling to represent an + /// Constructs an SUnit for pre-regalloc scheduling to represent an /// SDNode and any nodes flagged to it. SUnit(SDNode *node, unsigned nodenum) : Node(node), NodeNum(nodenum), isVRegCycle(false), isCall(false), @@ -319,7 +319,7 @@ class TargetRegisterInfo; isUnbuffered(false), hasReservedResource(false), isDepthCurrent(false), isHeightCurrent(false) {} - /// \brief Constructs an SUnit for post-regalloc scheduling to represent a + /// Constructs an SUnit for post-regalloc scheduling to represent a /// MachineInstr. SUnit(MachineInstr *instr, unsigned nodenum) : Instr(instr), NodeNum(nodenum), isVRegCycle(false), isCall(false), @@ -330,7 +330,7 @@ class TargetRegisterInfo; isUnbuffered(false), hasReservedResource(false), isDepthCurrent(false), isHeightCurrent(false) {} - /// \brief Constructs a placeholder SUnit. + /// Constructs a placeholder SUnit. SUnit() : isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), hasPhysRegDefs(false), @@ -339,7 +339,7 @@ class TargetRegisterInfo; isCloned(false), isUnbuffered(false), hasReservedResource(false), isDepthCurrent(false), isHeightCurrent(false) {} - /// \brief Boundary nodes are placeholders for the boundary of the + /// Boundary nodes are placeholders for the boundary of the /// scheduling region. /// /// BoundaryNodes can have DAG edges, including Data edges, but they do not @@ -362,7 +362,7 @@ class TargetRegisterInfo; return Node; } - /// \brief Returns true if this SUnit refers to a machine instruction as + /// Returns true if this SUnit refers to a machine instruction as /// opposed to an SDNode. bool isInstr() const { return Instr; } @@ -384,7 +384,7 @@ class TargetRegisterInfo; /// It also adds the current node as a successor of the specified node. bool addPred(const SDep &D, bool Required = true); - /// \brief Adds a barrier edge to SU by calling addPred(), with latency 0 + /// Adds a barrier edge to SU by calling addPred(), with latency 0 /// generally or latency 1 for a store followed by a load. bool addPredBarrier(SUnit *SU) { SDep Dep(SU, SDep::Barrier); @@ -406,7 +406,7 @@ class TargetRegisterInfo; return Depth; } - /// \brief Returns the height of this node, which is the length of the + /// Returns the height of this node, which is the length of the /// maximum path down to any node which has no successors. unsigned getHeight() const { if (!isHeightCurrent) @@ -414,21 +414,21 @@ class TargetRegisterInfo; return Height; } - /// \brief If NewDepth is greater than this node's depth value, sets it to + /// If NewDepth is greater than this node's depth value, sets it to /// be the new depth value. This also recursively marks successor nodes /// dirty. void setDepthToAtLeast(unsigned NewDepth); - /// \brief If NewDepth is greater than this node's depth value, set it to be + /// If NewDepth is greater than this node's depth value, set it to be /// the new height value. This also recursively marks predecessor nodes /// dirty. void setHeightToAtLeast(unsigned NewHeight); - /// \brief Sets a flag in this node to indicate that its stored Depth value + /// Sets a flag in this node to indicate that its stored Depth value /// will require recomputation the next time getDepth() is called. void setDepthDirty(); - /// \brief Sets a flag in this node to indicate that its stored Height value + /// Sets a flag in this node to indicate that its stored Height value /// will require recomputation the next time getHeight() is called. void setHeightDirty(); @@ -455,7 +455,7 @@ class TargetRegisterInfo; return NumSuccsLeft == 0; } - /// \brief Orders this node's predecessor edges such that the critical path + /// Orders this node's predecessor edges such that the critical path /// edge occurs first. void biasCriticalPath(); @@ -497,7 +497,7 @@ class TargetRegisterInfo; //===--------------------------------------------------------------------===// - /// \brief This interface is used to plug different priorities computation + /// This interface is used to plug different priorities computation /// algorithms into the list scheduler. It implements the interface of a /// standard priority queue, where nodes are inserted in arbitrary order and /// returned in priority order. The computation of the priority and the @@ -609,7 +609,7 @@ class TargetRegisterInfo; virtual void addCustomGraphFeatures(GraphWriter &) const {} #ifndef NDEBUG - /// \brief Verifies that all SUnits were scheduled and that their state is + /// Verifies that all SUnits were scheduled and that their state is /// consistent. Returns the number of scheduled SUnits. unsigned VerifyScheduledDAG(bool isBottomUp); #endif @@ -708,7 +708,7 @@ class TargetRegisterInfo; /// method. void DFS(const SUnit *SU, int UpperBound, bool& HasLoop); - /// \brief Reassigns topological indexes for the nodes in the DAG to + /// Reassigns topological indexes for the nodes in the DAG to /// preserve the topological ordering. void Shift(BitVector& Visited, int LowerBound, int UpperBound); @@ -735,11 +735,11 @@ class TargetRegisterInfo; /// Returns true if addPred(TargetSU, SU) creates a cycle. bool WillCreateCycle(SUnit *TargetSU, SUnit *SU); - /// \brief Updates the topological ordering to accommodate an edge to be + /// Updates the topological ordering to accommodate an edge to be /// added from SUnit \p X to SUnit \p Y. void AddPred(SUnit *Y, SUnit *X); - /// \brief Updates the topological ordering to accommodate an an edge to be + /// Updates the topological ordering to accommodate an an edge to be /// removed from the specified node \p N from the predecessors of the /// current node \p M. void RemovePred(SUnit *M, SUnit *N); diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index 14882205584e2582e7d0b3bc770e98c6637c34f5..520a23846f6e8c00691e7ed7e0b4ab1f2c633a52 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -190,7 +190,7 @@ namespace llvm { using SUList = std::list; protected: - /// \brief A map from ValueType to SUList, used during DAG construction, as + /// A map from ValueType to SUList, used during DAG construction, as /// a means of remembering which SUs depend on which memory locations. class Value2SUsMap; @@ -201,7 +201,7 @@ namespace llvm { void reduceHugeMemNodeMaps(Value2SUsMap &stores, Value2SUsMap &loads, unsigned N); - /// \brief Adds a chain edge between SUa and SUb, but only if both + /// Adds a chain edge between SUa and SUb, but only if both /// AliasAnalysis and Target fail to deny the dependency. void addChainDependency(SUnit *SUa, SUnit *SUb, unsigned Latency = 0); @@ -286,7 +286,7 @@ namespace llvm { /// Cleans up after scheduling in the given block. virtual void finishBlock(); - /// \brief Initialize the DAG and common scheduler state for a new + /// Initialize the DAG and common scheduler state for a new /// scheduling region. This does not actually create the DAG, only clears /// it. The scheduling driver may call BuildSchedGraph multiple times per /// scheduling region. @@ -308,7 +308,7 @@ namespace llvm { LiveIntervals *LIS = nullptr, bool TrackLaneMasks = false); - /// \brief Adds dependencies from instructions in the current list of + /// Adds dependencies from instructions in the current list of /// instructions being scheduled to scheduling barrier. We want to make sure /// instructions which define registers that are either used by the /// terminator or are live-out are properly scheduled. This is especially diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h index d6a8c791392cadd320c77636fcc2ee824da71a67..3ecc033ac35a8e6079fe2382e4acf1bf74c80915 100644 --- a/include/llvm/CodeGen/ScheduleDFS.h +++ b/include/llvm/CodeGen/ScheduleDFS.h @@ -25,7 +25,7 @@ namespace llvm { class raw_ostream; -/// \brief Represent the ILP of the subDAG rooted at a DAG node. +/// Represent the ILP of the subDAG rooted at a DAG node. /// /// ILPValues summarize the DAG subtree rooted at each node. ILPValues are /// valid for all nodes regardless of their subtree membership. @@ -62,13 +62,13 @@ struct ILPValue { void dump() const; }; -/// \brief Compute the values of each DAG node for various metrics during DFS. +/// Compute the values of each DAG node for various metrics during DFS. class SchedDFSResult { friend class SchedDFSImpl; static const unsigned InvalidSubtreeID = ~0u; - /// \brief Per-SUnit data computed during DFS for various metrics. + /// Per-SUnit data computed during DFS for various metrics. /// /// A node's SubtreeID is set to itself when it is visited to indicate that it /// is the root of a subtree. Later it is set to its parent to indicate an @@ -81,7 +81,7 @@ class SchedDFSResult { NodeData() = default; }; - /// \brief Per-Subtree data computed during DFS. + /// Per-Subtree data computed during DFS. struct TreeData { unsigned ParentTreeID = InvalidSubtreeID; unsigned SubInstrCount = 0; @@ -89,7 +89,7 @@ class SchedDFSResult { TreeData() = default; }; - /// \brief Record a connection between subtrees and the connection level. + /// Record a connection between subtrees and the connection level. struct Connection { unsigned TreeID; unsigned Level; @@ -117,15 +117,15 @@ public: SchedDFSResult(bool IsBU, unsigned lim) : IsBottomUp(IsBU), SubtreeLimit(lim) {} - /// \brief Get the node cutoff before subtrees are considered significant. + /// Get the node cutoff before subtrees are considered significant. unsigned getSubtreeLimit() const { return SubtreeLimit; } - /// \brief Return true if this DFSResult is uninitialized. + /// Return true if this DFSResult is uninitialized. /// /// resize() initializes DFSResult, while compute() populates it. bool empty() const { return DFSNodeData.empty(); } - /// \brief Clear the results. + /// Clear the results. void clear() { DFSNodeData.clear(); DFSTreeData.clear(); @@ -133,37 +133,37 @@ public: SubtreeConnectLevels.clear(); } - /// \brief Initialize the result data with the size of the DAG. + /// Initialize the result data with the size of the DAG. void resize(unsigned NumSUnits) { DFSNodeData.resize(NumSUnits); } - /// \brief Compute various metrics for the DAG with given roots. + /// Compute various metrics for the DAG with given roots. void compute(ArrayRef SUnits); - /// \brief Get the number of instructions in the given subtree and its + /// Get the number of instructions in the given subtree and its /// children. unsigned getNumInstrs(const SUnit *SU) const { return DFSNodeData[SU->NodeNum].InstrCount; } - /// \brief Get the number of instructions in the given subtree not including + /// Get the number of instructions in the given subtree not including /// children. unsigned getNumSubInstrs(unsigned SubtreeID) const { return DFSTreeData[SubtreeID].SubInstrCount; } - /// \brief Get the ILP value for a DAG node. + /// Get the ILP value for a DAG node. /// /// A leaf node has an ILP of 1/1. ILPValue getILP(const SUnit *SU) const { return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth()); } - /// \brief The number of subtrees detected in this DAG. + /// The number of subtrees detected in this DAG. unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); } - /// \brief Get the ID of the subtree the given DAG node belongs to. + /// Get the ID of the subtree the given DAG node belongs to. /// /// For convenience, if DFSResults have not been computed yet, give everything /// tree ID 0. @@ -174,7 +174,7 @@ public: return DFSNodeData[SU->NodeNum].SubtreeID; } - /// \brief Get the connection level of a subtree. + /// Get the connection level of a subtree. /// /// For bottom-up trees, the connection level is the latency depth (in cycles) /// of the deepest connection to another subtree. @@ -182,7 +182,7 @@ public: return SubtreeConnectLevels[SubtreeID]; } - /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is + /// Scheduler callback to update SubtreeConnectLevels when a tree is /// initially scheduled. void scheduleTree(unsigned SubtreeID); }; diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index af43c9b08340e59d806c3086e042486aee08a8ff..befb011777a96df407eeb8380f5514ba11ab30ec 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -73,6 +73,7 @@ class MachineConstantPoolValue; class MCSymbol; class OptimizationRemarkEmitter; class SDDbgValue; +class SDDbgLabel; class SelectionDAG; class SelectionDAGTargetInfo; class TargetLibraryInfo; @@ -148,6 +149,7 @@ class SDDbgInfo { BumpPtrAllocator Alloc; SmallVector DbgValues; SmallVector ByvalParmDbgValues; + SmallVector DbgLabels; using DbgValMapType = DenseMap>; DbgValMapType DbgValMap; @@ -164,7 +166,11 @@ public: DbgValMap[Node].push_back(V); } - /// \brief Invalidate all DbgValues attached to the node and remove + void add(SDDbgLabel *L) { + DbgLabels.push_back(L); + } + + /// Invalidate all DbgValues attached to the node and remove /// it from the Node-to-DbgValues map. void erase(const SDNode *Node); @@ -172,13 +178,14 @@ public: DbgValMap.clear(); DbgValues.clear(); ByvalParmDbgValues.clear(); + DbgLabels.clear(); Alloc.Reset(); } BumpPtrAllocator &getAlloc() { return Alloc; } bool empty() const { - return DbgValues.empty() && ByvalParmDbgValues.empty(); + return DbgValues.empty() && ByvalParmDbgValues.empty() && DbgLabels.empty(); } ArrayRef getSDDbgValues(const SDNode *Node) { @@ -189,11 +196,14 @@ public: } using DbgIterator = SmallVectorImpl::iterator; + using DbgLabelIterator = SmallVectorImpl::iterator; DbgIterator DbgBegin() { return DbgValues.begin(); } DbgIterator DbgEnd() { return DbgValues.end(); } DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); } DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); } + DbgLabelIterator DbgLabelBegin() { return DbgLabels.begin(); } + DbgLabelIterator DbgLabelEnd() { return DbgLabels.end(); } }; void checkForCycles(const SelectionDAG *DAG, bool force = false); @@ -255,7 +265,7 @@ class SelectionDAG { /// Pool allocation for misc. objects that are created once per SelectionDAG. BumpPtrAllocator Allocator; - /// Tracks dbg_value information through SDISel. + /// Tracks dbg_value and dbg_label information through SDISel. SDDbgInfo *DbgInfo; uint16_t NextPersistentId = 0; @@ -486,7 +496,7 @@ public: /// the graph. void Legalize(); - /// \brief Transforms a SelectionDAG node and any operands to it into a node + /// Transforms a SelectionDAG node and any operands to it into a node /// that is compatible with the target instruction selector, as indicated by /// the TargetLowering object. /// @@ -537,7 +547,7 @@ public: //===--------------------------------------------------------------------===// // Node creation methods. - /// \brief Create a ConstantSDNode wrapping a constant value. + /// Create a ConstantSDNode wrapping a constant value. /// If VT is a vector type, the constant is splatted into a BUILD_VECTOR. /// /// If only legal types can be produced, this does the necessary @@ -571,12 +581,12 @@ public: return getConstant(Val, DL, VT, true, isOpaque); } - /// \brief Create a true or false constant of type \p VT using the target's + /// Create a true or false constant of type \p VT using the target's /// BooleanContent for type \p OpVT. SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT); /// @} - /// \brief Create a ConstantFPSDNode wrapping a constant value. + /// Create a ConstantFPSDNode wrapping a constant value. /// If VT is a vector type, the constant is splatted into a BUILD_VECTOR. /// /// If only legal types can be produced, this does the necessary @@ -748,7 +758,7 @@ public: return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); } - /// \brief Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to + /// Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to /// the shuffle node in input but with swapped operands. /// /// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3> @@ -800,10 +810,10 @@ public: /// Create a bitwise NOT operation as (XOR Val, -1). SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT); - /// \brief Create a logical NOT operation as (XOR Val, BooleanOne). + /// Create a logical NOT operation as (XOR Val, BooleanOne). SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT); - /// \brief Create an add instruction with appropriate flags when used for + /// Create an add instruction with appropriate flags when used for /// addressing some offset of an object. i.e. if a load is split into multiple /// components, create an add nuw from the base pointer to the offset. SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Op, int64_t Offset) { @@ -917,6 +927,23 @@ public: SDValue Size, unsigned Align, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo); + SDValue getAtomicMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, + unsigned DstAlign, SDValue Src, unsigned SrcAlign, + SDValue Size, Type *SizeTy, unsigned ElemSz, + bool isTailCall, MachinePointerInfo DstPtrInfo, + MachinePointerInfo SrcPtrInfo); + + SDValue getAtomicMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst, + unsigned DstAlign, SDValue Src, unsigned SrcAlign, + SDValue Size, Type *SizeTy, unsigned ElemSz, + bool isTailCall, MachinePointerInfo DstPtrInfo, + MachinePointerInfo SrcPtrInfo); + + SDValue getAtomicMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, + unsigned DstAlign, SDValue Value, SDValue Size, + Type *SizeTy, unsigned ElemSz, bool isTailCall, + MachinePointerInfo DstPtrInfo); + /// Helper function to make it easier to build SetCC's if you just /// have an ISD::CondCode instead of an SDValue. /// @@ -1225,6 +1252,14 @@ public: unsigned FI, const DebugLoc &DL, unsigned O); + /// Creates a VReg SDDbgValue node. + SDDbgValue *getVRegDbgValue(DIVariable *Var, DIExpression *Expr, + unsigned VReg, bool IsIndirect, + const DebugLoc &DL, unsigned O); + + /// Creates a SDDbgLabel node. + SDDbgLabel *getDbgLabel(DILabel *Label, const DebugLoc &DL, unsigned O); + /// Transfer debug values from one node to another, while optionally /// generating fragment expressions for split-up values. If \p InvalidateDbg /// is set, debug values are invalidated after they are transferred. @@ -1306,6 +1341,9 @@ public: /// value is produced by SD. void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter); + /// Add a dbg_label SDNode. + void AddDbgLabel(SDDbgLabel *DB); + /// Get the debug values which reference the given SDNode. ArrayRef GetDbgValues(const SDNode* SD) { return DbgInfo->getSDDbgValues(SD); @@ -1327,6 +1365,13 @@ public: return DbgInfo->ByvalParmDbgEnd(); } + SDDbgInfo::DbgLabelIterator DbgLabelBegin() { + return DbgInfo->DbgLabelBegin(); + } + SDDbgInfo::DbgLabelIterator DbgLabelEnd() { + return DbgInfo->DbgLabelEnd(); + } + /// To be invoked on an SDNode that is slated to be erased. This /// function mirrors \c llvm::salvageDebugInfo. void salvageDebugInfo(SDNode &N); diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index e56eafc437c5e546b35342ef8da7dd45b1ce4658..97a46192ba01b1a189e552ab7ea7d7e17f993f8d 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -280,7 +280,7 @@ public: void SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, unsigned TableSize); - /// \brief Return true if complex patterns for this target can mutate the + /// Return true if complex patterns for this target can mutate the /// DAG. virtual bool ComplexPatternFuncMutatesDAG() const { return false; @@ -309,10 +309,10 @@ private: /// instruction selected, false if no code should be emitted for it. bool PrepareEHLandingPad(); - /// \brief Perform instruction selection on all basic blocks in the function. + /// Perform instruction selection on all basic blocks in the function. void SelectAllBasicBlocks(const Function &Fn); - /// \brief Perform instruction selection on a single basic block, for + /// Perform instruction selection on a single basic block, for /// instructions between \p Begin and \p End. \p HadTailCall will be set /// to true if a call in the block was translated as a tail call. void SelectBasicBlock(BasicBlock::const_iterator Begin, @@ -322,7 +322,7 @@ private: void CodeGenAndEmitDAG(); - /// \brief Generate instructions for lowering the incoming arguments of the + /// Generate instructions for lowering the incoming arguments of the /// given function. void LowerArguments(const Function &F); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index ffb5c0057bbf1b74fbf79231d92bd836ad01e8a0..b1f8b8c02babb75a112c62116f1cb99364e80817 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -37,6 +37,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" @@ -359,21 +360,34 @@ private: bool NoUnsignedWrap : 1; bool NoSignedWrap : 1; bool Exact : 1; - bool UnsafeAlgebra : 1; bool NoNaNs : 1; bool NoInfs : 1; bool NoSignedZeros : 1; bool AllowReciprocal : 1; bool VectorReduction : 1; bool AllowContract : 1; + bool ApproximateFuncs : 1; + bool AllowReassociation : 1; public: /// Default constructor turns off all optimization flags. SDNodeFlags() : AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false), - Exact(false), UnsafeAlgebra(false), NoNaNs(false), NoInfs(false), + Exact(false), NoNaNs(false), NoInfs(false), NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false), - AllowContract(false) {} + AllowContract(false), ApproximateFuncs(false), + AllowReassociation(false) {} + + /// Propagate the fast-math-flags from an IR FPMathOperator. + void copyFMF(const FPMathOperator &FPMO) { + setNoNaNs(FPMO.hasNoNaNs()); + setNoInfs(FPMO.hasNoInfs()); + setNoSignedZeros(FPMO.hasNoSignedZeros()); + setAllowReciprocal(FPMO.hasAllowReciprocal()); + setAllowContract(FPMO.hasAllowContract()); + setApproximateFuncs(FPMO.hasApproxFunc()); + setAllowReassociation(FPMO.hasAllowReassoc()); + } /// Sets the state of the flags to the defined state. void setDefined() { AnyDefined = true; } @@ -393,10 +407,6 @@ public: setDefined(); Exact = b; } - void setUnsafeAlgebra(bool b) { - setDefined(); - UnsafeAlgebra = b; - } void setNoNaNs(bool b) { setDefined(); NoNaNs = b; @@ -421,18 +431,32 @@ public: setDefined(); AllowContract = b; } + void setApproximateFuncs(bool b) { + setDefined(); + ApproximateFuncs = b; + } + void setAllowReassociation(bool b) { + setDefined(); + AllowReassociation = b; + } // These are accessors for each flag. bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } bool hasNoSignedWrap() const { return NoSignedWrap; } bool hasExact() const { return Exact; } - bool hasUnsafeAlgebra() const { return UnsafeAlgebra; } bool hasNoNaNs() const { return NoNaNs; } bool hasNoInfs() const { return NoInfs; } bool hasNoSignedZeros() const { return NoSignedZeros; } bool hasAllowReciprocal() const { return AllowReciprocal; } bool hasVectorReduction() const { return VectorReduction; } bool hasAllowContract() const { return AllowContract; } + bool hasApproximateFuncs() const { return ApproximateFuncs; } + bool hasAllowReassociation() const { return AllowReassociation; } + + bool isFast() const { + return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs && + AllowContract && ApproximateFuncs && AllowReassociation; + } /// Clear any flags in this flag set that aren't also set in Flags. /// If the given Flags are undefined then don't do anything. @@ -442,13 +466,14 @@ public: NoUnsignedWrap &= Flags.NoUnsignedWrap; NoSignedWrap &= Flags.NoSignedWrap; Exact &= Flags.Exact; - UnsafeAlgebra &= Flags.UnsafeAlgebra; NoNaNs &= Flags.NoNaNs; NoInfs &= Flags.NoInfs; NoSignedZeros &= Flags.NoSignedZeros; AllowReciprocal &= Flags.AllowReciprocal; VectorReduction &= Flags.VectorReduction; AllowContract &= Flags.AllowContract; + ApproximateFuncs &= Flags.ApproximateFuncs; + AllowReassociation &= Flags.AllowReassociation; } }; @@ -544,7 +569,7 @@ protected: static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide"); static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide"); static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide"); - static_assert(sizeof(LoadSDNodeBitfields) <= 4, "field too wide"); + static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide"); static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide"); private: @@ -923,6 +948,7 @@ public: const SDNodeFlags getFlags() const { return Flags; } void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; } + bool isFast() { return Flags.isFast(); } /// Clear any flags in this node that aren't also set in Flags. /// If Flags is not in a defined state then this has no effect. @@ -1765,13 +1791,13 @@ public: unsigned MinSplatBits = 0, bool isBigEndian = false) const; - /// \brief Returns the splatted value or a null value if this is not a splat. + /// Returns the splatted value or a null value if this is not a splat. /// /// If passed a non-null UndefElements bitvector, it will resize it to match /// the vector width and set the bits where elements are undef. SDValue getSplatValue(BitVector *UndefElements = nullptr) const; - /// \brief Returns the splatted constant or null if this is not a constant + /// Returns the splatted constant or null if this is not a constant /// splat. /// /// If passed a non-null UndefElements bitvector, it will resize it to match @@ -1779,7 +1805,7 @@ public: ConstantSDNode * getConstantSplatNode(BitVector *UndefElements = nullptr) const; - /// \brief Returns the splatted constant FP or null if this is not a constant + /// Returns the splatted constant FP or null if this is not a constant /// FP splat. /// /// If passed a non-null UndefElements bitvector, it will resize it to match @@ -1787,7 +1813,7 @@ public: ConstantFPSDNode * getConstantFPSplatNode(BitVector *UndefElements = nullptr) const; - /// \brief If this is a constant FP splat and the splatted constant FP is an + /// If this is a constant FP splat and the splatted constant FP is an /// exact power or 2, return the log base 2 integer value. Otherwise, /// return -1. /// diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 3a91e363f923156457d3961aa628c0bb75686b01..334267d9828bee30d548993e7472e41f724b4228 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -578,9 +578,9 @@ class raw_ostream; assert(!MI.isInsideBundle() && "Instructions inside bundles should use bundle start's slot."); assert(mi2iMap.find(&MI) == mi2iMap.end() && "Instr already indexed."); - // Numbering DBG_VALUE instructions could cause code generation to be + // Numbering debug instructions could cause code generation to be // affected by debug information. - assert(!MI.isDebugValue() && "Cannot number DBG_VALUE instructions."); + assert(!MI.isDebugInstr() && "Cannot number debug instructions."); assert(MI.getParent() != nullptr && "Instr must be added to function."); @@ -674,10 +674,10 @@ class raw_ostream; idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); renumberIndexes(newItr); - std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); + llvm::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); } - /// \brief Free the resources that were required to maintain a SlotIndex. + /// Free the resources that were required to maintain a SlotIndex. /// /// Once an index is no longer needed (for instance because the instruction /// at that index has been moved), the resources required to maintain the diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index 4407114d2741bf5acf64a32376493926c629283a..3c9850265737750300261d147e595b572afbf989 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -29,7 +29,7 @@ class MCStreamer; class raw_ostream; class TargetRegisterInfo; -/// \brief MI-level stackmap operands. +/// MI-level stackmap operands. /// /// MI stackmap operations take the form: /// , , live args... @@ -60,7 +60,7 @@ public: } }; -/// \brief MI-level patchpoint operands. +/// MI-level patchpoint operands. /// /// MI patchpoint operations take the form: /// [], , , , , , ... @@ -137,7 +137,7 @@ public: return getVarIdx(); } - /// \brief Get the next scratch register operand index. + /// Get the next scratch register operand index. unsigned getNextScratchIdx(unsigned StartIdx = 0) const; }; @@ -236,15 +236,15 @@ public: FnInfos.clear(); } - /// \brief Generate a stackmap record for a stackmap instruction. + /// Generate a stackmap record for a stackmap instruction. /// /// MI must be a raw STACKMAP, not a PATCHPOINT. void recordStackMap(const MachineInstr &MI); - /// \brief Generate a stackmap record for a patchpoint instruction. + /// Generate a stackmap record for a patchpoint instruction. void recordPatchPoint(const MachineInstr &MI); - /// \brief Generate a stackmap record for a statepoint instruction. + /// Generate a stackmap record for a statepoint instruction. void recordStatepoint(const MachineInstr &MI); /// If there is any stack map data, create a stack map section and serialize @@ -293,11 +293,11 @@ private: MachineInstr::const_mop_iterator MOE, LocationVec &Locs, LiveOutVec &LiveOuts) const; - /// \brief Create a live-out register record for the given register @p Reg. + /// Create a live-out register record for the given register @p Reg. LiveOutReg createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const; - /// \brief Parse the register live-out mask and return a vector of live-out + /// Parse the register live-out mask and return a vector of live-out /// registers that need to be recorded in the stackmap. LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const; @@ -311,16 +311,16 @@ private: MachineInstr::const_mop_iterator MOE, bool recordResult = false); - /// \brief Emit the stackmap header. + /// Emit the stackmap header. void emitStackmapHeader(MCStreamer &OS); - /// \brief Emit the function frame record for each function. + /// Emit the function frame record for each function. void emitFunctionFrameRecords(MCStreamer &OS); - /// \brief Emit the constant pool. + /// Emit the constant pool. void emitConstantPoolEntries(MCStreamer &OS); - /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call. + /// Emit the callsite info for each stackmap/patchpoint intrinsic call. void emitCallsiteEntries(MCStreamer &OS); void print(raw_ostream &OS); diff --git a/include/llvm/CodeGen/StackProtector.h b/include/llvm/CodeGen/StackProtector.h index 72de212d0df9a97399ef49208a91051b19683a80..0fe2688a68b8f25888e8f4e534592ec46d20cb2e 100644 --- a/include/llvm/CodeGen/StackProtector.h +++ b/include/llvm/CodeGen/StackProtector.h @@ -70,7 +70,7 @@ private: /// AllocaInst triggers a stack protector. SSPLayoutMap Layout; - /// \brief The minimum size of buffers that will receive stack smashing + /// The minimum size of buffers that will receive stack smashing /// protection when -fstack-protection is used. unsigned SSPBufferSize = 0; @@ -107,7 +107,7 @@ private: bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, bool InStruct = false) const; - /// \brief Check whether a stack allocation has its address taken. + /// Check whether a stack allocation has its address taken. bool HasAddressTaken(const Instruction *AI); /// RequiresStackProtector - Check whether or not this function needs a diff --git a/include/llvm/CodeGen/TargetFrameLowering.h b/include/llvm/CodeGen/TargetFrameLowering.h index 61f1cf07bcf2c0b4f9527cdc96b9b3f332b865f7..f8effee998e3be12c0a0d094a316eee6df493bb7 100644 --- a/include/llvm/CodeGen/TargetFrameLowering.h +++ b/include/llvm/CodeGen/TargetFrameLowering.h @@ -158,6 +158,10 @@ public: return false; } + /// Returns true if the target can safely skip saving callee-saved registers + /// for noreturn nounwind functions. + virtual bool enableCalleeSaveSkip(const MachineFunction &MF) const; + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// the function. virtual void emitPrologue(MachineFunction &MF, @@ -341,6 +345,14 @@ public: return false; return true; } + + /// Return initial CFA offset value i.e. the one valid at the beginning of the + /// function (before any stack operations). + virtual int getInitialCFAOffset(const MachineFunction &MF) const; + + /// Return initial CFA register value i.e. the one valid at the beginning of + /// the function (before any stack operations). + virtual unsigned getInitialCFARegister(const MachineFunction &MF) const; }; } // End llvm namespace diff --git a/include/llvm/CodeGen/TargetInstrInfo.h b/include/llvm/CodeGen/TargetInstrInfo.h index 5c2a530762a9fbbc1ae29e479a5c01c198c169f1..3e742e588bac618928737f823bc00a6d28dc7796 100644 --- a/include/llvm/CodeGen/TargetInstrInfo.h +++ b/include/llvm/CodeGen/TargetInstrInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/None.h" +#include "llvm/CodeGen/LiveRegUnits.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineCombinerPattern.h" #include "llvm/CodeGen/MachineFunction.h" @@ -225,6 +226,17 @@ public: return 0; } + /// Optional extension of isLoadFromStackSlot that returns the number of + /// bytes loaded from the stack. This must be implemented if a backend + /// supports partial stack slot spills/loads to further disambiguate + /// what the load does. + virtual unsigned isLoadFromStackSlot(const MachineInstr &MI, + int &FrameIndex, + unsigned &MemBytes) const { + MemBytes = 0; + return isLoadFromStackSlot(MI, FrameIndex); + } + /// Check for post-frame ptr elimination stack locations as well. /// This uses a heuristic so it isn't reliable for correctness. virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, @@ -252,6 +264,17 @@ public: return 0; } + /// Optional extension of isStoreToStackSlot that returns the number of + /// bytes stored to the stack. This must be implemented if a backend + /// supports partial stack slot spills/loads to further disambiguate + /// what the store does. + virtual unsigned isStoreToStackSlot(const MachineInstr &MI, + int &FrameIndex, + unsigned &MemBytes) const { + MemBytes = 0; + return isStoreToStackSlot(MI, FrameIndex); + } + /// Check for post-frame ptr elimination stack locations as well. /// This uses a heuristic, so it isn't reliable for correctness. virtual unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, @@ -325,7 +348,7 @@ public: unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const; - /// \brief Clones instruction or the whole instruction bundle \p Orig and + /// Clones instruction or the whole instruction bundle \p Orig and /// insert into \p MBB before \p InsertBefore. The target may update operands /// that are required to be unique. /// @@ -822,6 +845,14 @@ public: llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!"); } + /// If the specific machine instruction is a instruction that moves/copies + /// value from one register to another register return true along with + /// @Source machine operand and @Destination machine operand. + virtual bool isCopyInstr(const MachineInstr &MI, MachineOperand &Source, + MachineOperand &Destination) const { + return false; + } + /// Store the specified register of the given register class to the specified /// stack frame index. The store instruction is to be added to the given /// machine basic block before the specified machine instruction. If isKill @@ -957,11 +988,6 @@ public: /// even if it has glue. virtual bool canCopyGluedNodeDuringSchedule(SDNode *N) const { return false; } - /// Remember what registers the specified instruction uses and modifies. - virtual void trackRegDefsUses(const MachineInstr &MI, BitVector &ModifiedRegs, - BitVector &UsedRegs, - const TargetRegisterInfo *TRI) const; - protected: /// Target-dependent implementation for foldMemoryOperand. /// Target-independent code in foldMemoryOperand will @@ -988,7 +1014,7 @@ protected: return nullptr; } - /// \brief Target-dependent implementation of getRegSequenceInputs. + /// Target-dependent implementation of getRegSequenceInputs. /// /// \returns true if it is possible to build the equivalent /// REG_SEQUENCE inputs with the pair \p MI, \p DefIdx. False otherwise. @@ -1002,7 +1028,7 @@ protected: return false; } - /// \brief Target-dependent implementation of getExtractSubregInputs. + /// Target-dependent implementation of getExtractSubregInputs. /// /// \returns true if it is possible to build the equivalent /// EXTRACT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise. @@ -1016,7 +1042,7 @@ protected: return false; } - /// \brief Target-dependent implementation of getInsertSubregInputs. + /// Target-dependent implementation of getInsertSubregInputs. /// /// \returns true if it is possible to build the equivalent /// INSERT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise. @@ -1438,7 +1464,7 @@ public: return 0; } - /// \brief Return the minimum clearance before an instruction that reads an + /// Return the minimum clearance before an instruction that reads an /// unused register. /// /// For example, AVX instructions may copy part of a register operand into @@ -1505,7 +1531,7 @@ public: return false; } - /// \brief Return the value to use for the MachineCSE's LookAheadLimit, + /// Return the value to use for the MachineCSE's LookAheadLimit, /// which is a heuristic used for CSE'ing phys reg defs. virtual unsigned getMachineCSELookAheadLimit() const { // The default lookahead is small to prevent unprofitable quadratic @@ -1574,49 +1600,59 @@ public: return false; } - /// \brief Describes the number of instructions that it will take to call and + /// Returns true if the target implements the MachineOutliner. + virtual bool useMachineOutliner() const { return false; } + + /// Describes the number of instructions that it will take to call and /// construct a frame for a given outlining candidate. struct MachineOutlinerInfo { + /// Represents the size of a sequence in bytes. (Some instructions vary + /// widely in size, so just counting the instructions isn't very useful.) + unsigned SequenceSize; + /// Number of instructions to call an outlined function for this candidate. unsigned CallOverhead; - /// \brief Number of instructions to construct an outlined function frame + /// Number of instructions to construct an outlined function frame /// for this candidate. unsigned FrameOverhead; - /// \brief Represents the specific instructions that must be emitted to + /// Represents the specific instructions that must be emitted to /// construct a call to this candidate. unsigned CallConstructionID; - /// \brief Represents the specific instructions that must be emitted to + /// Represents the specific instructions that must be emitted to /// construct a frame for this candidate's outlined function. unsigned FrameConstructionID; MachineOutlinerInfo() {} - MachineOutlinerInfo(unsigned CallOverhead, unsigned FrameOverhead, - unsigned CallConstructionID, + MachineOutlinerInfo(unsigned SequenceSize, unsigned CallOverhead, + unsigned FrameOverhead, unsigned CallConstructionID, unsigned FrameConstructionID) - : CallOverhead(CallOverhead), FrameOverhead(FrameOverhead), + : SequenceSize(SequenceSize), CallOverhead(CallOverhead), + FrameOverhead(FrameOverhead), CallConstructionID(CallConstructionID), FrameConstructionID(FrameConstructionID) {} }; - /// \brief Returns a \p MachineOutlinerInfo struct containing target-specific + /// Returns a \p MachineOutlinerInfo struct containing target-specific /// information for a set of outlining candidates. virtual MachineOutlinerInfo getOutlininingCandidateInfo( std::vector< std::pair> &RepeatedSequenceLocs) const { llvm_unreachable( - "Target didn't implement TargetInstrInfo::getOutliningOverhead!"); + "Target didn't implement TargetInstrInfo::getOutliningCandidateInfo!"); } /// Represents how an instruction should be mapped by the outliner. /// \p Legal instructions are those which are safe to outline. + /// \p LegalTerminator instructions are safe to outline, but only as the + /// last instruction in a sequence. /// \p Illegal instructions are those which cannot be outlined. /// \p Invisible instructions are instructions which can be outlined, but /// shouldn't actually impact the outlining result. - enum MachineOutlinerInstrType { Legal, Illegal, Invisible }; + enum MachineOutlinerInstrType { Legal, LegalTerminator, Illegal, Invisible }; /// Returns how or if \p MI should be outlined. virtual MachineOutlinerInstrType @@ -1625,7 +1661,7 @@ public: "Target didn't implement TargetInstrInfo::getOutliningType!"); } - /// \brief Returns target-defined flags defining properties of the MBB for + /// Returns target-defined flags defining properties of the MBB for /// the outliner. virtual unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const { return 0x0; @@ -1677,7 +1713,7 @@ private: unsigned ReturnOpcode; }; -/// \brief Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair. +/// Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair. template <> struct DenseMapInfo { using RegInfo = DenseMapInfo; @@ -1691,7 +1727,7 @@ template <> struct DenseMapInfo { RegInfo::getTombstoneKey()); } - /// \brief Reuse getHashValue implementation from + /// Reuse getHashValue implementation from /// std::pair. static unsigned getHashValue(const TargetInstrInfo::RegSubRegPair &Val) { std::pair PairVal = std::make_pair(Val.Reg, Val.SubReg); diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h index 483223a0873c991f2a13a3f65a022b2e076c7cb0..d3b8b9166800eac6eba296e88ea6ca980cb1d384 100644 --- a/include/llvm/CodeGen/TargetLowering.h +++ b/include/llvm/CodeGen/TargetLowering.h @@ -223,7 +223,7 @@ public: virtual ~TargetLoweringBase() = default; protected: - /// \brief Initialize all of the actions to default values. + /// Initialize all of the actions to default values. void initActions(); public: @@ -423,17 +423,17 @@ public: return true; } - /// \brief Return true if it is cheap to speculate a call to intrinsic cttz. + /// Return true if it is cheap to speculate a call to intrinsic cttz. virtual bool isCheapToSpeculateCttz() const { return false; } - /// \brief Return true if it is cheap to speculate a call to intrinsic ctlz. + /// Return true if it is cheap to speculate a call to intrinsic ctlz. virtual bool isCheapToSpeculateCtlz() const { return false; } - /// \brief Return true if ctlz instruction is fast. + /// Return true if ctlz instruction is fast. virtual bool isCtlzFast() const { return false; } @@ -446,13 +446,13 @@ public: return false; } - /// \brief Return true if it is cheaper to split the store of a merged int val + /// Return true if it is cheaper to split the store of a merged int val /// from a pair of smaller values into multiple stores. virtual bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const { return false; } - /// \brief Return if the target supports combining a + /// Return if the target supports combining a /// chain like: /// \code /// %andResult = and %val1, #mask @@ -509,7 +509,7 @@ public: return hasAndNotCompare(X); } - /// \brief Return true if the target wants to use the optimization that + /// Return true if the target wants to use the optimization that /// turns ext(promotableInst1(...(promotableInstN(load)))) into /// promotedInst1(...(promotedInstN(ext(load)))). bool enableExtLdPromotion() const { return EnableExtLdPromotion; } @@ -767,6 +767,35 @@ public: return OpActions[(unsigned)VT.getSimpleVT().SimpleTy][Op]; } + LegalizeAction getStrictFPOperationAction(unsigned Op, EVT VT) const { + unsigned EqOpc; + switch (Op) { + default: llvm_unreachable("Unexpected FP pseudo-opcode"); + case ISD::STRICT_FSQRT: EqOpc = ISD::FSQRT; break; + case ISD::STRICT_FPOW: EqOpc = ISD::FPOW; break; + case ISD::STRICT_FPOWI: EqOpc = ISD::FPOWI; break; + case ISD::STRICT_FMA: EqOpc = ISD::FMA; break; + case ISD::STRICT_FSIN: EqOpc = ISD::FSIN; break; + case ISD::STRICT_FCOS: EqOpc = ISD::FCOS; break; + case ISD::STRICT_FEXP: EqOpc = ISD::FEXP; break; + case ISD::STRICT_FEXP2: EqOpc = ISD::FEXP2; break; + case ISD::STRICT_FLOG: EqOpc = ISD::FLOG; break; + case ISD::STRICT_FLOG10: EqOpc = ISD::FLOG10; break; + case ISD::STRICT_FLOG2: EqOpc = ISD::FLOG2; break; + case ISD::STRICT_FRINT: EqOpc = ISD::FRINT; break; + case ISD::STRICT_FNEARBYINT: EqOpc = ISD::FNEARBYINT; break; + } + + auto Action = getOperationAction(EqOpc, VT); + + // We don't currently handle Custom or Promote for strict FP pseudo-ops. + // For now, we just expand for those cases. + if (Action != Legal) + Action = Expand; + + return Action; + } + /// Return true if the specified operation is legal on this target or can be /// made legal with custom lowering. This is used to help guide high-level /// lowering decisions. @@ -1117,10 +1146,6 @@ public: /// Certain combinations of ABIs, Targets and features require that types /// are legal for some operations and not for other operations. /// For MIPS all vector types must be passed through the integer register set. - virtual MVT getRegisterTypeForCallingConv(MVT VT) const { - return getRegisterType(VT); - } - virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, EVT VT) const { return getRegisterType(Context, VT); @@ -1179,7 +1204,7 @@ public: return getPointerTy(DL).getSizeInBits(); } - /// \brief Get maximum # of store operations permitted for llvm.memset + /// Get maximum # of store operations permitted for llvm.memset /// /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memset. The value is set by the target at the @@ -1189,7 +1214,7 @@ public: return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset; } - /// \brief Get maximum # of store operations permitted for llvm.memcpy + /// Get maximum # of store operations permitted for llvm.memcpy /// /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memcpy. The value is set by the target at the @@ -1199,6 +1224,15 @@ public: return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy; } + /// \brief Get maximum # of store operations to be glued together + /// + /// This function returns the maximum number of store operations permitted + /// to glue together during lowering of llvm.memcpy. The value is set by + // the target at the performance threshold for such a replacement. + virtual unsigned getMaxGluedStoresPerMemcpy() const { + return MaxGluedStoresPerMemcpy; + } + /// Get maximum # of load operations permitted for memcmp /// /// This function returns the maximum number of load operations permitted @@ -1221,7 +1255,7 @@ public: return 1; } - /// \brief Get maximum # of store operations permitted for llvm.memmove + /// Get maximum # of store operations permitted for llvm.memmove /// /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memmove. The value is set by the target at the @@ -1231,7 +1265,7 @@ public: return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove; } - /// \brief Determine if the target supports unaligned memory accesses. + /// Determine if the target supports unaligned memory accesses. /// /// This function returns true if the target allows unaligned memory accesses /// of the specified type in the given address space. If true, it also returns @@ -1369,7 +1403,7 @@ public: /// If the target has a standard location for the stack protector guard, /// returns the address of that location. Otherwise, returns nullptr. /// DEPRECATED: please override useLoadStackGuardNode and customize - /// LOAD_STACK_GUARD, or customize @llvm.stackguard(). + /// LOAD_STACK_GUARD, or customize \@llvm.stackguard(). virtual Value *getIRStackGuard(IRBuilder<> &IRB) const; /// Inserts necessary declarations for SSP (stack protection) purpose. @@ -1924,7 +1958,7 @@ public: Type *Ty, unsigned AddrSpace, Instruction *I = nullptr) const; - /// \brief Return the cost of the scaling factor used in the addressing mode + /// Return the cost of the scaling factor used in the addressing mode /// represented by AM for this target, for a load/store of the specified type. /// /// If the AM is supported, the return value must be >= 0. @@ -2120,11 +2154,11 @@ public: /// Return true if the target has a vector blend instruction. virtual bool hasVectorBlend() const { return false; } - /// \brief Get the maximum supported factor for interleaved memory accesses. + /// Get the maximum supported factor for interleaved memory accesses. /// Default to be the minimum interleave factor: 2. virtual unsigned getMaxSupportedInterleaveFactor() const { return 2; } - /// \brief Lower an interleaved load to target specific intrinsics. Return + /// Lower an interleaved load to target specific intrinsics. Return /// true on success. /// /// \p LI is the vector load instruction. @@ -2138,7 +2172,7 @@ public: return false; } - /// \brief Lower an interleaved store to target specific intrinsics. Return + /// Lower an interleaved store to target specific intrinsics. Return /// true on success. /// /// \p SI is the vector store instruction. @@ -2211,7 +2245,7 @@ public: return false; } - /// \brief Return true if it is beneficial to convert a load of a constant to + /// Return true if it is beneficial to convert a load of a constant to /// just the constant itself. /// On some targets it might be more efficient to use a combination of /// arithmetic instructions to materialize the constant instead of loading it @@ -2236,6 +2270,11 @@ public: return false; } + // Return true if CodeGenPrepare should consider splitting large offset of a + // GEP to make the GEP fit into the addressing mode and can be sunk into the + // same blocks of its users. + virtual bool shouldConsiderGEPOffsetSplit() const { return false; } + //===--------------------------------------------------------------------===// // Runtime Library hooks // @@ -2475,7 +2514,7 @@ protected: /// expected to be merged. unsigned GatherAllAliasesMaxDepth; - /// \brief Specify maximum number of store instructions per memset call. + /// Specify maximum number of store instructions per memset call. /// /// When lowering \@llvm.memset this field specifies the maximum number of /// store operations that may be substituted for the call to memset. Targets @@ -2491,7 +2530,7 @@ protected: /// to memset, used for functions with OptSize attribute. unsigned MaxStoresPerMemsetOptSize; - /// \brief Specify maximum bytes of store instructions per memcpy call. + /// Specify maximum bytes of store instructions per memcpy call. /// /// When lowering \@llvm.memcpy this field specifies the maximum number of /// store operations that may be substituted for a call to memcpy. Targets @@ -2504,13 +2543,21 @@ protected: /// constant size. unsigned MaxStoresPerMemcpy; + + /// \brief Specify max number of store instructions to glue in inlined memcpy. + /// + /// When memcpy is inlined based on MaxStoresPerMemcpy, specify maximum number + /// of store instructions to keep together. This helps in pairing and + // vectorization later on. + unsigned MaxGluedStoresPerMemcpy = 0; + /// Maximum number of store operations that may be substituted for a call to /// memcpy, used for functions with OptSize attribute. unsigned MaxStoresPerMemcpyOptSize; unsigned MaxLoadsPerMemcmp; unsigned MaxLoadsPerMemcmpOptSize; - /// \brief Specify maximum bytes of store instructions per memmove call. + /// Specify maximum bytes of store instructions per memmove call. /// /// When lowering \@llvm.memmove this field specifies the maximum number of /// store instructions that may be substituted for a call to memmove. Targets @@ -2547,6 +2594,11 @@ protected: /// details. MachineBasicBlock *emitXRayCustomEvent(MachineInstr &MI, MachineBasicBlock *MBB) const; + + /// Replace/modify the XRay typed event operands with target-dependent + /// details. + MachineBasicBlock *emitXRayTypedEvent(MachineInstr &MI, + MachineBasicBlock *MBB) const; }; /// This class defines information used to lower LLVM code to legal SelectionDAG diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 78da77fbd480f69fee1be666dab6bb4e4a7e50e9..bdeaaa46c13b0f08615d6b37324be2801bfae736 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -42,8 +42,7 @@ public: ~TargetLoweringObjectFileELF() override = default; /// Emit Obj-C garbage collection and linker options. - void emitModuleMetadata(MCStreamer &Streamer, Module &M, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const override; @@ -98,8 +97,7 @@ public: void Initialize(MCContext &Ctx, const TargetMachine &TM) override; /// Emit the module flags that specify the garbage collection information. - void emitModuleMetadata(MCStreamer &Streamer, Module &M, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override; @@ -153,8 +151,7 @@ public: const TargetMachine &TM) const override; /// Emit Obj-C garbage collection and linker options. - void emitModuleMetadata(MCStreamer &Streamer, Module &M, - const TargetMachine &TM) const override; + void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; MCSection *getStaticCtorSection(unsigned Priority, const MCSymbol *KeySym) const override; diff --git a/include/llvm/CodeGen/TargetRegisterInfo.h b/include/llvm/CodeGen/TargetRegisterInfo.h index ea47a24c898bafd7697dd8fa2987cf7e035b6edc..7c4e1392f9beb05cce8644dd3a0daedd19481471 100644 --- a/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/include/llvm/CodeGen/TargetRegisterInfo.h @@ -971,7 +971,7 @@ public: //===--------------------------------------------------------------------===// /// Subtarget Hooks - /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. + /// SrcRC and DstRC will be morphed into NewRC if this returns true. virtual bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, @@ -995,6 +995,12 @@ public: /// of the set as well. bool checkAllSuperRegsMarked(const BitVector &RegisterSet, ArrayRef Exceptions = ArrayRef()) const; + + virtual const TargetRegisterClass * + getConstrainedRegClassForOperand(const MachineOperand &MO, + const MachineRegisterInfo &MRI) const { + return nullptr; + } }; //===----------------------------------------------------------------------===// @@ -1174,11 +1180,11 @@ Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI = nullptr, /// Usage: OS << printRegUnit(Unit, TRI) << '\n'; Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI); -/// \brief Create Printable object to print virtual registers and physical +/// Create Printable object to print virtual registers and physical /// registers on a \ref raw_ostream. Printable printVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI); -/// \brief Create Printable object to print register classes or register banks +/// Create Printable object to print register classes or register banks /// on a \ref raw_ostream. Printable printRegClassOrBank(unsigned Reg, const MachineRegisterInfo &RegInfo, const TargetRegisterInfo *TRI); diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h index 1044f0bd27e6dfe3568f4cd34a8cc18944f15442..fa3c64fd6891a6f43c0c91afe6ebccb2e8e664fe 100644 --- a/include/llvm/CodeGen/TargetSchedule.h +++ b/include/llvm/CodeGen/TargetSchedule.h @@ -19,6 +19,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Config/llvm-config.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSchedule.h" @@ -45,24 +46,23 @@ class TargetSchedModel { public: TargetSchedModel() : SchedModel(MCSchedModel::GetDefaultSchedModel()) {} - /// \brief Initialize the machine model for instruction scheduling. + /// Initialize the machine model for instruction scheduling. /// /// The machine model API keeps a copy of the top-level MCSchedModel table /// indices and may query TargetSubtargetInfo and TargetInstrInfo to resolve /// dynamic properties. - void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti, - const TargetInstrInfo *tii); + void init(const TargetSubtargetInfo *TSInfo); /// Return the MCSchedClassDesc for this instruction. const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const; - /// \brief TargetSubtargetInfo getter. + /// TargetSubtargetInfo getter. const TargetSubtargetInfo *getSubtargetInfo() const { return STI; } - /// \brief TargetInstrInfo getter. + /// TargetInstrInfo getter. const TargetInstrInfo *getInstrInfo() const { return TII; } - /// \brief Return true if this machine model includes an instruction-level + /// Return true if this machine model includes an instruction-level /// scheduling model. /// /// This is more detailed than the course grain IssueWidth and default @@ -71,7 +71,7 @@ public: const MCSchedModel *getMCSchedModel() const { return &SchedModel; } - /// \brief Return true if this machine model includes cycle-to-cycle itinerary + /// Return true if this machine model includes cycle-to-cycle itinerary /// data. /// /// This models scheduling at each stage in the processor pipeline. @@ -83,35 +83,35 @@ public: return nullptr; } - /// \brief Return true if this machine model includes an instruction-level + /// Return true if this machine model includes an instruction-level /// scheduling model or cycle-to-cycle itinerary data. bool hasInstrSchedModelOrItineraries() const { return hasInstrSchedModel() || hasInstrItineraries(); } - /// \brief Identify the processor corresponding to the current subtarget. + /// Identify the processor corresponding to the current subtarget. unsigned getProcessorID() const { return SchedModel.getProcessorID(); } - /// \brief Maximum number of micro-ops that may be scheduled per cycle. + /// Maximum number of micro-ops that may be scheduled per cycle. unsigned getIssueWidth() const { return SchedModel.IssueWidth; } - /// \brief Return true if new group must begin. + /// Return true if new group must begin. bool mustBeginGroup(const MachineInstr *MI, const MCSchedClassDesc *SC = nullptr) const; - /// \brief Return true if current group must end. + /// Return true if current group must end. bool mustEndGroup(const MachineInstr *MI, const MCSchedClassDesc *SC = nullptr) const; - /// \brief Return the number of issue slots required for this MI. + /// Return the number of issue slots required for this MI. unsigned getNumMicroOps(const MachineInstr *MI, const MCSchedClassDesc *SC = nullptr) const; - /// \brief Get the number of kinds of resources for this target. + /// Get the number of kinds of resources for this target. unsigned getNumProcResourceKinds() const { return SchedModel.getNumProcResourceKinds(); } - /// \brief Get a processor resource by ID for convenience. + /// Get a processor resource by ID for convenience. const MCProcResourceDesc *getProcResource(unsigned PIdx) const { return SchedModel.getProcResource(PIdx); } @@ -126,7 +126,7 @@ public: using ProcResIter = const MCWriteProcResEntry *; - // \brief Get an iterator into the processor resources consumed by this + // Get an iterator into the processor resources consumed by this // scheduling class. ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const { // The subtarget holds a single resource table for all processors. @@ -136,34 +136,34 @@ public: return STI->getWriteProcResEnd(SC); } - /// \brief Multiply the number of units consumed for a resource by this factor + /// Multiply the number of units consumed for a resource by this factor /// to normalize it relative to other resources. unsigned getResourceFactor(unsigned ResIdx) const { return ResourceFactors[ResIdx]; } - /// \brief Multiply number of micro-ops by this factor to normalize it + /// Multiply number of micro-ops by this factor to normalize it /// relative to other resources. unsigned getMicroOpFactor() const { return MicroOpFactor; } - /// \brief Multiply cycle count by this factor to normalize it relative to + /// Multiply cycle count by this factor to normalize it relative to /// other resources. This is the number of resource units per cycle. unsigned getLatencyFactor() const { return ResourceLCM; } - /// \brief Number of micro-ops that may be buffered for OOO execution. + /// Number of micro-ops that may be buffered for OOO execution. unsigned getMicroOpBufferSize() const { return SchedModel.MicroOpBufferSize; } - /// \brief Number of resource units that may be buffered for OOO execution. + /// Number of resource units that may be buffered for OOO execution. /// \return The buffer size in resource units or -1 for unlimited. int getResourceBufferSize(unsigned PIdx) const { return SchedModel.getProcResource(PIdx)->BufferSize; } - /// \brief Compute operand latency based on the available machine model. + /// Compute operand latency based on the available machine model. /// /// Compute and return the latency of the given data dependent def and use /// when the operand indices are already known. UseMI may be NULL for an @@ -172,7 +172,7 @@ public: const MachineInstr *UseMI, unsigned UseOperIdx) const; - /// \brief Compute the instruction latency based on the available machine + /// Compute the instruction latency based on the available machine /// model. /// /// Compute and return the expected latency of this instruction independent of @@ -185,18 +185,20 @@ public: /// if converter after moving it to TargetSchedModel). unsigned computeInstrLatency(const MachineInstr *MI, bool UseDefaultDefLatency = true) const; + unsigned computeInstrLatency(const MCInst &MI) const; unsigned computeInstrLatency(unsigned Opcode) const; - /// \brief Output dependency latency of a pair of defs of the same register. + /// Output dependency latency of a pair of defs of the same register. /// /// This is typically one cycle. unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx, const MachineInstr *DepMI) const; - /// \brief Compute the reciprocal throughput of the given instruction. - Optional computeInstrRThroughput(const MachineInstr *MI) const; - Optional computeInstrRThroughput(unsigned Opcode) const; + /// Compute the reciprocal throughput of the given instruction. + Optional computeReciprocalThroughput(const MachineInstr *MI) const; + Optional computeReciprocalThroughput(const MCInst &MI) const; + Optional computeReciprocalThroughput(unsigned Opcode) const; }; } // end namespace llvm diff --git a/include/llvm/CodeGen/TargetSubtargetInfo.h b/include/llvm/CodeGen/TargetSubtargetInfo.h index 5e5faac6cbb156c58efe6e14ef659e6020227669..227e591f5a7db84a47621050673408d95c266547 100644 --- a/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -144,7 +144,7 @@ public: return 0; } - /// \brief True if the subtarget should run MachineScheduler after aggressive + /// True if the subtarget should run MachineScheduler after aggressive /// coalescing. /// /// This currently replaces the SelectionDAG scheduler with the "source" order @@ -152,14 +152,14 @@ public: /// TargetLowering preference). It does not yet disable the postRA scheduler. virtual bool enableMachineScheduler() const; - /// \brief Support printing of [latency:throughput] comment in output .S file. + /// Support printing of [latency:throughput] comment in output .S file. virtual bool supportPrintSchedInfo() const { return false; } - /// \brief True if the machine scheduler should disable the TLI preference + /// True if the machine scheduler should disable the TLI preference /// for preRA scheduling with the source level scheduler. virtual bool enableMachineSchedDefaultSched() const { return true; } - /// \brief True if the subtarget should enable joining global copies. + /// True if the subtarget should enable joining global copies. /// /// By default this is enabled if the machine scheduler is enabled, but /// can be overridden. @@ -171,13 +171,13 @@ public: /// which is the preferred way to influence this. virtual bool enablePostRAScheduler() const; - /// \brief True if the subtarget should run the atomic expansion pass. + /// True if the subtarget should run the atomic expansion pass. virtual bool enableAtomicExpand() const; /// True if the subtarget should run the indirectbr expansion pass. virtual bool enableIndirectBrExpand() const; - /// \brief Override generic scheduling policy within a region. + /// Override generic scheduling policy within a region. /// /// This is a convenient way for targets that don't provide any custom /// scheduling heuristics (no custom MachineSchedStrategy) to make @@ -185,7 +185,7 @@ public: virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const {} - // \brief Perform target specific adjustments to the latency of a schedule + // Perform target specific adjustments to the latency of a schedule // dependency. virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {} @@ -200,13 +200,13 @@ public: return CriticalPathRCs.clear(); } - // \brief Provide an ordered list of schedule DAG mutations for the post-RA + // Provide an ordered list of schedule DAG mutations for the post-RA // scheduler. virtual void getPostRAMutations( std::vector> &Mutations) const { } - // \brief Provide an ordered list of schedule DAG mutations for the machine + // Provide an ordered list of schedule DAG mutations for the machine // pipeliner. virtual void getSMSMutations( std::vector> &Mutations) const { @@ -218,25 +218,25 @@ public: return CodeGenOpt::Default; } - /// \brief True if the subtarget should run the local reassignment + /// True if the subtarget should run the local reassignment /// heuristic of the register allocator. /// This heuristic may be compile time intensive, \p OptLevel provides /// a finer grain to tune the register allocator. virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; - /// \brief True if the subtarget should consider the cost of local intervals + /// True if the subtarget should consider the cost of local intervals /// created by a split candidate when choosing the best split candidate. This /// heuristic may be compile time intensive. virtual bool enableAdvancedRASplitCost() const; - /// \brief Enable use of alias analysis during code generation (during MI + /// Enable use of alias analysis during code generation (during MI /// scheduling, DAGCombine, etc.). virtual bool useAA() const; - /// \brief Enable the use of the early if conversion pass. + /// Enable the use of the early if conversion pass. virtual bool enableEarlyIfConversion() const { return false; } - /// \brief Return PBQPConstraint(s) for the target. + /// Return PBQPConstraint(s) for the target. /// /// Override to provide custom PBQP constraints. virtual std::unique_ptr getCustomPBQPConstraints() const { @@ -249,7 +249,7 @@ public: virtual bool enableSubRegLiveness() const { return false; } /// Returns string representation of scheduler comment - std::string getSchedInfoStr(const MachineInstr &MI) const override; + std::string getSchedInfoStr(const MachineInstr &MI) const; std::string getSchedInfoStr(MCInst const &MCI) const override; /// This is called after a .mir file was loaded. diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h index 3b06f039311473fb2739cd89a7f5a88810bc474b..f409814c4f43999343226177126f0a07f9ccda07 100644 --- a/include/llvm/CodeGen/VirtRegMap.h +++ b/include/llvm/CodeGen/VirtRegMap.h @@ -90,24 +90,24 @@ class TargetInstrInfo; void grow(); - /// @brief returns true if the specified virtual register is + /// returns true if the specified virtual register is /// mapped to a physical register bool hasPhys(unsigned virtReg) const { return getPhys(virtReg) != NO_PHYS_REG; } - /// @brief returns the physical register mapped to the specified + /// returns the physical register mapped to the specified /// virtual register unsigned getPhys(unsigned virtReg) const { assert(TargetRegisterInfo::isVirtualRegister(virtReg)); return Virt2PhysMap[virtReg]; } - /// @brief creates a mapping for the specified virtual register to + /// creates a mapping for the specified virtual register to /// the specified physical register void assignVirt2Phys(unsigned virtReg, MCPhysReg physReg); - /// @brief clears the specified virtual register's, physical + /// clears the specified virtual register's, physical /// register mapping void clearVirt(unsigned virtReg) { assert(TargetRegisterInfo::isVirtualRegister(virtReg)); @@ -116,26 +116,26 @@ class TargetInstrInfo; Virt2PhysMap[virtReg] = NO_PHYS_REG; } - /// @brief clears all virtual to physical register mappings + /// clears all virtual to physical register mappings void clearAllVirt() { Virt2PhysMap.clear(); grow(); } - /// @brief returns true if VirtReg is assigned to its preferred physreg. + /// returns true if VirtReg is assigned to its preferred physreg. bool hasPreferredPhys(unsigned VirtReg); - /// @brief returns true if VirtReg has a known preferred register. + /// returns true if VirtReg has a known preferred register. /// This returns false if VirtReg has a preference that is a virtual /// register that hasn't been assigned yet. bool hasKnownPreference(unsigned VirtReg); - /// @brief records virtReg is a split live interval from SReg. + /// records virtReg is a split live interval from SReg. void setIsSplitFromReg(unsigned virtReg, unsigned SReg) { Virt2SplitMap[virtReg] = SReg; } - /// @brief returns the live interval virtReg is split from. + /// returns the live interval virtReg is split from. unsigned getPreSplitReg(unsigned virtReg) const { return Virt2SplitMap[virtReg]; } @@ -149,7 +149,7 @@ class TargetInstrInfo; return Orig ? Orig : VirtReg; } - /// @brief returns true if the specified virtual register is not + /// returns true if the specified virtual register is not /// mapped to a stack slot or rematerialized. bool isAssignedReg(unsigned virtReg) const { if (getStackSlot(virtReg) == NO_STACK_SLOT) @@ -159,18 +159,18 @@ class TargetInstrInfo; return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG); } - /// @brief returns the stack slot mapped to the specified virtual + /// returns the stack slot mapped to the specified virtual /// register int getStackSlot(unsigned virtReg) const { assert(TargetRegisterInfo::isVirtualRegister(virtReg)); return Virt2StackSlotMap[virtReg]; } - /// @brief create a mapping for the specifed virtual register to + /// create a mapping for the specifed virtual register to /// the next available stack slot int assignVirt2StackSlot(unsigned virtReg); - /// @brief create a mapping for the specified virtual register to + /// create a mapping for the specified virtual register to /// the specified stack slot void assignVirt2StackSlot(unsigned virtReg, int frameIndex); diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 940f8420304204d98de14f5c866600e17d59833a..e934617d7ec78de5d389d01e9493d3716415e43a 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -43,10 +43,6 @@ /* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */ #cmakedefine01 LLVM_ENABLE_DIA_SDK -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_DIRENT_H ${HAVE_DIRENT_H} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H} @@ -80,9 +76,6 @@ /* Define to 1 if you have the `futimes' function. */ #cmakedefine HAVE_FUTIMES ${HAVE_FUTIMES} -/* Define to 1 if you have the `getcwd' function. */ -#cmakedefine HAVE_GETCWD ${HAVE_GETCWD} - /* Define to 1 if you have the `getpagesize' function. */ #cmakedefine HAVE_GETPAGESIZE ${HAVE_GETPAGESIZE} @@ -92,21 +85,15 @@ /* Define to 1 if you have the `getrusage' function. */ #cmakedefine HAVE_GETRUSAGE ${HAVE_GETRUSAGE} -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY} - -/* Define to 1 if the system has the type `int64_t'. */ -#cmakedefine HAVE_INT64_T ${HAVE_INT64_T} - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} - /* Define to 1 if you have the `isatty' function. */ #cmakedefine HAVE_ISATTY 1 /* Define to 1 if you have the `edit' library (-ledit). */ #cmakedefine HAVE_LIBEDIT ${HAVE_LIBEDIT} +/* Define to 1 if you have the `pfm' library (-lpfm). */ +#cmakedefine HAVE_LIBPFM ${HAVE_LIBPFM} + /* Define to 1 if you have the `psapi' library (-lpsapi). */ #cmakedefine HAVE_LIBPSAPI ${HAVE_LIBPSAPI} @@ -119,9 +106,6 @@ /* Define to 1 if you have the `pthread_setname_np' function. */ #cmakedefine HAVE_PTHREAD_SETNAME_NP ${HAVE_PTHREAD_SETNAME_NP} -/* Define to 1 if you have the `shell32' library (-lshell32). */ -#cmakedefine HAVE_LIBSHELL32 ${HAVE_LIBSHELL32} - /* Define to 1 if you have the `z' library (-lz). */ #cmakedefine HAVE_LIBZ ${HAVE_LIBZ} @@ -149,18 +133,6 @@ /* Define to 1 if you have the `malloc_zone_statistics' function. */ #cmakedefine HAVE_MALLOC_ZONE_STATISTICS ${HAVE_MALLOC_ZONE_STATISTICS} -/* Define to 1 if you have the `mkdtemp' function. */ -#cmakedefine HAVE_MKDTEMP ${HAVE_MKDTEMP} - -/* Define to 1 if you have the `mkstemp' function. */ -#cmakedefine HAVE_MKSTEMP ${HAVE_MKSTEMP} - -/* Define to 1 if you have the `mktemp' function. */ -#cmakedefine HAVE_MKTEMP ${HAVE_MKTEMP} - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H} - /* Define to 1 if you have the `posix_fallocate' function. */ #cmakedefine HAVE_POSIX_FALLOCATE ${HAVE_POSIX_FALLOCATE} @@ -206,35 +178,21 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGNAL_H ${HAVE_SIGNAL_H} -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} - /* Define to 1 if you have the `strerror' function. */ #cmakedefine HAVE_STRERROR ${HAVE_STRERROR} /* Define to 1 if you have the `strerror_r' function. */ #cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R} -/* Define to 1 if you have the `strtoll' function. */ -#cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL} - /* Define to 1 if you have the `sysconf' function. */ #cmakedefine HAVE_SYSCONF ${HAVE_SYSCONF} -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_SYS_DIR_H ${HAVE_SYS_DIR_H} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H} /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_MMAN_H ${HAVE_SYS_MMAN_H} -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_SYS_NDIR_H ${HAVE_SYS_NDIR_H} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H} @@ -250,9 +208,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UIO_H ${HAVE_SYS_UIO_H} - /* Define if the setupterm() function is supported this platform. */ #cmakedefine HAVE_TERMINFO ${HAVE_TERMINFO} @@ -262,21 +217,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H} -/* Define to 1 if the system has the type `uint64_t'. */ -#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} -/* Define to 1 if the system has the type `u_int64_t'. */ -#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_VALGRIND_VALGRIND_H ${HAVE_VALGRIND_VALGRIND_H} -/* Define to 1 if you have the `writev' function. */ -#cmakedefine HAVE_WRITEV ${HAVE_WRITEV} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H} @@ -343,58 +289,22 @@ /* Linker version detected at compile time. */ #cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}" -/* Define if we link Polly to the tools */ -#cmakedefine LINK_POLLY_INTO_TOOLS - /* Target triple LLVM will generate code for by default */ /* Doesn't use `cmakedefine` because it is allowed to be empty. */ #define LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}" -/* Define if threads enabled */ -#cmakedefine01 LLVM_ENABLE_THREADS - /* Define if zlib compression is available */ #cmakedefine01 LLVM_ENABLE_ZLIB -/* Has gcc/MSVC atomic intrinsics */ -#cmakedefine01 LLVM_HAS_ATOMICS - -/* Host triple LLVM will be executed on */ -#cmakedefine LLVM_HOST_TRIPLE "${LLVM_HOST_TRIPLE}" - -/* Define if this is Unixish platform */ -#cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} - -/* Define if this is Win32ish platform */ -#cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32} - /* Define if overriding target triple is enabled */ #cmakedefine LLVM_TARGET_TRIPLE_ENV "${LLVM_TARGET_TRIPLE_ENV}" -/* Define if we have the Intel JIT API runtime support library */ -#cmakedefine01 LLVM_USE_INTEL_JITEVENTS - -/* Define if we have the oprofile JIT-support library */ -#cmakedefine01 LLVM_USE_OPROFILE - /* LLVM version information */ #cmakedefine LLVM_VERSION_INFO "${LLVM_VERSION_INFO}" /* Whether tools show host and target info when invoked with --version */ #cmakedefine01 LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO -/* Major version of the LLVM API */ -#define LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR} - -/* Minor version of the LLVM API */ -#define LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR} - -/* Patch version of the LLVM API */ -#define LLVM_VERSION_PATCH ${LLVM_VERSION_PATCH} - -/* LLVM version string */ -#define LLVM_VERSION_STRING "${PACKAGE_VERSION}" - /* Define if libxml2 is supported on this platform. */ #cmakedefine LLVM_LIBXML2_ENABLED ${LLVM_LIBXML2_ENABLED} @@ -410,9 +320,6 @@ /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}" @@ -422,12 +329,6 @@ /* Define as the return type of signal handlers (`int' or `void'). */ #cmakedefine RETSIGTYPE ${RETSIGTYPE} -/* Define to a function replacing strtoll */ -#cmakedefine strtoll ${strtoll} - -/* Define to a function implementing strtoull */ -#cmakedefine strtoull ${strtoull} - /* Define to a function implementing stricmp */ #cmakedefine stricmp ${stricmp} diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index 58cc9f99d9994f408a9ac6008b71f066be035bf8..c0fd158334807c21a7b87f34cf84424c424258c9 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -56,9 +56,6 @@ /* Define if this is Unixish platform */ #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} -/* Define if this is Win32ish platform */ -#cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32} - /* Define if we have the Intel JIT API runtime support library */ #cmakedefine01 LLVM_USE_INTEL_JITEVENTS diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 301e4f6358f27ce84d7478bb37963cbe587db573..4ce9f68cffd99ac7b87bd9f9337d39f07addeeb6 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -22,8 +22,8 @@ namespace llvm { namespace codeview { -/// Distinguishes individual records in .debug$T section or PDB type stream. The -/// documentation and headers talk about this as the "leaf" type. +/// Distinguishes individual records in .debug$T or .debug$P section or PDB type +/// stream. The documentation and headers talk about this as the "leaf" type. enum class TypeRecordKind : uint16_t { #define TYPE_RECORD(lf_ename, value, name) name = value, #include "CodeViewTypes.def" diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def index 3f06602948668944a1fb2771ab4f94e2b877b350..6da8893bd61af5485708e50ee24ebb324a92b1b4 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def +++ b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def @@ -15,254 +15,254 @@ #define CV_REGISTER(name, value) #endif -// This currently only contains the "register subset shraed by all processor +// This currently only contains the "register subset shared by all processor // types" (ERR etc.) and the x86 registers. -CV_REGISTER(ERR, 30000) -CV_REGISTER(TEB, 30001) -CV_REGISTER(TIMER, 30002) -CV_REGISTER(EFAD1, 30003) -CV_REGISTER(EFAD2, 30004) -CV_REGISTER(EFAD3, 30005) -CV_REGISTER(VFRAME, 30006) -CV_REGISTER(HANDLE, 30007) -CV_REGISTER(PARAMS, 30008) -CV_REGISTER(LOCALS, 30009) -CV_REGISTER(TID, 30010) -CV_REGISTER(ENV, 30011) -CV_REGISTER(CMDLN, 30012) +CV_REGISTER(CVRegERR, 30000) +CV_REGISTER(CVRegTEB, 30001) +CV_REGISTER(CVRegTIMER, 30002) +CV_REGISTER(CVRegEFAD1, 30003) +CV_REGISTER(CVRegEFAD2, 30004) +CV_REGISTER(CVRegEFAD3, 30005) +CV_REGISTER(CVRegVFRAME, 30006) +CV_REGISTER(CVRegHANDLE, 30007) +CV_REGISTER(CVRegPARAMS, 30008) +CV_REGISTER(CVRegLOCALS, 30009) +CV_REGISTER(CVRegTID, 30010) +CV_REGISTER(CVRegENV, 30011) +CV_REGISTER(CVRegCMDLN, 30012) -CV_REGISTER(NONE, 0) -CV_REGISTER(AL, 1) -CV_REGISTER(CL, 2) -CV_REGISTER(DL, 3) -CV_REGISTER(BL, 4) -CV_REGISTER(AH, 5) -CV_REGISTER(CH, 6) -CV_REGISTER(DH, 7) -CV_REGISTER(BH, 8) -CV_REGISTER(AX, 9) -CV_REGISTER(CX, 10) -CV_REGISTER(DX, 11) -CV_REGISTER(BX, 12) -CV_REGISTER(SP, 13) -CV_REGISTER(BP, 14) -CV_REGISTER(SI, 15) -CV_REGISTER(DI, 16) -CV_REGISTER(EAX, 17) -CV_REGISTER(ECX, 18) -CV_REGISTER(EDX, 19) -CV_REGISTER(EBX, 20) -CV_REGISTER(ESP, 21) -CV_REGISTER(EBP, 22) -CV_REGISTER(ESI, 23) -CV_REGISTER(EDI, 24) -CV_REGISTER(ES, 25) -CV_REGISTER(CS, 26) -CV_REGISTER(SS, 27) -CV_REGISTER(DS, 28) -CV_REGISTER(FS, 29) -CV_REGISTER(GS, 30) -CV_REGISTER(IP, 31) -CV_REGISTER(FLAGS, 32) -CV_REGISTER(EIP, 33) -CV_REGISTER(EFLAGS, 34) -CV_REGISTER(TEMP, 40) -CV_REGISTER(TEMPH, 41) -CV_REGISTER(QUOTE, 42) -CV_REGISTER(PCDR3, 43) -CV_REGISTER(PCDR4, 44) -CV_REGISTER(PCDR5, 45) -CV_REGISTER(PCDR6, 46) -CV_REGISTER(PCDR7, 47) -CV_REGISTER(CR0, 80) -CV_REGISTER(CR1, 81) -CV_REGISTER(CR2, 82) -CV_REGISTER(CR3, 83) -CV_REGISTER(CR4, 84) -CV_REGISTER(DR0, 90) -CV_REGISTER(DR1, 91) -CV_REGISTER(DR2, 92) -CV_REGISTER(DR3, 93) -CV_REGISTER(DR4, 94) -CV_REGISTER(DR5, 95) -CV_REGISTER(DR6, 96) -CV_REGISTER(DR7, 97) -CV_REGISTER(GDTR, 110) -CV_REGISTER(GDTL, 111) -CV_REGISTER(IDTR, 112) -CV_REGISTER(IDTL, 113) -CV_REGISTER(LDTR, 114) -CV_REGISTER(TR, 115) +CV_REGISTER(CVRegNONE, 0) +CV_REGISTER(CVRegAL, 1) +CV_REGISTER(CVRegCL, 2) +CV_REGISTER(CVRegDL, 3) +CV_REGISTER(CVRegBL, 4) +CV_REGISTER(CVRegAH, 5) +CV_REGISTER(CVRegCH, 6) +CV_REGISTER(CVRegDH, 7) +CV_REGISTER(CVRegBH, 8) +CV_REGISTER(CVRegAX, 9) +CV_REGISTER(CVRegCX, 10) +CV_REGISTER(CVRegDX, 11) +CV_REGISTER(CVRegBX, 12) +CV_REGISTER(CVRegSP, 13) +CV_REGISTER(CVRegBP, 14) +CV_REGISTER(CVRegSI, 15) +CV_REGISTER(CVRegDI, 16) +CV_REGISTER(CVRegEAX, 17) +CV_REGISTER(CVRegECX, 18) +CV_REGISTER(CVRegEDX, 19) +CV_REGISTER(CVRegEBX, 20) +CV_REGISTER(CVRegESP, 21) +CV_REGISTER(CVRegEBP, 22) +CV_REGISTER(CVRegESI, 23) +CV_REGISTER(CVRegEDI, 24) +CV_REGISTER(CVRegES, 25) +CV_REGISTER(CVRegCS, 26) +CV_REGISTER(CVRegSS, 27) +CV_REGISTER(CVRegDS, 28) +CV_REGISTER(CVRegFS, 29) +CV_REGISTER(CVRegGS, 30) +CV_REGISTER(CVRegIP, 31) +CV_REGISTER(CVRegFLAGS, 32) +CV_REGISTER(CVRegEIP, 33) +CV_REGISTER(CVRegEFLAGS, 34) +CV_REGISTER(CVRegTEMP, 40) +CV_REGISTER(CVRegTEMPH, 41) +CV_REGISTER(CVRegQUOTE, 42) +CV_REGISTER(CVRegPCDR3, 43) +CV_REGISTER(CVRegPCDR4, 44) +CV_REGISTER(CVRegPCDR5, 45) +CV_REGISTER(CVRegPCDR6, 46) +CV_REGISTER(CVRegPCDR7, 47) +CV_REGISTER(CVRegCR0, 80) +CV_REGISTER(CVRegCR1, 81) +CV_REGISTER(CVRegCR2, 82) +CV_REGISTER(CVRegCR3, 83) +CV_REGISTER(CVRegCR4, 84) +CV_REGISTER(CVRegDR0, 90) +CV_REGISTER(CVRegDR1, 91) +CV_REGISTER(CVRegDR2, 92) +CV_REGISTER(CVRegDR3, 93) +CV_REGISTER(CVRegDR4, 94) +CV_REGISTER(CVRegDR5, 95) +CV_REGISTER(CVRegDR6, 96) +CV_REGISTER(CVRegDR7, 97) +CV_REGISTER(CVRegGDTR, 110) +CV_REGISTER(CVRegGDTL, 111) +CV_REGISTER(CVRegIDTR, 112) +CV_REGISTER(CVRegIDTL, 113) +CV_REGISTER(CVRegLDTR, 114) +CV_REGISTER(CVRegTR, 115) -CV_REGISTER(PSEUDO1, 116) -CV_REGISTER(PSEUDO2, 117) -CV_REGISTER(PSEUDO3, 118) -CV_REGISTER(PSEUDO4, 119) -CV_REGISTER(PSEUDO5, 120) -CV_REGISTER(PSEUDO6, 121) -CV_REGISTER(PSEUDO7, 122) -CV_REGISTER(PSEUDO8, 123) -CV_REGISTER(PSEUDO9, 124) +CV_REGISTER(CVRegPSEUDO1, 116) +CV_REGISTER(CVRegPSEUDO2, 117) +CV_REGISTER(CVRegPSEUDO3, 118) +CV_REGISTER(CVRegPSEUDO4, 119) +CV_REGISTER(CVRegPSEUDO5, 120) +CV_REGISTER(CVRegPSEUDO6, 121) +CV_REGISTER(CVRegPSEUDO7, 122) +CV_REGISTER(CVRegPSEUDO8, 123) +CV_REGISTER(CVRegPSEUDO9, 124) -CV_REGISTER(ST0, 128) -CV_REGISTER(ST1, 129) -CV_REGISTER(ST2, 130) -CV_REGISTER(ST3, 131) -CV_REGISTER(ST4, 132) -CV_REGISTER(ST5, 133) -CV_REGISTER(ST6, 134) -CV_REGISTER(ST7, 135) -CV_REGISTER(CTRL, 136) -CV_REGISTER(STAT, 137) -CV_REGISTER(TAG, 138) -CV_REGISTER(FPIP, 139) -CV_REGISTER(FPCS, 140) -CV_REGISTER(FPDO, 141) -CV_REGISTER(FPDS, 142) -CV_REGISTER(ISEM, 143) -CV_REGISTER(FPEIP, 144) -CV_REGISTER(FPEDO, 145) +CV_REGISTER(CVRegST0, 128) +CV_REGISTER(CVRegST1, 129) +CV_REGISTER(CVRegST2, 130) +CV_REGISTER(CVRegST3, 131) +CV_REGISTER(CVRegST4, 132) +CV_REGISTER(CVRegST5, 133) +CV_REGISTER(CVRegST6, 134) +CV_REGISTER(CVRegST7, 135) +CV_REGISTER(CVRegCTRL, 136) +CV_REGISTER(CVRegSTAT, 137) +CV_REGISTER(CVRegTAG, 138) +CV_REGISTER(CVRegFPIP, 139) +CV_REGISTER(CVRegFPCS, 140) +CV_REGISTER(CVRegFPDO, 141) +CV_REGISTER(CVRegFPDS, 142) +CV_REGISTER(CVRegISEM, 143) +CV_REGISTER(CVRegFPEIP, 144) +CV_REGISTER(CVRegFPEDO, 145) -CV_REGISTER(MM0, 146) -CV_REGISTER(MM1, 147) -CV_REGISTER(MM2, 148) -CV_REGISTER(MM3, 149) -CV_REGISTER(MM4, 150) -CV_REGISTER(MM5, 151) -CV_REGISTER(MM6, 152) -CV_REGISTER(MM7, 153) +CV_REGISTER(CVRegMM0, 146) +CV_REGISTER(CVRegMM1, 147) +CV_REGISTER(CVRegMM2, 148) +CV_REGISTER(CVRegMM3, 149) +CV_REGISTER(CVRegMM4, 150) +CV_REGISTER(CVRegMM5, 151) +CV_REGISTER(CVRegMM6, 152) +CV_REGISTER(CVRegMM7, 153) -CV_REGISTER(XMM0, 154) -CV_REGISTER(XMM1, 155) -CV_REGISTER(XMM2, 156) -CV_REGISTER(XMM3, 157) -CV_REGISTER(XMM4, 158) -CV_REGISTER(XMM5, 159) -CV_REGISTER(XMM6, 160) -CV_REGISTER(XMM7, 161) +CV_REGISTER(CVRegXMM0, 154) +CV_REGISTER(CVRegXMM1, 155) +CV_REGISTER(CVRegXMM2, 156) +CV_REGISTER(CVRegXMM3, 157) +CV_REGISTER(CVRegXMM4, 158) +CV_REGISTER(CVRegXMM5, 159) +CV_REGISTER(CVRegXMM6, 160) +CV_REGISTER(CVRegXMM7, 161) -CV_REGISTER(MXCSR, 211) +CV_REGISTER(CVRegMXCSR, 211) -CV_REGISTER(EDXEAX, 212) +CV_REGISTER(CVRegEDXEAX, 212) -CV_REGISTER(EMM0L, 220) -CV_REGISTER(EMM1L, 221) -CV_REGISTER(EMM2L, 222) -CV_REGISTER(EMM3L, 223) -CV_REGISTER(EMM4L, 224) -CV_REGISTER(EMM5L, 225) -CV_REGISTER(EMM6L, 226) -CV_REGISTER(EMM7L, 227) +CV_REGISTER(CVRegEMM0L, 220) +CV_REGISTER(CVRegEMM1L, 221) +CV_REGISTER(CVRegEMM2L, 222) +CV_REGISTER(CVRegEMM3L, 223) +CV_REGISTER(CVRegEMM4L, 224) +CV_REGISTER(CVRegEMM5L, 225) +CV_REGISTER(CVRegEMM6L, 226) +CV_REGISTER(CVRegEMM7L, 227) -CV_REGISTER(EMM0H, 228) -CV_REGISTER(EMM1H, 229) -CV_REGISTER(EMM2H, 230) -CV_REGISTER(EMM3H, 231) -CV_REGISTER(EMM4H, 232) -CV_REGISTER(EMM5H, 233) -CV_REGISTER(EMM6H, 234) -CV_REGISTER(EMM7H, 235) +CV_REGISTER(CVRegEMM0H, 228) +CV_REGISTER(CVRegEMM1H, 229) +CV_REGISTER(CVRegEMM2H, 230) +CV_REGISTER(CVRegEMM3H, 231) +CV_REGISTER(CVRegEMM4H, 232) +CV_REGISTER(CVRegEMM5H, 233) +CV_REGISTER(CVRegEMM6H, 234) +CV_REGISTER(CVRegEMM7H, 235) -CV_REGISTER(MM00, 236) -CV_REGISTER(MM01, 237) -CV_REGISTER(MM10, 238) -CV_REGISTER(MM11, 239) -CV_REGISTER(MM20, 240) -CV_REGISTER(MM21, 241) -CV_REGISTER(MM30, 242) -CV_REGISTER(MM31, 243) -CV_REGISTER(MM40, 244) -CV_REGISTER(MM41, 245) -CV_REGISTER(MM50, 246) -CV_REGISTER(MM51, 247) -CV_REGISTER(MM60, 248) -CV_REGISTER(MM61, 249) -CV_REGISTER(MM70, 250) -CV_REGISTER(MM71, 251) +CV_REGISTER(CVRegMM00, 236) +CV_REGISTER(CVRegMM01, 237) +CV_REGISTER(CVRegMM10, 238) +CV_REGISTER(CVRegMM11, 239) +CV_REGISTER(CVRegMM20, 240) +CV_REGISTER(CVRegMM21, 241) +CV_REGISTER(CVRegMM30, 242) +CV_REGISTER(CVRegMM31, 243) +CV_REGISTER(CVRegMM40, 244) +CV_REGISTER(CVRegMM41, 245) +CV_REGISTER(CVRegMM50, 246) +CV_REGISTER(CVRegMM51, 247) +CV_REGISTER(CVRegMM60, 248) +CV_REGISTER(CVRegMM61, 249) +CV_REGISTER(CVRegMM70, 250) +CV_REGISTER(CVRegMM71, 251) -CV_REGISTER(BND0, 396) -CV_REGISTER(BND1, 397) -CV_REGISTER(BND2, 398) +CV_REGISTER(CVRegBND0, 396) +CV_REGISTER(CVRegBND1, 397) +CV_REGISTER(CVRegBND2, 398) -CV_REGISTER(XMM8, 252) -CV_REGISTER(XMM9, 253) -CV_REGISTER(XMM10, 254) -CV_REGISTER(XMM11, 255) -CV_REGISTER(XMM12, 256) -CV_REGISTER(XMM13, 257) -CV_REGISTER(XMM14, 258) -CV_REGISTER(XMM15, 259) +CV_REGISTER(CVRegXMM8, 252) +CV_REGISTER(CVRegXMM9, 253) +CV_REGISTER(CVRegXMM10, 254) +CV_REGISTER(CVRegXMM11, 255) +CV_REGISTER(CVRegXMM12, 256) +CV_REGISTER(CVRegXMM13, 257) +CV_REGISTER(CVRegXMM14, 258) +CV_REGISTER(CVRegXMM15, 259) -CV_REGISTER(SIL, 324) -CV_REGISTER(DIL, 325) -CV_REGISTER(BPL, 326) -CV_REGISTER(SPL, 327) +CV_REGISTER(CVRegSIL, 324) +CV_REGISTER(CVRegDIL, 325) +CV_REGISTER(CVRegBPL, 326) +CV_REGISTER(CVRegSPL, 327) -CV_REGISTER(RAX, 328) -CV_REGISTER(RBX, 329) -CV_REGISTER(RCX, 330) -CV_REGISTER(RDX, 331) -CV_REGISTER(RSI, 332) -CV_REGISTER(RDI, 333) -CV_REGISTER(RBP, 334) -CV_REGISTER(RSP, 335) +CV_REGISTER(CVRegRAX, 328) +CV_REGISTER(CVRegRBX, 329) +CV_REGISTER(CVRegRCX, 330) +CV_REGISTER(CVRegRDX, 331) +CV_REGISTER(CVRegRSI, 332) +CV_REGISTER(CVRegRDI, 333) +CV_REGISTER(CVRegRBP, 334) +CV_REGISTER(CVRegRSP, 335) -CV_REGISTER(R8, 336) -CV_REGISTER(R9, 337) -CV_REGISTER(R10, 338) -CV_REGISTER(R11, 339) -CV_REGISTER(R12, 340) -CV_REGISTER(R13, 341) -CV_REGISTER(R14, 342) -CV_REGISTER(R15, 343) +CV_REGISTER(CVRegR8, 336) +CV_REGISTER(CVRegR9, 337) +CV_REGISTER(CVRegR10, 338) +CV_REGISTER(CVRegR11, 339) +CV_REGISTER(CVRegR12, 340) +CV_REGISTER(CVRegR13, 341) +CV_REGISTER(CVRegR14, 342) +CV_REGISTER(CVRegR15, 343) -CV_REGISTER(R8B, 344) -CV_REGISTER(R9B, 345) -CV_REGISTER(R10B, 346) -CV_REGISTER(R11B, 347) -CV_REGISTER(R12B, 348) -CV_REGISTER(R13B, 349) -CV_REGISTER(R14B, 350) -CV_REGISTER(R15B, 351) +CV_REGISTER(CVRegR8B, 344) +CV_REGISTER(CVRegR9B, 345) +CV_REGISTER(CVRegR10B, 346) +CV_REGISTER(CVRegR11B, 347) +CV_REGISTER(CVRegR12B, 348) +CV_REGISTER(CVRegR13B, 349) +CV_REGISTER(CVRegR14B, 350) +CV_REGISTER(CVRegR15B, 351) -CV_REGISTER(R8W, 352) -CV_REGISTER(R9W, 353) -CV_REGISTER(R10W, 354) -CV_REGISTER(R11W, 355) -CV_REGISTER(R12W, 356) -CV_REGISTER(R13W, 357) -CV_REGISTER(R14W, 358) -CV_REGISTER(R15W, 359) +CV_REGISTER(CVRegR8W, 352) +CV_REGISTER(CVRegR9W, 353) +CV_REGISTER(CVRegR10W, 354) +CV_REGISTER(CVRegR11W, 355) +CV_REGISTER(CVRegR12W, 356) +CV_REGISTER(CVRegR13W, 357) +CV_REGISTER(CVRegR14W, 358) +CV_REGISTER(CVRegR15W, 359) -CV_REGISTER(R8D, 360) -CV_REGISTER(R9D, 361) -CV_REGISTER(R10D, 362) -CV_REGISTER(R11D, 363) -CV_REGISTER(R12D, 364) -CV_REGISTER(R13D, 365) -CV_REGISTER(R14D, 366) -CV_REGISTER(R15D, 367) +CV_REGISTER(CVRegR8D, 360) +CV_REGISTER(CVRegR9D, 361) +CV_REGISTER(CVRegR10D, 362) +CV_REGISTER(CVRegR11D, 363) +CV_REGISTER(CVRegR12D, 364) +CV_REGISTER(CVRegR13D, 365) +CV_REGISTER(CVRegR14D, 366) +CV_REGISTER(CVRegR15D, 367) // cvconst.h defines both CV_REG_YMM0 (252) and CV_AMD64_YMM0 (368). Keep the // original prefix to distinguish them. -CV_REGISTER(AMD64_YMM0, 368) -CV_REGISTER(AMD64_YMM1, 369) -CV_REGISTER(AMD64_YMM2, 370) -CV_REGISTER(AMD64_YMM3, 371) -CV_REGISTER(AMD64_YMM4, 372) -CV_REGISTER(AMD64_YMM5, 373) -CV_REGISTER(AMD64_YMM6, 374) -CV_REGISTER(AMD64_YMM7, 375) -CV_REGISTER(AMD64_YMM8, 376) -CV_REGISTER(AMD64_YMM9, 377) -CV_REGISTER(AMD64_YMM10, 378) -CV_REGISTER(AMD64_YMM11, 379) -CV_REGISTER(AMD64_YMM12, 380) -CV_REGISTER(AMD64_YMM13, 381) -CV_REGISTER(AMD64_YMM14, 382) -CV_REGISTER(AMD64_YMM15, 383) +CV_REGISTER(CVRegAMD64_YMM0, 368) +CV_REGISTER(CVRegAMD64_YMM1, 369) +CV_REGISTER(CVRegAMD64_YMM2, 370) +CV_REGISTER(CVRegAMD64_YMM3, 371) +CV_REGISTER(CVRegAMD64_YMM4, 372) +CV_REGISTER(CVRegAMD64_YMM5, 373) +CV_REGISTER(CVRegAMD64_YMM6, 374) +CV_REGISTER(CVRegAMD64_YMM7, 375) +CV_REGISTER(CVRegAMD64_YMM8, 376) +CV_REGISTER(CVRegAMD64_YMM9, 377) +CV_REGISTER(CVRegAMD64_YMM10, 378) +CV_REGISTER(CVRegAMD64_YMM11, 379) +CV_REGISTER(CVRegAMD64_YMM12, 380) +CV_REGISTER(CVRegAMD64_YMM13, 381) +CV_REGISTER(CVRegAMD64_YMM14, 382) +CV_REGISTER(CVRegAMD64_YMM15, 383) diff --git a/include/llvm/DebugInfo/CodeView/CodeViewTypes.def b/include/llvm/DebugInfo/CodeView/CodeViewTypes.def index 69ce9606a670f2cde6dd2cc0bbf5a14d77d72164..e9a479dba496ce466717430ecd29d9eb77c22653 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewTypes.def +++ b/include/llvm/DebugInfo/CodeView/CodeViewTypes.def @@ -87,6 +87,8 @@ TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine) TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList) +TYPE_RECORD(LF_PRECOMP, 0x1509, Precomp) +TYPE_RECORD(LF_ENDPRECOMP, 0x0014, EndPrecomp) // 16 bit type records. CV_TYPE(LF_MODIFIER_16t, 0x0001) @@ -106,7 +108,6 @@ CV_TYPE(LF_NOTTRAN, 0x0010) CV_TYPE(LF_DIMARRAY_16t, 0x0011) CV_TYPE(LF_VFTPATH_16t, 0x0012) CV_TYPE(LF_PRECOMP_16t, 0x0013) -CV_TYPE(LF_ENDPRECOMP, 0x0014) CV_TYPE(LF_OEM_16t, 0x0015) CV_TYPE(LF_TYPESERVER_ST, 0x0016) @@ -181,7 +182,6 @@ CV_TYPE(LF_MANAGED_ST, 0x140f) CV_TYPE(LF_ST_MAX, 0x1500) CV_TYPE(LF_TYPESERVER, 0x1501) CV_TYPE(LF_DIMARRAY, 0x1508) -CV_TYPE(LF_PRECOMP, 0x1509) CV_TYPE(LF_ALIAS, 0x150a) CV_TYPE(LF_DEFARG, 0x150b) CV_TYPE(LF_FRIENDFCN, 0x150c) diff --git a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h index 16d78692c839ab3b3b17d88616bc590770f780df..383f7dd9fb6a7d6e4fadcc5ffe7dc2cd6718dd84 100644 --- a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h +++ b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h @@ -26,7 +26,7 @@ namespace llvm { namespace codeview { -/// \brief Provides amortized O(1) random access to a CodeView type stream. +/// Provides amortized O(1) random access to a CodeView type stream. /// Normally to access a type from a type stream, you must know its byte /// offset into the type stream, because type records are variable-lengthed. /// However, this is not the way we prefer to access them. For example, given diff --git a/include/llvm/DebugInfo/CodeView/TypeHashing.h b/include/llvm/DebugInfo/CodeView/TypeHashing.h index 741337533701ce415a0e310ce17e1dd2b9c11e12..1f732d29a538f95e68bc2710813c91e780b446cc 100644 --- a/include/llvm/DebugInfo/CodeView/TypeHashing.h +++ b/include/llvm/DebugInfo/CodeView/TypeHashing.h @@ -58,7 +58,10 @@ struct LocallyHashedType { } }; -enum class GlobalTypeHashAlg : uint16_t { SHA1 = 0 }; +enum class GlobalTypeHashAlg : uint16_t { + SHA1 = 0, // standard 20-byte SHA1 hash + SHA1_8 // last 8-bytes of standard SHA1 hash +}; /// A globally hashed type represents a hash value that is sufficient to /// uniquely identify a record across multiple type streams or type sequences. @@ -77,10 +80,10 @@ struct GloballyHashedType { GloballyHashedType(StringRef H) : GloballyHashedType(ArrayRef(H.bytes_begin(), H.bytes_end())) {} GloballyHashedType(ArrayRef H) { - assert(H.size() == 20); - ::memcpy(Hash.data(), H.data(), 20); + assert(H.size() == 8); + ::memcpy(Hash.data(), H.data(), 8); } - std::array Hash; + std::array Hash; /// Given a sequence of bytes representing a record, compute a global hash for /// this record. Due to the nature of global hashes incorporating the hashes diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 55f28225c7cbe9a68bd0bb7011ea5f47f944a6a6..61ebdf878ce719c95c37cd319f4519a90c635754 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -896,6 +896,33 @@ public: TypeIndex ContinuationIndex; }; +// LF_PRECOMP +class PrecompRecord : public TypeRecord { +public: + PrecompRecord() = default; + explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + uint32_t getStartTypeIndex() const { return StartTypeIndex; } + uint32_t getTypesCount() const { return TypesCount; } + uint32_t getSignature() const { return Signature; } + StringRef getPrecompFilePath() const { return PrecompFilePath; } + + uint32_t StartTypeIndex; + uint32_t TypesCount; + uint32_t Signature; + StringRef PrecompFilePath; +}; + +// LF_ENDPRECOMP +class EndPrecompRecord : public TypeRecord { +public: + EndPrecompRecord() = default; + explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + uint32_t getSignature() const { return Signature; } + + uint32_t Signature; +}; } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index 59e216abcb11c5959c2c5ff18d056eba2c4fd069..583740d2eb4b78fc31a8ec474277a45b254a8854 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -23,7 +23,7 @@ struct GloballyHashedType; class GlobalTypeTableBuilder; class MergingTypeTableBuilder; -/// \brief Merge one set of type records into another. This method assumes +/// Merge one set of type records into another. This method assumes /// that all records are type records, and there are no Id records present. /// /// \param Dest The table to store the re-written type records into. @@ -40,7 +40,7 @@ Error mergeTypeRecords(MergingTypeTableBuilder &Dest, SmallVectorImpl &SourceToDest, const CVTypeArray &Types); -/// \brief Merge one set of id records into another. This method assumes +/// Merge one set of id records into another. This method assumes /// that all records are id records, and there are no Type records present. /// However, since Id records can refer back to Type records, this method /// assumes that the referenced type records have also been merged into @@ -65,7 +65,7 @@ Error mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef Types, SmallVectorImpl &SourceToDest, const CVTypeArray &Ids); -/// \brief Merge a unified set of type and id records, splitting them into +/// Merge a unified set of type and id records, splitting them into /// separate output streams. /// /// \param DestIds The table to store the re-written id records into. diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 27f11cae0cc3c6bdd5c3825cba355f82b15432a4..741cec3507c910649ab1b6312f57aee6c0b59657 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -239,6 +239,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable { public: class NameIndex; + class NameIterator; class ValueIterator; /// Dwarf 5 Name Index header. @@ -283,6 +284,11 @@ public: Entry(const NameIndex &NameIdx, const Abbrev &Abbr); + public: + Optional getCUOffset() const override; + Optional getDIESectionOffset() const override; + Optional getTag() const override { return tag(); } + /// Returns the Index into the Compilation Unit list of the owning Name /// Index or None if this Accelerator Entry does not have an associated /// Compilation Unit. It is up to the user to verify that the returned Index @@ -293,11 +299,6 @@ public: /// DW_IDX_compile_unit attribute. Optional getCUIndex() const; - public: - Optional getCUOffset() const override; - Optional getDIESectionOffset() const override; - Optional getTag() const override { return tag(); } - /// .debug_names-specific getter, which always succeeds (DWARF v5 index /// entries always have a tag). dwarf::Tag tag() const { return Abbr->Tag; } @@ -319,7 +320,6 @@ public: friend class ValueIterator; }; -private: /// Error returned by NameIndex::getEntry to report it has reached the end of /// the entry list. class SentinelError : public ErrorInfo { @@ -330,6 +330,7 @@ private: std::error_code convertToErrorCode() const override; }; +private: /// DenseMapInfo for struct Abbrev. struct AbbrevMapInfo { static Abbrev getEmptyKey(); @@ -351,9 +352,34 @@ private: public: /// A single entry in the Name Table (Dwarf 5 sect. 6.1.1.4.6) of the Name /// Index. - struct NameTableEntry { - uint32_t StringOffset; ///< Offset of the name of the described entities. - uint32_t EntryOffset; ///< Offset of the first Entry in the list. + class NameTableEntry { + DataExtractor StrData; + + uint32_t Index; + uint32_t StringOffset; + uint32_t EntryOffset; + + public: + NameTableEntry(const DataExtractor &StrData, uint32_t Index, + uint32_t StringOffset, uint32_t EntryOffset) + : StrData(StrData), Index(Index), StringOffset(StringOffset), + EntryOffset(EntryOffset) {} + + /// Return the index of this name in the parent Name Index. + uint32_t getIndex() const { return Index; } + + /// Returns the offset of the name of the described entities. + uint32_t getStringOffset() const { return StringOffset; } + + /// Return the string referenced by this name table entry or nullptr if the + /// string offset is not valid. + const char *getString() const { + uint32_t Off = StringOffset; + return StrData.getCStr(&Off); + } + + /// Returns the offset of the first Entry in the list. + uint32_t getEntryOffset() const { return EntryOffset; } }; /// Represents a single accelerator table within the Dwarf 5 .debug_names @@ -373,14 +399,12 @@ public: uint32_t EntryOffsetsBase; uint32_t EntriesBase; - Expected getEntry(uint32_t *Offset) const; - void dumpCUs(ScopedPrinter &W) const; void dumpLocalTUs(ScopedPrinter &W) const; void dumpForeignTUs(ScopedPrinter &W) const; void dumpAbbreviations(ScopedPrinter &W) const; bool dumpEntry(ScopedPrinter &W, uint32_t *Offset) const; - void dumpName(ScopedPrinter &W, uint32_t Index, + void dumpName(ScopedPrinter &W, const NameTableEntry &NTE, Optional Hash) const; void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const; @@ -429,6 +453,14 @@ public: return Abbrevs; } + Expected getEntry(uint32_t *Offset) const; + + /// Look up all entries in this Name Index matching \c Key. + iterator_range equal_range(StringRef Key) const; + + NameIterator begin() const { return NameIterator(this, 1); } + NameIterator end() const { return NameIterator(this, getNameCount() + 1); } + llvm::Error extract(); uint32_t getUnitOffset() const { return Base; } uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; } @@ -444,6 +476,10 @@ public: /// "NameIndices" vector in the Accelerator section. const NameIndex *CurrentIndex = nullptr; + /// Whether this is a local iterator (searches in CurrentIndex only) or not + /// (searches all name indices). + bool IsLocal; + Optional CurrentEntry; unsigned DataOffset = 0; ///< Offset into the section. std::string Key; ///< The Key we are searching for. @@ -464,6 +500,10 @@ public: /// Indexes in the section in sequence. ValueIterator(const DWARFDebugNames &AccelTable, StringRef Key); + /// Create a "begin" iterator for looping over all entries in a specific + /// Name Index. Other indices in the section will not be visited. + ValueIterator(const NameIndex &NI, StringRef Key); + /// End marker. ValueIterator() = default; @@ -486,8 +526,55 @@ public: } }; + class NameIterator { + + /// The Name Index we are iterating through. + const NameIndex *CurrentIndex; + + /// The current name in the Name Index. + uint32_t CurrentName; + + void next() { + assert(CurrentName <= CurrentIndex->getNameCount()); + ++CurrentName; + } + + public: + using iterator_category = std::input_iterator_tag; + using value_type = NameTableEntry; + using difference_type = uint32_t; + using pointer = NameTableEntry *; + using reference = NameTableEntry; // We return entries by value. + + /// Creates an iterator whose initial position is name CurrentName in + /// CurrentIndex. + NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName) + : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {} + + NameTableEntry operator*() const { + return CurrentIndex->getNameTableEntry(CurrentName); + } + NameIterator &operator++() { + next(); + return *this; + } + NameIterator operator++(int) { + NameIterator I = *this; + next(); + return I; + } + + friend bool operator==(const NameIterator &A, const NameIterator &B) { + return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName; + } + friend bool operator!=(const NameIterator &A, const NameIterator &B) { + return !(A == B); + } + }; + private: SmallVector NameIndices; + DenseMap CUToNameIndex; public: DWARFDebugNames(const DWARFDataExtractor &AccelSection, @@ -503,6 +590,10 @@ public: using const_iterator = SmallVector::const_iterator; const_iterator begin() const { return NameIndices.begin(); } const_iterator end() const { return NameIndices.end(); } + + /// Return the Name Index covering the compile unit at CUOffset, or nullptr if + /// there is no Name Index covering that unit. + const NameIndex *getCUNameIndex(uint32_t CUOffset); }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index a18adf87bf8e1b2886c458aba6dae6866618ffc6..c219ca75e6406a1b42fa9f0323b20b58f9fa9729 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -18,13 +18,13 @@ namespace llvm { class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, - bool IsDWO, const DWARFUnitSectionBase &UnitSection, - const DWARFUnitIndex::Entry *Entry) - : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - UnitSection, Entry) {} + bool IsDWO, const DWARFUnitSectionBase &UnitSection) + : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, + UnitSection) {} // VTable anchor. ~DWARFCompileUnit() override; diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index e842cf231e780d79ab40a1cf380ceba725c9eaa4..6634eedbcd0485fbcced9d5d4b08d3f252565cba 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -259,7 +259,14 @@ public: const AppleAcceleratorTable &getAppleObjC(); /// Get a pointer to a parsed line table corresponding to a compile unit. - const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); + /// Report any parsing issues as warnings on stderr. + const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U); + + /// Get a pointer to a parsed line table corresponding to a compile unit. + /// Report any recoverable parsing problems using the callback. + Expected + getLineTableForUnit(DWARFUnit *U, + std::function RecoverableErrorCallback); DataExtractor getStringExtractor() const { return DataExtractor(DObj->getStringSection(), false, 0); diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index c24364a288419dc4615978b6a29436b3af879705..5b2af34bbcf54513de0c2eef2af0b78861daed9c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -13,9 +13,11 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" +#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/Support/MD5.h" #include #include @@ -103,6 +105,8 @@ public: uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; } + bool totalLengthIsValid() const; + /// Length of the prologue in bytes. uint32_t getLength() const { return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) + @@ -120,8 +124,8 @@ public: void clear(); void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const; - bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, - const DWARFContext &Ctx, const DWARFUnit *U = nullptr); + Error parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + const DWARFContext &Ctx, const DWARFUnit *U = nullptr); }; /// Standard .debug_line state machine structure. @@ -243,9 +247,10 @@ public: void clear(); /// Parse prologue and all rows. - bool parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, - const DWARFContext &Ctx, const DWARFUnit *U, - raw_ostream *OS = nullptr); + Error parse(DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + const DWARFContext &Ctx, const DWARFUnit *U, + std::function RecoverableErrorCallback = warn, + raw_ostream *OS = nullptr); using RowVector = std::vector; using RowIter = RowVector::const_iterator; @@ -259,14 +264,75 @@ public: private: uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, uint64_t Address) const; - Optional getSourceByIndex(uint64_t FileIndex, - DILineInfoSpecifier::FileLineInfoKind Kind) const; + Optional + getSourceByIndex(uint64_t FileIndex, + DILineInfoSpecifier::FileLineInfoKind Kind) const; }; const LineTable *getLineTable(uint32_t Offset) const; - const LineTable *getOrParseLineTable(DWARFDataExtractor &DebugLineData, - uint32_t Offset, const DWARFContext &C, - const DWARFUnit *U); + Expected getOrParseLineTable( + DWARFDataExtractor &DebugLineData, uint32_t Offset, + const DWARFContext &Ctx, const DWARFUnit *U, + std::function RecoverableErrorCallback = warn); + + /// Helper to allow for parsing of an entire .debug_line section in sequence. + class SectionParser { + public: + using cu_range = DWARFUnitSection::iterator_range; + using tu_range = + iterator_range>::iterator>; + using LineToUnitMap = std::map; + + SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs, + tu_range TUs); + + /// Get the next line table from the section. Report any issues via the + /// callbacks. + /// + /// \param RecoverableErrorCallback - any issues that don't prevent further + /// parsing of the table will be reported through this callback. + /// \param UnrecoverableErrorCallback - any issues that prevent further + /// parsing of the table will be reported through this callback. + /// \param OS - if not null, the parser will print information about the + /// table as it parses it. + LineTable + parseNext(function_ref RecoverableErrorCallback = warn, + function_ref UnrecoverableErrorCallback = warn, + raw_ostream *OS = nullptr); + + /// Skip the current line table and go to the following line table (if + /// present) immediately. + /// + /// \param ErrorCallback - report any prologue parsing issues via this + /// callback. + void skip(function_ref ErrorCallback = warn); + + /// Indicates if the parser has parsed as much as possible. + /// + /// \note Certain problems with the line table structure might mean that + /// parsing stops before the end of the section is reached. + bool done() const { return Done; } + + /// Get the offset the parser has reached. + uint32_t getOffset() const { return Offset; } + + private: + DWARFUnit *prepareToParse(uint32_t Offset); + void moveToNextTable(uint32_t OldOffset, const Prologue &P); + + LineToUnitMap LineToUnit; + + DWARFDataExtractor &DebugLineData; + const DWARFContext &Context; + uint32_t Offset = 0; + bool Done = false; + }; + + /// Helper function for DWARFDebugLine parse functions, to report issues + /// identified during parsing. + /// + /// \param Err The Error to report. + static void warn(Error Err); private: struct ParsingState { diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index a6d319a90457f2d3ecb2f3bc9eaa752819cbf95a..9a73745fb6b4d82ed7f5fc0f9f7ac7bd9ce91cf7 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -42,7 +42,8 @@ public: SmallVector Entries; /// Dump this list on OS. void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *MRI, unsigned Indent) const; + const MCRegisterInfo *MRI, uint64_t BaseAddress, + unsigned Indent) const; }; private: diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h index 7579def070da336251c004504980f3865e956b15..49bea290e4365fc78853119e2aa4b581394b90f3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h @@ -10,10 +10,12 @@ #ifndef LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H #define LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include +#include #include namespace llvm { @@ -21,8 +23,48 @@ namespace llvm { class Error; class raw_ostream; -class DWARFDebugRnglists { +/// A class representing a single rangelist. +class DWARFDebugRnglist { +public: + struct RangeListEntry { + /// The offset at which the entry is located in the section. + uint32_t Offset; + /// The DWARF encoding (DW_RLE_*). + uint8_t EntryKind; + /// The index of the section this range belongs to. + uint64_t SectionIndex; + /// The values making up the range list entry. Most represent a range with + /// a start and end address or a start address and a length. Others are + /// single value base addresses or end-of-list with no values. The unneeded + /// values are semantically undefined, but initialized to 0. + uint64_t Value0; + uint64_t Value1; + + Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr); + }; + + using RngListEntries = std::vector; + private: + RngListEntries Entries; + +public: + const RngListEntries &getEntries() const { return Entries; } + bool empty() const { return Entries.empty(); } + void clear() { Entries.clear(); } + Error extract(DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End, + uint32_t *OffsetPtr); + /// Build a DWARFAddressRangesVector from a rangelist. + DWARFAddressRangesVector + getAbsoluteRanges(llvm::Optional BaseAddr) const; +}; + +/// A class representing a table of range lists as specified in DWARF v5. +/// The table consists of a header followed by an array of offsets into the +/// .debug_rnglists section, followed by one or more rangelists. The rangelists +/// are kept in a map where the keys are the lists' section offsets. +class DWARFDebugRnglistTable { +public: struct Header { /// The total length of the entries for this table, not including the length /// field itself. @@ -40,35 +82,44 @@ private: uint32_t OffsetEntryCount; }; -public: - struct RangeListEntry { - /// The offset at which the entry is located in the section. - const uint32_t Offset; - /// The DWARF encoding (DW_RLE_*). - const uint8_t EntryKind; - /// The values making up the range list entry. Most represent a range with - /// a start and end address or a start address and a length. Others are - /// single value base addresses or end-of-list with no values. The unneeded - /// values are semantically undefined, but initialized to 0. - const uint64_t Value0; - const uint64_t Value1; - }; - - using DWARFRangeList = std::vector; - private: + dwarf::DwarfFormat Format; uint32_t HeaderOffset; Header HeaderData; std::vector Offsets; - std::vector Ranges; - // The length of the longest encoding string we encountered during parsing. - uint8_t MaxEncodingStringLength = 0; + std::map Ranges; public: void clear(); + /// Extract the table header and the array of offsets. + Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr); + /// Extract an entire table, including all rangelists. Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr); + /// Look up a rangelist based on a given offset. Extract it and enter it into + /// the ranges map if necessary. + Optional findRangeList(DWARFDataExtractor Data, + uint32_t Offset); uint32_t getHeaderOffset() const { return HeaderOffset; } + uint8_t getAddrSize() const { return HeaderData.AddrSize; } void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const; + /// Return the contents of the offset entry designated by a given index. + Optional getOffsetEntry(uint32_t Index) const { + if (Index < Offsets.size()) + return Offsets[Index]; + return None; + } + /// Return the size of the table header including the length but not including + /// the offsets. This is dependent on the table format, which is unambiguously + /// derived from parsing the table. + uint8_t getHeaderSize() const { + switch (Format) { + case dwarf::DwarfFormat::DWARF32: + return 12; + case dwarf::DwarfFormat::DWARF64: + return 20; + } + llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64"); + } /// Returns the length of this table, including the length field, or 0 if the /// length has not been determined (e.g. because the table has not yet been diff --git a/include/llvm/DebugInfo/DWARF/DWARFObject.h b/include/llvm/DebugInfo/DWARF/DWARFObject.h index 795eddd1c5dbca7e357f3cd12e858d29a4e8f758..6e8f370f4aeafed9080b646e187d56590b4315b6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFObject.h +++ b/include/llvm/DebugInfo/DWARF/DWARFObject.h @@ -63,6 +63,7 @@ public: return Dummy; } virtual const DWARFSection &getRangeDWOSection() const { return Dummy; } + virtual const DWARFSection &getRnglistsDWOSection() const { return Dummy; } virtual const DWARFSection &getAddrSection() const { return Dummy; } virtual const DWARFSection &getAppleNamesSection() const { return Dummy; } virtual const DWARFSection &getAppleTypesSection() const { return Dummy; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index a659a6395231f907f0945322f55525e33c35fb7d..cb5a78ee3dbffcd24bebff279407fbfa077f679b 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -24,30 +24,21 @@ struct DWARFSection; class raw_ostream; class DWARFTypeUnit : public DWARFUnit { -private: - uint64_t TypeHash; - uint32_t TypeOffset; - public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, - const DWARFUnitIndex::Entry *Entry) - : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - UnitSection, Entry) {} + const DWARFUnitSectionBase &UnitSection) + : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, + UnitSection) {} - uint32_t getHeaderSize() const override { - return DWARFUnit::getHeaderSize() + 12; - } + uint64_t getTypeHash() const { return getHeader().getTypeHash(); } + uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); } void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}); static const DWARFSectionKind Section = DW_SECT_TYPES; - -protected: - bool extractImpl(const DWARFDataExtractor &debug_info, - uint32_t *offset_ptr) override; }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index fe3f573427b15422e000bc7d59436bf303c67819..b6ea11ec88e4c3b4268f0099fe148772554f6d28 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -18,6 +18,7 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" @@ -40,6 +41,66 @@ class DWARFContext; class DWARFDebugAbbrev; class DWARFUnit; +/// Base class describing the header of any kind of "unit." Some information +/// is specific to certain unit types. We separate this class out so we can +/// parse the header before deciding what specific kind of unit to construct. +class DWARFUnitHeader { + // Offset within section. + uint32_t Offset = 0; + // Version, address size, and DWARF format. + dwarf::FormParams FormParams; + uint32_t Length = 0; + uint64_t AbbrOffset = 0; + + // For DWO units only. + const DWARFUnitIndex::Entry *IndexEntry = nullptr; + + // For type units only. + uint64_t TypeHash = 0; + uint32_t TypeOffset = 0; + + // For v5 split or skeleton compile units only. + Optional DWOId; + + // Unit type as parsed, or derived from the section kind. + uint8_t UnitType = 0; + + // Size as parsed. uint8_t for compactness. + uint8_t Size = 0; + +public: + /// Parse a unit header from \p debug_info starting at \p offset_ptr. + bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, + uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO, + const DWARFUnitIndex *Index = nullptr); + uint32_t getOffset() const { return Offset; } + const dwarf::FormParams &getFormParams() const { return FormParams; } + uint16_t getVersion() const { return FormParams.Version; } + dwarf::DwarfFormat getFormat() const { return FormParams.Format; } + uint8_t getAddressByteSize() const { return FormParams.AddrSize; } + uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); } + uint8_t getDwarfOffsetByteSize() const { + return FormParams.getDwarfOffsetByteSize(); + } + uint32_t getLength() const { return Length; } + uint64_t getAbbrOffset() const { return AbbrOffset; } + Optional getDWOId() const { return DWOId; } + void setDWOId(uint64_t Id) { + assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value"); + DWOId = Id; + } + const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; } + uint64_t getTypeHash() const { return TypeHash; } + uint32_t getTypeOffset() const { return TypeOffset; } + uint8_t getUnitType() const { return UnitType; } + bool isTypeUnit() const { + return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type; + } + uint8_t getSize() const { return Size; } + // FIXME: Support DWARF64. + uint32_t getNextUnitOffset() const { return Offset + Length + 4; } +}; + /// Base class for all DWARFUnitSection classes. This provides the /// functionality common to all unit types. class DWARFUnitSectionBase { @@ -133,11 +194,12 @@ private: &LS](uint32_t Offset) -> std::unique_ptr { if (!Data.isValidOffset(Offset)) return nullptr; - auto U = llvm::make_unique( - Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, *this, - Index ? Index->getFromOffset(Offset) : nullptr); - if (!U->extract(Data, &Offset)) + DWARFUnitHeader Header; + if (!Header.extract(Context, Data, &Offset, UnitType::Section, Index)) return nullptr; + auto U = llvm::make_unique( + Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, + *this); return U; }; } @@ -169,6 +231,7 @@ struct BaseAddress { /// Represents a unit's contribution to the string offsets table. struct StrOffsetsContributionDescriptor { uint64_t Base = 0; + /// The contribution size not including the header. uint64_t Size = 0; /// Format and version. dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32}; @@ -194,6 +257,7 @@ class DWARFUnit { /// Section containing this DWARFUnit. const DWARFSection &InfoSection; + DWARFUnitHeader Header; const DWARFDebugAbbrev *Abbrev; const DWARFSection *RangeSection; uint32_t RangeSectionBase; @@ -206,17 +270,14 @@ class DWARFUnit { bool isDWO; const DWARFUnitSectionBase &UnitSection; - // Version, address size, and DWARF format. - dwarf::FormParams FormParams; /// Start, length, and DWARF format of the unit's contribution to the string /// offsets table (DWARF v5). Optional StringOffsetsTableContribution; - uint32_t Offset; - uint32_t Length; + /// A table of range lists (DWARF v5 and later). + Optional RngListTable; + mutable const DWARFAbbreviationDeclarationSet *Abbrevs; - uint64_t AbbrOffset; - uint8_t UnitType; llvm::Optional BaseAddr; /// The compile unit debug information entry items. std::vector DieArray; @@ -231,8 +292,6 @@ class DWARFUnit { std::shared_ptr DWO; - const DWARFUnitIndex::Entry *IndexEntry; - uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) { auto First = DieArray.data(); assert(Die >= First && Die < First + DieArray.size()); @@ -240,11 +299,10 @@ class DWARFUnit { } protected: - virtual bool extractImpl(const DWARFDataExtractor &debug_info, - uint32_t *offset_ptr); + const DWARFUnitHeader &getHeader() const { return Header; } - /// Size in bytes of the unit header. - virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; } + /// Size in bytes of the parsed unit header. + uint32_t getHeaderSize() const { return Header.getSize(); } /// Find the unit's contribution to the string offsets table and determine its /// length and form. The given offset is expected to be derived from the unit @@ -263,16 +321,28 @@ protected: public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, + const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, - const DWARFUnitIndex::Entry *IndexEntry = nullptr); + const DWARFUnitSectionBase &UnitSection); virtual ~DWARFUnit(); DWARFContext& getContext() const { return Context; } - + uint32_t getOffset() const { return Header.getOffset(); } + const dwarf::FormParams &getFormParams() const { + return Header.getFormParams(); + } + uint16_t getVersion() const { return Header.getVersion(); } + uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); } + uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); } + uint8_t getDwarfOffsetByteSize() const { + return Header.getDwarfOffsetByteSize(); + } + uint32_t getLength() const { return Header.getLength(); } + uint8_t getUnitType() const { return Header.getUnitType(); } + uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); } const DWARFSection &getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } const DWARFSection &getStringOffsetSection() const { @@ -301,30 +371,17 @@ public: return DataExtractor(StringSection, false, 0); } - bool extract(const DWARFDataExtractor &debug_info, uint32_t *offset_ptr); - /// extractRangeList - extracts the range list referenced by this compile /// unit from .debug_ranges section. Returns true on success. /// Requires that compile unit is already extracted. bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const; void clear(); - uint32_t getOffset() const { return Offset; } - uint32_t getNextUnitOffset() const { return Offset + Length + 4; } - uint32_t getLength() const { return Length; } const Optional & getStringOffsetsTableContribution() const { return StringOffsetsTableContribution; } - const dwarf::FormParams &getFormParams() const { return FormParams; } - uint16_t getVersion() const { return FormParams.Version; } - dwarf::DwarfFormat getFormat() const { return FormParams.Format; } - uint8_t getAddressByteSize() const { return FormParams.AddrSize; } - uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); } - uint8_t getDwarfOffsetByteSize() const { - return FormParams.getDwarfOffsetByteSize(); - } uint8_t getDwarfStringOffsetsByteSize() const { assert(StringOffsetsTableContribution); @@ -338,8 +395,6 @@ public: const DWARFAbbreviationDeclarationSet *getAbbreviations() const; - uint8_t getUnitType() const { return UnitType; } - static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) { switch (UnitType) { case dwarf::DW_UT_compile: @@ -357,7 +412,7 @@ public: return false; } - /// \brief Return the number of bytes for the header of a unit of + /// Return the number of bytes for the header of a unit of /// UnitType type. /// /// This function must be called with a valid unit type which in @@ -377,9 +432,7 @@ public: llvm_unreachable("Invalid UnitType."); } - llvm::Optional getBaseAddress() const { return BaseAddr; } - - void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; } + llvm::Optional getBaseAddress(); DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { extractDIEsIfNeeded(ExtractUnitDIEOnly); @@ -389,7 +442,26 @@ public: } const char *getCompilationDir(); - Optional getDWOId(); + Optional getDWOId() const { return getHeader().getDWOId(); } + void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); } + + /// Return a vector of address ranges resulting from a (possibly encoded) + /// range list starting at a given offset in the appropriate ranges section. + DWARFAddressRangesVector findRnglistFromOffset(uint32_t Offset); + + /// Return a vector of address ranges retrieved from an encoded range + /// list whose offset is found via a table lookup given an index (DWARF v5 + /// and later). + DWARFAddressRangesVector findRnglistFromIndex(uint32_t Index); + + /// Return a rangelist's offset based on an index. The index designates + /// an entry in the rangelist table's offset array and is supplied by + /// DW_FORM_rnglistx. + Optional getRnglistOffset(uint32_t Index) { + if (RngListTable) + return RngListTable->getOffsetEntry(Index); + return None; + } void collectAddressRanges(DWARFAddressRangesVector &CURanges); @@ -407,14 +479,14 @@ public: /// getUnitSection - Return the DWARFUnitSection containing this unit. const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; } - /// \brief Returns the number of DIEs in the unit. Parses the unit + /// Returns the number of DIEs in the unit. Parses the unit /// if necessary. unsigned getNumDIEs() { extractDIEsIfNeeded(false); return DieArray.size(); } - /// \brief Return the index of a DIE inside the unit's DIE vector. + /// Return the index of a DIE inside the unit's DIE vector. /// /// It is illegal to call this method with a DIE that hasn't be /// created by this unit. In other word, it's illegal to call this @@ -424,7 +496,7 @@ public: return getDIEIndex(D.getDebugInfoEntry()); } - /// \brief Return the DIE object at the given index. + /// Return the DIE object at the given index. DWARFDie getDIEAtIndex(unsigned Index) { assert(Index < DieArray.size()); return DWARFDie(this, &DieArray[Index]); @@ -434,7 +506,7 @@ public: DWARFDie getSibling(const DWARFDebugInfoEntry *Die); DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die); - /// \brief Return the DIE object for a given offset inside the + /// Return the DIE object for a given offset inside the /// unit's DIE vector. /// /// The unit needs to have its DIEs extracted for this method to work. @@ -452,7 +524,7 @@ public: } uint32_t getLineTableOffset() const { - if (IndexEntry) + if (auto IndexEntry = Header.getIndexEntry()) if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE)) return Contrib->Offset; return 0; @@ -465,7 +537,9 @@ public: private: /// Size in bytes of the .debug_info data associated with this compile unit. - size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); } + size_t getDebugInfoSize() const { + return Header.getLength() + 4 - getHeaderSize(); + } /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it /// hasn't already been done. Returns the number of DIEs parsed at this call. diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h index afaa299262daa25076b68246b466a531d3ad676e..71bf8f9b24d8f0758f7918979a1ef899d3a59fc5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -25,6 +25,7 @@ struct DWARFAttribute; class DWARFContext; class DWARFDie; class DWARFUnit; +class DWARFCompileUnit; class DWARFDataExtractor; class DWARFDebugAbbrev; class DataExtractor; @@ -240,6 +241,10 @@ private: unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr, DWARFDebugNames::AttributeEncoding AttrEnc); + unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI, + const DWARFDebugNames::NameTableEntry &NTE); + unsigned verifyNameIndexCompleteness(const DWARFDie &Die, + const DWARFDebugNames::NameIndex &NI); /// Verify that the DWARF v5 accelerator table is valid. /// @@ -251,6 +256,8 @@ private: /// - The buckets have a valid index, or they are empty. /// - All names are reachable via the hash table (they have the correct hash, /// and the hash is in the correct bucket). + /// - Information in the index entries is complete (all required entries are + /// present) and consistent with the debug_info section DIEs. /// /// \param AccelSection section containing the acceleration table /// \param StrData string section diff --git a/include/llvm/DebugInfo/MSF/MSFBuilder.h b/include/llvm/DebugInfo/MSF/MSFBuilder.h index 19e5c31b30764e4eeb20a50f80362fb1d79f4090..c06a0b4687d47851fdad39c2970c9194a8fa0d41 100644 --- a/include/llvm/DebugInfo/MSF/MSFBuilder.h +++ b/include/llvm/DebugInfo/MSF/MSFBuilder.h @@ -24,7 +24,7 @@ namespace msf { class MSFBuilder { public: - /// \brief Create a new `MSFBuilder`. + /// Create a new `MSFBuilder`. /// /// \param BlockSize The internal block size used by the PDB file. See /// isValidBlockSize() for a list of valid block sizes. diff --git a/include/llvm/DebugInfo/MSF/MSFCommon.h b/include/llvm/DebugInfo/MSF/MSFCommon.h index dd532647b71a368d3ac395d0f2b5e2f36c5093a0..2db2b71df4a7433481591f99a9132065c2fec4a8 100644 --- a/include/llvm/DebugInfo/MSF/MSFCommon.h +++ b/include/llvm/DebugInfo/MSF/MSFCommon.h @@ -69,7 +69,7 @@ struct MSFLayout { std::vector> StreamMap; }; -/// \brief Describes the layout of a stream in an MSF layout. A "stream" here +/// Describes the layout of a stream in an MSF layout. A "stream" here /// is defined as any logical unit of data which may be arranged inside the MSF /// file as a sequence of (possibly discontiguous) blocks. When we want to read /// from a particular MSF Stream, we fill out a stream layout structure and the @@ -81,7 +81,7 @@ public: std::vector Blocks; }; -/// \brief Determine the layout of the FPM stream, given the MSF layout. An FPM +/// Determine the layout of the FPM stream, given the MSF layout. An FPM /// stream spans 1 or more blocks, each at equally spaced intervals throughout /// the file. MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf, diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h index 5c37d9bc63cfe922854ba758827c77c8281934c7..52c9563b5d5f76e7cc698b615e776c52f2110cdd 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h @@ -34,7 +34,7 @@ private: const DIASession &Session; CComPtr Enumerator; }; -} -} +} // namespace pdb +} // namespace llvm #endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMSECTIONCONTRIBS_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h b/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h index 7bc28e30d70c2b73732fb82127c31354a9d18c33..4688f1f91a89b308c3eae68608b75192a5a39fc9 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h @@ -49,7 +49,7 @@ private: const DIASession &Session; CComPtr Section; }; -} -} +} // namespace pdb +} // namespace llvm #endif // LLVM_DEBUGINFO_PDB_DIA_DIASECTIONCONTRIB_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index 4f3d72816f3743dae132b6966bb49aa608c58422..a636594393893a9be23cc1e09736fc69d8de542b 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -41,6 +41,11 @@ public: std::unique_ptr findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override; + std::unique_ptr findSymbolByRVA(uint32_t RVA, + PDB_SymType Type) const override; + std::unique_ptr + findSymbolBySectOffset(uint32_t Section, uint32_t Offset, + PDB_SymType Type) const override; std::unique_ptr findLineNumbers(const PDBSymbolCompiland &Compiland, diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h index 3b4a348289df94e4414e13af9027ecef23630376..92ebc04ae5a4ae465507fbb250520d48e78aa7da 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h @@ -22,14 +22,6 @@ #define NOMINMAX #endif -// llvm/Support/Debug.h unconditionally #defines DEBUG as a macro. -// DIA headers #define it if it is not already defined, so we have -// an order of includes problem. The real fix is to make LLVM use -// something less generic than DEBUG, such as LLVM_DEBUG(), but it's -// fairly prevalent. So for now, we save the definition state and -// restore it. -#pragma push_macro("DEBUG") - // atlbase.h has to come before windows.h #include #include @@ -39,6 +31,4 @@ #include #include -#pragma pop_macro("DEBUG") - #endif // LLVM_DEBUGINFO_PDB_DIA_DIASUPPORT_H diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 695d62c7216fe8f14116c54ce58ddf26c69bb366..88ec517bc4a559ca045059c80d123b3c139311bb 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -44,6 +44,11 @@ public: virtual std::unique_ptr findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0; + virtual std::unique_ptr + findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const = 0; + virtual std::unique_ptr + findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) const = 0; virtual std::unique_ptr findLineNumbers(const PDBSymbolCompiland &Compiland, diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h index 8200f51e3da9d2b6bfb5f464d6796fb8adb8709a..9eef4041d0a1ecb401c0ad5e413c6ad39eefb5dc 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h @@ -47,6 +47,8 @@ public: uint32_t getRecordLength() const; + const SectionContrib &getSectionContrib() const; + private: StringRef ModuleName; StringRef ObjFileName; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index c918a5d5e976d4da3a4d0e89b4b48313e2429988..ce4d07917755c1d7eac87ad7c3e4dfdb0a23a7c7 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -49,6 +49,7 @@ public: void setPdbFilePathNI(uint32_t NI); void setObjFileName(StringRef Name); + void setFirstSectionContrib(const SectionContrib &SC); void addSymbol(codeview::CVSymbol Symbol); void diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 760d19ac3f801aadbce3860461dc3c301a61b27e..280615bdb50794ee0c807c2ff664fe26478608a6 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -38,9 +38,9 @@ class DbiStream { friend class DbiStreamBuilder; public: - DbiStream(PDBFile &File, std::unique_ptr Stream); + explicit DbiStream(std::unique_ptr Stream); ~DbiStream(); - Error reload(); + Error reload(PDBFile *Pdb); PdbRaw_DbiVer getDbiVersion() const; uint32_t getAge() const; @@ -89,12 +89,11 @@ public: private: Error initializeSectionContributionData(); - Error initializeSectionHeadersData(); + Error initializeSectionHeadersData(PDBFile *Pdb); Error initializeSectionMapData(); - Error initializeFpoRecords(); + Error initializeFpoRecords(PDBFile *Pdb); - PDBFile &Pdb; - std::unique_ptr Stream; + std::unique_ptr Stream; PDBStringTable ECNames; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index daea062ca6408b6d7c0ccc7407cf51215ac6e378..51befcdac775e346b6bbed66657e97f59a65cead 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -12,6 +12,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSet.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/Support/Error.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -46,10 +47,12 @@ public: void setVersionHeader(PdbRaw_DbiVer V); void setAge(uint32_t A); void setBuildNumber(uint16_t B); + void setBuildNumber(uint8_t Major, uint8_t Minor); void setPdbDllVersion(uint16_t V); void setPdbDllRbld(uint16_t R); void setFlags(uint16_t F); void setMachineType(PDB_Machine M); + void setMachineType(COFF::MachineTypes M); void setSectionMap(ArrayRef SecMap); // Add given bytes as a new stream. diff --git a/include/llvm/DebugInfo/PDB/Native/InfoStream.h b/include/llvm/DebugInfo/PDB/Native/InfoStream.h index caeb423af7242e43ccbb75e289e84d05b16930e8..8c52b042f289ae1376ebcaa0912ab0f4724f7888 100644 --- a/include/llvm/DebugInfo/PDB/Native/InfoStream.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStream.h @@ -30,7 +30,7 @@ class InfoStream { friend class InfoStreamBuilder; public: - InfoStream(std::unique_ptr Stream); + InfoStream(std::unique_ptr Stream); Error reload(); @@ -52,11 +52,11 @@ public: BinarySubstreamRef getNamedStreamsBuffer() const; - uint32_t getNamedStreamIndex(llvm::StringRef Name) const; + Expected getNamedStreamIndex(llvm::StringRef Name) const; StringMap named_streams() const; private: - std::unique_ptr Stream; + std::unique_ptr Stream; const InfoStreamHeader *Header; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index 60a94d9b70207f45e4a8b9970834c1fc7b3082d4..aff7ef2f8f21eb9835a2703d10dadb24c025d126 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -60,6 +60,11 @@ public: std::unique_ptr findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override; + std::unique_ptr findSymbolByRVA(uint32_t RVA, + PDB_SymType Type) const override; + std::unique_ptr + findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) const override; std::unique_ptr findLineNumbers(const PDBSymbolCompiland &Compiland, diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 5cc8821f72926c08be88ed7a46c77fac6331a023..19f592d562e4414fd20bc3c83de229e58fb8d226 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -112,6 +112,8 @@ struct DbiBuildNo { static const uint16_t BuildMajorMask = 0x7F00; static const uint16_t BuildMajorShift = 8; + + static const uint16_t NewVersionFormatMask = 0x8000; }; /// The fixed size header that appears at the beginning of the DBI Stream. @@ -175,18 +177,6 @@ struct DbiStreamHeader { }; static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!"); -struct SectionContribEntry { - support::ulittle16_t Section; - char Padding1[2]; - support::little32_t Offset; - support::little32_t Size; - support::ulittle32_t Characteristics; - support::ulittle16_t ModuleIndex; - char Padding2[2]; - support::ulittle32_t DataCrc; - support::ulittle32_t RelocCrc; -}; - /// The header preceeding the File Info Substream of the DBI stream. struct FileInfoSubstreamHeader { /// Total # of modules, should match number of records in the ModuleInfo @@ -228,7 +218,7 @@ struct ModuleInfoHeader { support::ulittle32_t Mod; /// First section contribution of this module. - SectionContribEntry SC; + SectionContrib SC; /// See ModInfoFlags definition. support::ulittle16_t Flags; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h index d6013e22992939249eb6c8d94f7e421b7b5797a4..05d585d2576320c0f07b5abc09af5b20e32763bc 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h @@ -39,7 +39,9 @@ public: FORWARD_SYMBOL_METHOD(getAddressSection) FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(isCompilerGenerated) + FORWARD_SYMBOL_METHOD(isConstructorVirtualBase) FORWARD_SYMBOL_METHOD(isConstType) + FORWARD_SYMBOL_METHOD(isCxxReturnUdt) FORWARD_SYMBOL_METHOD(hasCustomCallingConvention) FORWARD_SYMBOL_METHOD(hasFarReturn) FORWARD_SYMBOL_METHOD(hasAlloca) diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index bc6233ac79047f93d497886614ea7462b2cbd242..da6cb1d2677105c6c697752e642d4fdff8d5d376 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -111,7 +111,7 @@ enum PDB_NameSearchFlags { /// Specifies the hash algorithm that a source file from a PDB was hashed with. /// This corresponds to the CV_SourceChksum_t enumeration and are documented /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx -enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 }; +enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 }; /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx @@ -225,6 +225,7 @@ enum class PDB_LocType { IlRel, MetaData, Constant, + RegRelAliasIndir, Max }; @@ -234,11 +235,24 @@ enum class PDB_UdtType { Struct, Class, Union, Interface }; /// These values correspond to the StackFrameTypeEnum enumeration, and are /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. -enum class PDB_StackFrameType { FPO, KernelTrap, KernelTSS, EBP, FrameData }; +enum class PDB_StackFrameType : uint16_t { + FPO, + KernelTrap, + KernelTSS, + EBP, + FrameData, + Unknown = 0xffff +}; -/// These values correspond to the StackFrameTypeEnum enumeration, and are -/// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. -enum class PDB_MemoryType { Code, Data, Stack, HeapCode }; +/// These values correspond to the MemoryTypeEnum enumeration, and are +/// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx. +enum class PDB_MemoryType : uint16_t { + Code, + Data, + Stack, + HeapCode, + Any = 0xffff +}; /// These values correspond to the Basictype enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx @@ -268,7 +282,7 @@ enum class PDB_BuiltinType { /// These values correspond to the flags that can be combined to control the /// return of an undecorated name for a C++ decorated name, and are documented /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx -enum PDB_UndnameFlags: uint32_t { +enum PDB_UndnameFlags : uint32_t { Undname_Complete = 0x0, Undname_NoLeadingUnderscores = 0x1, Undname_NoMsKeywords = 0x2, diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h index 6480aef109c66885fdd9dc87c556291254c7e34c..289148f569db63d0a27a10ff4cfc58e6c874e7cf 100644 --- a/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -90,11 +90,11 @@ private: const ObjectFile *Obj, const std::string &ArchName); - /// \brief Returns pair of pointers to object and debug object. + /// Returns pair of pointers to object and debug object. Expected getOrCreateObjectPair(const std::string &Path, const std::string &ArchName); - /// \brief Return a pointer to object file at specified path, for a specified + /// Return a pointer to object file at specified path, for a specified /// architecture (e.g. if path refers to a Mach-O universal binary, only one /// object file from it will be returned). Expected getOrCreateObject(const std::string &Path, @@ -102,14 +102,14 @@ private: std::map> Modules; - /// \brief Contains cached results of getOrCreateObjectPair(). + /// Contains cached results of getOrCreateObjectPair(). std::map, ObjectPair> ObjectPairForPathArch; - /// \brief Contains parsed binary for each path, or parsing error. + /// Contains parsed binary for each path, or parsing error. std::map> BinaryForPath; - /// \brief Parsed object file for path/architecture pair, where "path" refers + /// Parsed object file for path/architecture pair, where "path" refers /// to Mach-O universal binary. std::map, std::unique_ptr> ObjectForUBPathAndArch; diff --git a/include/llvm/Demangle/Compiler.h b/include/llvm/Demangle/Compiler.h index c996f9b71e5b25a2d5ed0d25cbc7e6c163412af5..1fb3c5e92c34a2d3916eb89c035ac023c022dc81 100644 --- a/include/llvm/Demangle/Compiler.h +++ b/include/llvm/Demangle/Compiler.h @@ -42,7 +42,7 @@ #endif /// \macro LLVM_GNUC_PREREQ -/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't +/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't /// available. #ifndef LLVM_GNUC_PREREQ # if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) @@ -58,7 +58,7 @@ #endif /// \macro LLVM_MSC_PREREQ -/// \brief Is the compiler MSVC of at least the specified version? +/// Is the compiler MSVC of at least the specified version? /// The common \param version values to check for are: /// * 1900: Microsoft Visual Studio 2015 / 14.0 #ifdef _MSC_VER @@ -73,7 +73,7 @@ #define LLVM_MSC_PREREQ(version) 0 #endif -/// \brief Does the compiler support ref-qualifiers for *this? +/// Does the compiler support ref-qualifiers for *this? /// /// Sadly, this is separate from just rvalue reference support because GCC /// and MSVC implemented this later than everything else. @@ -99,7 +99,7 @@ /// functions, making them private to any shared library they are linked into. /// On PE/COFF targets, library visibility is the default, so this isn't needed. #if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ - !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32) + !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #else #define LLVM_LIBRARY_VISIBILITY @@ -146,7 +146,7 @@ // FIXME: Provide this for PE/COFF targets. #if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ - (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)) + (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)) #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else #define LLVM_ATTRIBUTE_WEAK @@ -303,7 +303,7 @@ #endif /// \macro LLVM_ASSUME_ALIGNED -/// \brief Returns a pointer with an assumed alignment. +/// Returns a pointer with an assumed alignment. #if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) @@ -315,7 +315,7 @@ #endif /// \macro LLVM_ALIGNAS -/// \brief Used to specify a minimum alignment for a structure or variable. +/// Used to specify a minimum alignment for a structure or variable. #if __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 1) # define LLVM_ALIGNAS(x) __attribute__((aligned(x))) #else @@ -323,7 +323,7 @@ #endif /// \macro LLVM_PACKED -/// \brief Used to specify a packed structure. +/// Used to specify a packed structure. /// LLVM_PACKED( /// struct A { /// int i; @@ -351,7 +351,7 @@ #endif /// \macro LLVM_PTR_SIZE -/// \brief A constant integer equivalent to the value of sizeof(void*). +/// A constant integer equivalent to the value of sizeof(void*). /// Generally used in combination with LLVM_ALIGNAS or when doing computation in /// the preprocessor. #ifdef __SIZEOF_POINTER__ @@ -367,7 +367,7 @@ #endif /// \macro LLVM_MEMORY_SANITIZER_BUILD -/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation. +/// Whether LLVM itself is built with MemorySanitizer instrumentation. #if __has_feature(memory_sanitizer) # define LLVM_MEMORY_SANITIZER_BUILD 1 # include @@ -378,7 +378,7 @@ #endif /// \macro LLVM_ADDRESS_SANITIZER_BUILD -/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation. +/// Whether LLVM itself is built with AddressSanitizer instrumentation. #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) # define LLVM_ADDRESS_SANITIZER_BUILD 1 # include @@ -389,7 +389,7 @@ #endif /// \macro LLVM_THREAD_SANITIZER_BUILD -/// \brief Whether LLVM itself is built with ThreadSanitizer instrumentation. +/// Whether LLVM itself is built with ThreadSanitizer instrumentation. #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) # define LLVM_THREAD_SANITIZER_BUILD 1 #else @@ -432,14 +432,14 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif /// \macro LLVM_NO_SANITIZE -/// \brief Disable a particular sanitizer for a function. +/// Disable a particular sanitizer for a function. #if __has_attribute(no_sanitize) #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND))) #else #define LLVM_NO_SANITIZE(KIND) #endif -/// \brief Mark debug helper function definitions like dump() that should not be +/// Mark debug helper function definitions like dump() that should not be /// stripped from debug builds. /// Note that you should also surround dump() functions with /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always @@ -452,7 +452,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif /// \macro LLVM_PRETTY_FUNCTION -/// \brief Gets a user-friendly looking function signature for the current scope +/// Gets a user-friendly looking function signature for the current scope /// using the best available method on each platform. The exact format of the /// resulting string is implementation specific and non-portable, so this should /// only be used, for example, for logging or diagnostics. @@ -465,7 +465,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif /// \macro LLVM_THREAD_LOCAL -/// \brief A thread-local storage specifier which can be used with globals, +/// A thread-local storage specifier which can be used with globals, /// extern globals, and static globals. /// /// This is essentially an extremely restricted analog to C++11's thread_local @@ -494,7 +494,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif /// \macro LLVM_ENABLE_EXCEPTIONS -/// \brief Whether LLVM is built with exception support. +/// Whether LLVM is built with exception support. #if __has_feature(cxx_exceptions) #define LLVM_ENABLE_EXCEPTIONS 1 #elif defined(__GNUC__) && defined(__EXCEPTIONS) diff --git a/include/llvm/Demangle/Demangle.h b/include/llvm/Demangle/Demangle.h index d2eb56b39f9b80fded16044c47c7719f60406dfa..8203d539fdc44be7d2bb1f30ee935335b20345f2 100644 --- a/include/llvm/Demangle/Demangle.h +++ b/include/llvm/Demangle/Demangle.h @@ -25,4 +25,60 @@ namespace llvm { char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status); -} + +/// "Partial" demangler. This supports demangling a string into an AST +/// (typically an intermediate stage in itaniumDemangle) and querying certain +/// properties or partially printing the demangled name. +struct ItaniumPartialDemangler { + ItaniumPartialDemangler(); + + ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); + ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other); + + /// Demangle into an AST. Subsequent calls to the rest of the member functions + /// implicitly operate on the AST this produces. + /// \return true on error, false otherwise + bool partialDemangle(const char *MangledName); + + /// Just print the entire mangled name into Buf. Buf and N behave like the + /// second and third parameters to itaniumDemangle. + char *finishDemangle(char *Buf, size_t *N) const; + + /// Get the base name of a function. This doesn't include trailing template + /// arguments, ie for "a::b" this function returns "b". + char *getFunctionBaseName(char *Buf, size_t *N) const; + + /// Get the context name for a function. For "a::b::c", this function returns + /// "a::b". + char *getFunctionDeclContextName(char *Buf, size_t *N) const; + + /// Get the entire name of this function. + char *getFunctionName(char *Buf, size_t *N) const; + + /// Get the parameters for this function. + char *getFunctionParameters(char *Buf, size_t *N) const; + char *getFunctionReturnType(char *Buf, size_t *N) const; + + /// If this function has any any cv or reference qualifiers. These imply that + /// the function is a non-static member function. + bool hasFunctionQualifiers() const; + + /// If this symbol describes a constructor or destructor. + bool isCtorOrDtor() const; + + /// If this symbol describes a function. + bool isFunction() const; + + /// If this symbol describes a variable. + bool isData() const; + + /// If this symbol is a . These are generally implicitly + /// generated by the implementation, such as vtables and typeinfo names. + bool isSpecialName() const; + + ~ItaniumPartialDemangler(); +private: + void *RootNode; + void *Context; +}; +} // namespace llvm diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 7932688290e354467e1297ffb87b381bd62a0bd5..b61cb24fa5fb5e6afcc90f484b76c82648172da3 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -60,7 +60,7 @@ class ObjectFile; } // end namespace object -/// \brief Helper class for helping synchronize access to the global address map +/// Helper class for helping synchronize access to the global address map /// table. Access to this class should be serialized under a mutex. class ExecutionEngineState { public: @@ -86,7 +86,7 @@ public: return GlobalAddressReverseMap; } - /// \brief Erase an entry from the mapping table. + /// Erase an entry from the mapping table. /// /// \returns The address that \p ToUnmap was happed to. uint64_t RemoveMapping(StringRef Name); @@ -94,7 +94,7 @@ public: using FunctionCreator = std::function; -/// \brief Abstract interface for implementation execution of LLVM modules, +/// Abstract interface for implementation execution of LLVM modules, /// designed to support both interpreter and just-in-time (JIT) compiler /// implementations. class ExecutionEngine { @@ -634,7 +634,7 @@ public: return *this; } - // \brief Use OrcMCJITReplacement instead of MCJIT. Off by default. + // Use OrcMCJITReplacement instead of MCJIT. Off by default. void setUseOrcMCJITReplacement(bool UseOrcMCJITReplacement) { this->UseOrcMCJITReplacement = UseOrcMCJITReplacement; } @@ -642,7 +642,7 @@ public: void setEmulatedTLS(bool EmulatedTLS) { this->EmulatedTLS = EmulatedTLS; } - + TargetMachine *selectTarget(); /// selectTarget - Pick a target either via -march or by guessing the native diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index ff7840f00a44a8fe03a5d1ca0761320ab64c0fc0..5f0ca58e74842382d2a0aa1eff003392527a9348 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,9 +15,11 @@ #ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H #define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H +#include "llvm-c/ExecutionEngine.h" #include "llvm/Config/llvm-config.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/Support/CBindingWrapping.h" #include #include @@ -119,6 +121,16 @@ private: virtual void anchor(); }; +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITEventListener, LLVMJITEventListenerRef) + } // end namespace llvm +#ifndef LLVM_USE_INTEL_JITEVENTS +LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void); +#endif + +#ifndef LLVM_USE_OPROFILE +LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void); +#endif + #endif // LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H diff --git a/include/llvm/ExecutionEngine/JITSymbol.h b/include/llvm/ExecutionEngine/JITSymbol.h index 86ab17363e19dfbb81ffdc8ce75e41b00d92a26a..53037c3dbc72f4d4582b9f080a8409e522232e43 100644 --- a/include/llvm/ExecutionEngine/JITSymbol.h +++ b/include/llvm/ExecutionEngine/JITSymbol.h @@ -36,10 +36,10 @@ class BasicSymbolRef; } // end namespace object -/// @brief Represents an address in the target process's address space. +/// Represents an address in the target process's address space. using JITTargetAddress = uint64_t; -/// @brief Flags for symbols in the JIT. +/// Flags for symbols in the JIT. class JITSymbolFlags { public: using UnderlyingType = uint8_t; @@ -52,63 +52,73 @@ public: Common = 1U << 2, Absolute = 1U << 3, Exported = 1U << 4, - NotMaterialized = 1U << 5 + Lazy = 1U << 5, + Materializing = 1U << 6 }; static JITSymbolFlags stripTransientFlags(JITSymbolFlags Orig) { - return static_cast(Orig.Flags & ~NotMaterialized); + return static_cast(Orig.Flags & ~Lazy & ~Materializing); } - /// @brief Default-construct a JITSymbolFlags instance. + /// Default-construct a JITSymbolFlags instance. JITSymbolFlags() = default; - /// @brief Construct a JITSymbolFlags instance from the given flags. + /// Construct a JITSymbolFlags instance from the given flags. JITSymbolFlags(FlagNames Flags) : Flags(Flags) {} - /// @brief Construct a JITSymbolFlags instance from the given flags and target + /// Construct a JITSymbolFlags instance from the given flags and target /// flags. JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags) : Flags(Flags), TargetFlags(TargetFlags) {} - /// @brief Return true if there was an error retrieving this symbol. + /// Return true if there was an error retrieving this symbol. bool hasError() const { return (Flags & HasError) == HasError; } - /// @brief Returns true if this symbol has been fully materialized (i.e. is - /// callable). - bool isMaterialized() const { return !(Flags & NotMaterialized); } + /// Returns true if this is a lazy symbol. + /// This flag is used internally by the JIT APIs to track + /// materialization states. + bool isLazy() const { return Flags & Lazy; } - /// @brief Returns true if the Weak flag is set. + /// Returns true if this symbol is in the process of being + /// materialized. + bool isMaterializing() const { return Flags & Materializing; } + + /// Returns true if this symbol is fully materialized. + /// (i.e. neither lazy, nor materializing). + bool isMaterialized() const { return !(Flags & (Lazy | Materializing)); } + + /// Returns true if the Weak flag is set. bool isWeak() const { return (Flags & Weak) == Weak; } - /// @brief Returns true if the Common flag is set. + /// Returns true if the Common flag is set. bool isCommon() const { return (Flags & Common) == Common; } - /// @brief Returns true if the symbol isn't weak or common. + /// Returns true if the symbol isn't weak or common. bool isStrong() const { return !isWeak() && !isCommon(); } - /// @brief Returns true if the Exported flag is set. + /// Returns true if the Exported flag is set. bool isExported() const { return (Flags & Exported) == Exported; } - /// @brief Implicitly convert to the underlying flags type. + /// Implicitly convert to the underlying flags type. operator UnderlyingType&() { return Flags; } - /// @brief Implicitly convert to the underlying flags type. + /// Implicitly convert to the underlying flags type. operator const UnderlyingType&() const { return Flags; } - /// @brief Return a reference to the target-specific flags. + /// Return a reference to the target-specific flags. TargetFlagsType& getTargetFlags() { return TargetFlags; } - /// @brief Return a reference to the target-specific flags. + /// Return a reference to the target-specific flags. const TargetFlagsType& getTargetFlags() const { return TargetFlags; } /// Construct a JITSymbolFlags value based on the flags of the given global @@ -124,7 +134,7 @@ private: TargetFlagsType TargetFlags = 0; }; -/// @brief ARM-specific JIT symbol flags. +/// ARM-specific JIT symbol flags. /// FIXME: This should be moved into a target-specific header. class ARMJITSymbolFlags { public: @@ -143,56 +153,59 @@ private: JITSymbolFlags::TargetFlagsType Flags = 0; }; -/// @brief Represents a symbol that has been evaluated to an address already. +/// Represents a symbol that has been evaluated to an address already. class JITEvaluatedSymbol { public: JITEvaluatedSymbol() = default; - /// @brief Create a 'null' symbol. + /// Create a 'null' symbol. JITEvaluatedSymbol(std::nullptr_t) {} - /// @brief Create a symbol for the given address and flags. + /// Create a symbol for the given address and flags. JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags) : Address(Address), Flags(Flags) {} - /// @brief An evaluated symbol converts to 'true' if its address is non-zero. + /// An evaluated symbol converts to 'true' if its address is non-zero. explicit operator bool() const { return Address != 0; } - /// @brief Return the address of this symbol. + /// Return the address of this symbol. JITTargetAddress getAddress() const { return Address; } - /// @brief Return the flags for this symbol. + /// Return the flags for this symbol. JITSymbolFlags getFlags() const { return Flags; } + /// Set the flags for this symbol. + void setFlags(JITSymbolFlags Flags) { this->Flags = std::move(Flags); } + private: JITTargetAddress Address = 0; JITSymbolFlags Flags; }; -/// @brief Represents a symbol in the JIT. +/// Represents a symbol in the JIT. class JITSymbol { public: using GetAddressFtor = std::function()>; - /// @brief Create a 'null' symbol, used to represent a "symbol not found" + /// Create a 'null' symbol, used to represent a "symbol not found" /// result from a successful (non-erroneous) lookup. JITSymbol(std::nullptr_t) : CachedAddr(0) {} - /// @brief Create a JITSymbol representing an error in the symbol lookup + /// Create a JITSymbol representing an error in the symbol lookup /// process (e.g. a network failure during a remote lookup). JITSymbol(Error Err) : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {} - /// @brief Create a symbol for a definition with a known address. + /// Create a symbol for a definition with a known address. JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags) : CachedAddr(Addr), Flags(Flags) {} - /// @brief Construct a JITSymbol from a JITEvaluatedSymbol. + /// Construct a JITSymbol from a JITEvaluatedSymbol. JITSymbol(JITEvaluatedSymbol Sym) : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {} - /// @brief Create a symbol for a definition that doesn't have a known address + /// Create a symbol for a definition that doesn't have a known address /// yet. /// @param GetAddress A functor to materialize a definition (fixing the /// address) on demand. @@ -232,19 +245,19 @@ public: CachedAddr.~JITTargetAddress(); } - /// @brief Returns true if the symbol exists, false otherwise. + /// Returns true if the symbol exists, false otherwise. explicit operator bool() const { return !Flags.hasError() && (CachedAddr || GetAddress); } - /// @brief Move the error field value out of this JITSymbol. + /// Move the error field value out of this JITSymbol. Error takeError() { if (Flags.hasError()) return std::move(Err); return Error::success(); } - /// @brief Get the address of the symbol in the target address space. Returns + /// Get the address of the symbol in the target address space. Returns /// '0' if the symbol does not exist. Expected getAddress() { assert(!Flags.hasError() && "getAddress called on error value"); @@ -270,7 +283,7 @@ private: JITSymbolFlags Flags; }; -/// @brief Symbol resolution interface. +/// Symbol resolution interface. /// /// Allows symbol flags and addresses to be looked up by name. /// Symbol queries are done in bulk (i.e. you request resolution of a set of @@ -284,14 +297,14 @@ public: virtual ~JITSymbolResolver() = default; - /// @brief Returns the fully resolved address and flags for each of the given + /// Returns the fully resolved address and flags for each of the given /// symbols. /// /// This method will return an error if any of the given symbols can not be /// resolved, or if the resolution process itself triggers an error. virtual Expected lookup(const LookupSet &Symbols) = 0; - /// @brief Returns the symbol flags for each of the given symbols. + /// Returns the symbol flags for each of the given symbols. /// /// This method does NOT return an error if any of the given symbols is /// missing. Instead, that symbol will be left out of the result map. @@ -301,15 +314,15 @@ private: virtual void anchor(); }; -/// \brief Legacy symbol resolution interface. +/// Legacy symbol resolution interface. class LegacyJITSymbolResolver : public JITSymbolResolver { public: - /// @brief Performs lookup by, for each symbol, first calling + /// Performs lookup by, for each symbol, first calling /// findSymbolInLogicalDylib and if that fails calling /// findSymbol. Expected lookup(const LookupSet &Symbols) final; - /// @brief Performs flags lookup by calling findSymbolInLogicalDylib and + /// Performs flags lookup by calling findSymbolInLogicalDylib and /// returning the flags value for that symbol. Expected lookupFlags(const LookupSet &Symbols) final; diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index a64a6dd86a2e404871951a37af018a814f044e8e..f999caef2fd3664c76165f9ac3a35ea207678f3e 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -57,7 +57,7 @@ class Value; namespace orc { -/// @brief Compile-on-demand layer. +/// Compile-on-demand layer. /// /// When a module is added to this layer a stub is created for each of its /// function definitions. The stubs and other global values are immediately @@ -196,10 +196,10 @@ private: public: - /// @brief Module partitioning functor. + /// Module partitioning functor. using PartitioningFtor = std::function(Function&)>; - /// @brief Builder for IndirectStubsManagers. + /// Builder for IndirectStubsManagers. using IndirectStubsManagerBuilderT = std::function()>; @@ -209,7 +209,7 @@ public: using SymbolResolverSetter = std::function R)>; - /// @brief Construct a compile-on-demand layer instance. + /// Construct a compile-on-demand layer instance. CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver, SymbolResolverSetter SetSymbolResolver, @@ -230,7 +230,7 @@ public: consumeError(removeModule(LogicalDylibs.begin()->first)); } - /// @brief Add a module to the compile-on-demand layer. + /// Add a module to the compile-on-demand layer. Error addModule(VModuleKey K, std::unique_ptr M) { assert(!LogicalDylibs.count(K) && "VModuleKey K already in use"); @@ -242,12 +242,12 @@ public: return addLogicalModule(I->second, std::move(M)); } - /// @brief Add extra modules to an existing logical module. + /// Add extra modules to an existing logical module. Error addExtraModule(VModuleKey K, std::unique_ptr M) { return addLogicalModule(LogicalDylibs[K], std::move(M)); } - /// @brief Remove the module represented by the given key. + /// Remove the module represented by the given key. /// /// This will remove all modules in the layers below that were derived from /// the module represented by K. @@ -259,7 +259,7 @@ public: return Err; } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -275,7 +275,7 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of a symbol provided by this layer, or some layer + /// Get the address of a symbol provided by this layer, or some layer /// below this one. JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, bool ExportedSymbolsOnly) { @@ -283,7 +283,7 @@ public: return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly); } - /// @brief Update the stub for the given function to point at FnBodyAddr. + /// Update the stub for the given function to point at FnBodyAddr. /// This can be used to support re-optimization. /// @return true if the function exists and the stub is updated, false /// otherwise. @@ -349,22 +349,21 @@ private: // Create a callback, associate it with the stub for the function, // and set the compile action to compile the partition containing the // function. - if (auto CCInfoOrErr = CompileCallbackMgr.getCompileCallback()) { - auto &CCInfo = *CCInfoOrErr; + auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress { + if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F)) + return *FnImplAddrOrErr; + else { + // FIXME: Report error, return to 'abort' or something similar. + consumeError(FnImplAddrOrErr.takeError()); + return 0; + } + }; + if (auto CCAddr = + CompileCallbackMgr.getCompileCallback(std::move(CompileAction))) StubInits[MangledName] = - std::make_pair(CCInfo.getAddress(), - JITSymbolFlags::fromGlobalValue(F)); - CCInfo.setCompileAction([this, &LD, LMId, &F]() -> JITTargetAddress { - if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F)) - return *FnImplAddrOrErr; - else { - // FIXME: Report error, return to 'abort' or something similar. - consumeError(FnImplAddrOrErr.takeError()); - return 0; - } - }); - } else - return CCInfoOrErr.takeError(); + std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F)); + else + return CCAddr.takeError(); } if (auto Err = LD.StubsMgr->createStubs(StubInits)) @@ -402,9 +401,8 @@ private: // Initializers may refer to functions declared (but not defined) in this // module. Build a materializer to clone decls on demand. - Error MaterializerErrors = Error::success(); auto Materializer = createLambdaMaterializer( - [&LD, &GVsM, &MaterializerErrors](Value *V) -> Value* { + [&LD, &GVsM](Value *V) -> Value* { if (auto *F = dyn_cast(V)) { // Decls in the original module just get cloned. if (F->isDeclaration()) @@ -416,18 +414,8 @@ private: const DataLayout &DL = GVsM->getDataLayout(); std::string FName = mangle(F->getName(), DL); unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType()); - JITTargetAddress StubAddr = 0; - - // Get the address for the stub. If we encounter an error while - // doing so, stash it in the MaterializerErrors variable and use a - // null address as a placeholder. - if (auto StubSym = LD.StubsMgr->findStub(FName, false)) { - if (auto StubAddrOrErr = StubSym.getAddress()) - StubAddr = *StubAddrOrErr; - else - MaterializerErrors = joinErrors(std::move(MaterializerErrors), - StubAddrOrErr.takeError()); - } + JITTargetAddress StubAddr = + LD.StubsMgr->findStub(FName, false).getAddress(); ConstantInt *StubAddrCI = ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr)); @@ -456,15 +444,10 @@ private: NewA->setAliasee(cast(Init)); } - if (MaterializerErrors) - return MaterializerErrors; - // Build a resolver for the globals module and add it to the base layer. auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol { if (auto Sym = LD.StubsMgr->findStub(Name, false)) return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); if (auto Sym = LD.findSymbol(BaseLayer, Name, false)) return Sym; @@ -490,10 +473,11 @@ private: return LD.BackingResolver->lookupFlags(SymbolFlags, *NotFoundViaLegacyLookup); }, - [&LD, LegacyLookup](std::shared_ptr Query, - SymbolNameSet Symbols) { + [this, &LD, + LegacyLookup](std::shared_ptr Query, + SymbolNameSet Symbols) { auto NotFoundViaLegacyLookup = - lookupWithLegacyFn(*Query, Symbols, LegacyLookup); + lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup); return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup); }); @@ -647,10 +631,10 @@ private: return LD.BackingResolver->lookupFlags(SymbolFlags, *NotFoundViaLegacyLookup); }, - [&LD, LegacyLookup](std::shared_ptr Q, - SymbolNameSet Symbols) { + [this, &LD, LegacyLookup](std::shared_ptr Q, + SymbolNameSet Symbols) { auto NotFoundViaLegacyLookup = - lookupWithLegacyFn(*Q, Symbols, LegacyLookup); + lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup); return LD.BackingResolver->lookup(Q, std::move(NotFoundViaLegacyLookup)); }); diff --git a/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/include/llvm/ExecutionEngine/Orc/CompileUtils.h index a8050ff22080979693dd8d4effc5edf65c5ba605..2e4486440ac6933a3f505465d0baf0c6b89c4b5f 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileUtils.h +++ b/include/llvm/ExecutionEngine/Orc/CompileUtils.h @@ -16,13 +16,13 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ExecutionEngine/ObjectCache.h" -#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include @@ -35,7 +35,7 @@ class Module; namespace orc { -/// @brief Simple compile functor: Takes a single IR module and returns an +/// Simple compile functor: Takes a single IR module and returns an /// ObjectFile. class SimpleCompiler { private: @@ -56,14 +56,14 @@ private: public: using CompileResult = std::unique_ptr; - /// @brief Construct a simple compile functor with the given target. + /// Construct a simple compile functor with the given target. SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr) : TM(TM), ObjCache(ObjCache) {} - /// @brief Set an ObjectCache to query before compiling. + /// Set an ObjectCache to query before compiling. void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } - /// @brief Compile a Module to an ObjectFile. + /// Compile a Module to an ObjectFile. CompileResult operator()(Module &M) { CompileResult CachedObject = tryToLoadFromObjectCache(M); if (CachedObject) diff --git a/include/llvm/ExecutionEngine/Orc/Core.h b/include/llvm/ExecutionEngine/Orc/Core.h index 26fec8b359fe1a57d13a3fe9ffe5c9e54fdfde50..839e88c52bbb824fa693b4792b490c21bfcbc1a9 100644 --- a/include/llvm/ExecutionEngine/Orc/Core.h +++ b/include/llvm/ExecutionEngine/Orc/Core.h @@ -16,7 +16,9 @@ #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" +#include "llvm/IR/Module.h" +#include #include #include #include @@ -25,74 +27,380 @@ namespace llvm { namespace orc { +// Forward declare some classes. +class AsynchronousSymbolQuery; +class ExecutionSession; +class MaterializationUnit; +class MaterializationResponsibility; +class VSO; + /// VModuleKey provides a unique identifier (allocated and managed by /// ExecutionSessions) for a module added to the JIT. using VModuleKey = uint64_t; -class VSO; - -/// @brief A set of symbol names (represented by SymbolStringPtrs for +/// A set of symbol names (represented by SymbolStringPtrs for // efficiency). using SymbolNameSet = std::set; -/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols +/// Render a SymbolNameSet to an ostream. +raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols); + +/// A map from symbol names (as SymbolStringPtrs) to JITSymbols /// (address/flags pairs). using SymbolMap = std::map; -/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags. +/// Render a SymbolMap to an ostream. +raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols); + +/// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags. using SymbolFlagsMap = std::map; -/// @brief A symbol query that returns results via a callback when results are +/// Render a SymbolMap to an ostream. +raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &Symbols); + +/// A base class for materialization failures that allows the failing +/// symbols to be obtained for logging. +using SymbolDependenceMap = std::map; + +/// Render a SymbolDependendeMap. +raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps); + +/// Used to notify a VSO that the given set of symbols failed to materialize. +class FailedToMaterialize : public ErrorInfo { +public: + static char ID; + + FailedToMaterialize(SymbolNameSet Symbols); + std::error_code convertToErrorCode() const override; + void log(raw_ostream &OS) const override; + const SymbolNameSet &getSymbols() const { return Symbols; } + +private: + SymbolNameSet Symbols; +}; + +/// Used to notify clients when symbols can not be found during a lookup. +class SymbolsNotFound : public ErrorInfo { +public: + static char ID; + + SymbolsNotFound(SymbolNameSet Symbols); + std::error_code convertToErrorCode() const override; + void log(raw_ostream &OS) const override; + const SymbolNameSet &getSymbols() const { return Symbols; } + +private: + SymbolNameSet Symbols; +}; + +/// Tracks responsibility for materialization, and mediates interactions between +/// MaterializationUnits and VSOs. +/// +/// An instance of this class is passed to MaterializationUnits when their +/// materialize method is called. It allows MaterializationUnits to resolve and +/// finalize symbols, or abandon materialization by notifying any unmaterialized +/// symbols of an error. +class MaterializationResponsibility { + friend class MaterializationUnit; +public: + MaterializationResponsibility(MaterializationResponsibility &&) = default; + MaterializationResponsibility & + operator=(MaterializationResponsibility &&) = default; + + /// Destruct a MaterializationResponsibility instance. In debug mode + /// this asserts that all symbols being tracked have been either + /// finalized or notified of an error. + ~MaterializationResponsibility(); + + /// Returns the target VSO that these symbols are being materialized + /// into. + const VSO &getTargetVSO() const { return V; } + + /// Returns the names of any symbols covered by this + /// MaterializationResponsibility object that have queries pending. This + /// information can be used to return responsibility for unrequested symbols + /// back to the VSO via the delegate method. + SymbolNameSet getRequestedSymbols(); + + /// Resolves the given symbols. Individual calls to this method may + /// resolve a subset of the symbols, but all symbols must have been + /// resolved prior to calling finalize. + void resolve(const SymbolMap &Symbols); + + /// Finalizes all symbols tracked by this instance. + void finalize(); + + /// Adds new symbols to the VSO and this responsibility instance. + /// VSO entries start out in the materializing state. + /// + /// This method can be used by materialization units that want to add + /// additional symbols at materialization time (e.g. stubs, compile + /// callbacks, metadata). + Error defineMaterializing(const SymbolFlagsMap &SymbolFlags); + + /// Notify all unfinalized symbols that an error has occurred. + /// This will remove all symbols covered by this MaterializationResponsibilty + /// from V, and send an error to any queries waiting on these symbols. + void failMaterialization(); + + /// Transfers responsibility to the given MaterializationUnit for all + /// symbols defined by that MaterializationUnit. This allows + /// materializers to break up work based on run-time information (e.g. + /// by introspecting which symbols have actually been looked up and + /// materializing only those). + void delegate(std::unique_ptr MU); + + /// Add dependencies for the symbols in this dylib. + void addDependencies(const SymbolDependenceMap &Dependencies); + +private: + /// Create a MaterializationResponsibility for the given VSO and + /// initial symbols. + MaterializationResponsibility(VSO &V, SymbolFlagsMap SymbolFlags); + + VSO &V; + SymbolFlagsMap SymbolFlags; +}; + +/// A MaterializationUnit represents a set of symbol definitions that can +/// be materialized as a group, or individually discarded (when +/// overriding definitions are encountered). +/// +/// MaterializationUnits are used when providing lazy definitions of symbols to +/// VSOs. The VSO will call materialize when the address of a symbol is +/// requested via the lookup method. The VSO will call discard if a stronger +/// definition is added or already present. +class MaterializationUnit { +public: + MaterializationUnit(SymbolFlagsMap InitalSymbolFlags) + : SymbolFlags(std::move(InitalSymbolFlags)) {} + + virtual ~MaterializationUnit() {} + + /// Return the set of symbols that this source provides. + const SymbolFlagsMap &getSymbols() const { return SymbolFlags; } + + /// Called by materialization dispatchers (see + /// ExecutionSession::DispatchMaterializationFunction) to trigger + /// materialization of this MaterializationUnit. + void doMaterialize(VSO &V) { + materialize(MaterializationResponsibility(V, std::move(SymbolFlags))); + } + + /// Called by VSOs to notify MaterializationUnits that the given symbol has + /// been overridden. + void doDiscard(const VSO &V, SymbolStringPtr Name) { + SymbolFlags.erase(Name); + discard(V, std::move(Name)); + } + +protected: + SymbolFlagsMap SymbolFlags; + +private: + virtual void anchor(); + + /// Implementations of this method should materialize all symbols + /// in the materialzation unit, except for those that have been + /// previously discarded. + virtual void materialize(MaterializationResponsibility R) = 0; + + /// Implementations of this method should discard the given symbol + /// from the source (e.g. if the source is an LLVM IR Module and the + /// symbol is a function, delete the function body or mark it available + /// externally). + virtual void discard(const VSO &V, SymbolStringPtr Name) = 0; +}; + +/// A MaterializationUnit implementation for pre-existing absolute symbols. +/// +/// All symbols will be resolved and marked ready as soon as the unit is +/// materialized. +class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit { +public: + AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols); + +private: + void materialize(MaterializationResponsibility R) override; + void discard(const VSO &V, SymbolStringPtr Name) override; + static SymbolFlagsMap extractFlags(const SymbolMap &Symbols); + + SymbolMap Symbols; +}; + +/// Create an AbsoluteSymbolsMaterializationUnit with the given symbols. +/// Useful for inserting absolute symbols into a VSO. E.g.: +/// \code{.cpp} +/// VSO &V = ...; +/// SymbolStringPtr Foo = ...; +/// JITEvaluatedSymbol FooSym = ...; +/// if (auto Err = V.define(absoluteSymbols({{Foo, FooSym}}))) +/// return Err; +/// \endcode +/// +inline std::unique_ptr +absoluteSymbols(SymbolMap Symbols) { + return llvm::make_unique( + std::move(Symbols)); +} + +/// Base utilities for ExecutionSession. +class ExecutionSessionBase { +public: + /// For reporting errors. + using ErrorReporter = std::function; + + /// For dispatching MaterializationUnit::materialize calls. + using DispatchMaterializationFunction = + std::function MU)>; + + /// Construct an ExecutionSessionBase. + /// + /// SymbolStringPools may be shared between ExecutionSessions. + ExecutionSessionBase(std::shared_ptr SSP = nullptr) + : SSP(SSP ? std::move(SSP) : std::make_shared()) {} + + /// Returns the SymbolStringPool for this ExecutionSession. + SymbolStringPool &getSymbolStringPool() const { return *SSP; } + + /// Run the given lambda with the session mutex locked. + template auto runSessionLocked(Func &&F) -> decltype(F()) { + std::lock_guard Lock(SessionMutex); + return F(); + } + + /// Set the error reporter function. + ExecutionSessionBase &setErrorReporter(ErrorReporter ReportError) { + this->ReportError = std::move(ReportError); + return *this; + } + + /// Set the materialization dispatch function. + ExecutionSessionBase &setDispatchMaterialization( + DispatchMaterializationFunction DispatchMaterialization) { + this->DispatchMaterialization = std::move(DispatchMaterialization); + return *this; + } + + /// Report a error for this execution session. + /// + /// Unhandled errors can be sent here to log them. + void reportError(Error Err) { ReportError(std::move(Err)); } + + /// Allocate a module key for a new module to add to the JIT. + VModuleKey allocateVModule() { return ++LastKey; } + + /// Return a module key to the ExecutionSession so that it can be + /// re-used. This should only be done once all resources associated + /// with the original key have been released. + void releaseVModule(VModuleKey Key) { /* FIXME: Recycle keys */ + } + + /// Cause the given query to fail with the given Error. + /// + /// This should only be used by legacy APIs and will be deprecated in the + /// future. + void failQuery(AsynchronousSymbolQuery &Q, Error Err); + + /// Materialize the given unit. + void dispatchMaterialization(VSO &V, + std::unique_ptr MU) { + DispatchMaterialization(V, std::move(MU)); + } + +private: + static void logErrorsToStdErr(Error Err) { + logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: "); + } + + static void + materializeOnCurrentThread(VSO &V, std::unique_ptr MU) { + MU->doMaterialize(V); + } + + mutable std::recursive_mutex SessionMutex; + std::shared_ptr SSP; + VModuleKey LastKey = 0; + ErrorReporter ReportError = logErrorsToStdErr; + DispatchMaterializationFunction DispatchMaterialization = + materializeOnCurrentThread; +}; + +/// A symbol query that returns results via a callback when results are /// ready. /// /// makes a callback when all symbols are available. class AsynchronousSymbolQuery { + friend class ExecutionSessionBase; + friend class VSO; + public: - /// @brief Callback to notify client that symbols have been resolved. - using SymbolsResolvedCallback = std::function)>; + class ResolutionResult { + public: + ResolutionResult(SymbolMap Symbols, const SymbolDependenceMap &Dependencies) + : Symbols(std::move(Symbols)), Dependencies(Dependencies) {} - /// @brief Callback to notify client that symbols are ready for execution. + SymbolMap Symbols; + const SymbolDependenceMap &Dependencies; + }; + + /// Callback to notify client that symbols have been resolved. + using SymbolsResolvedCallback = + std::function)>; + + /// Callback to notify client that symbols are ready for execution. using SymbolsReadyCallback = std::function; - /// @brief Create a query for the given symbols, notify-resolved and + /// Create a query for the given symbols, notify-resolved and /// notify-ready callbacks. AsynchronousSymbolQuery(const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved, SymbolsReadyCallback NotifySymbolsReady); - /// @brief Notify client that the query failed. - /// - /// If the notify-resolved callback has not been made yet, then it is called - /// with the given error, and the notify-finalized callback is never made. - /// - /// If the notify-resolved callback has already been made then then the - /// notify-finalized callback is called with the given error. - /// - /// It is illegal to call setFailed after both callbacks have been made. - void setFailed(Error Err); + /// Set the resolved symbol information for the given symbol name. + void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym); + + /// Returns true if all symbols covered by this query have been + /// resolved. + bool isFullyResolved() const { return NotYetResolvedCount == 0; } - /// @brief Set the resolved symbol information for the given symbol name. + /// Call the NotifySymbolsResolved callback. /// - /// If this symbol was the last one not resolved, this will trigger a call to - /// the notify-finalized callback passing the completed sybol map. - void setDefinition(SymbolStringPtr Name, JITEvaluatedSymbol Sym); + /// This should only be called if all symbols covered by the query have been + /// resolved. + void handleFullyResolved(); + + /// Notify the query that a requested symbol is ready for execution. + void notifySymbolReady(); - /// @brief Notify the query that a requested symbol is ready for execution. + /// Returns true if all symbols covered by this query are ready. + bool isFullyReady() const { return NotYetReadyCount == 0; } + + /// Calls the NotifySymbolsReady callback. /// - /// This decrements the query's internal count of not-yet-ready symbols. If - /// this call to notifySymbolFinalized sets the counter to zero, it will call - /// the notify-finalized callback with Error::success as the value. - void notifySymbolFinalized(); + /// This should only be called if all symbols covered by this query are ready. + void handleFullyReady(); private: - SymbolMap Symbols; - size_t OutstandingResolutions = 0; - size_t OutstandingFinalizations = 0; + void addQueryDependence(VSO &V, SymbolStringPtr Name); + + void removeQueryDependence(VSO &V, const SymbolStringPtr &Name); + + bool canStillFail(); + + void handleFailed(Error Err); + + void detach(); + SymbolsResolvedCallback NotifySymbolsResolved; SymbolsReadyCallback NotifySymbolsReady; + SymbolDependenceMap QueryRegistrations; + SymbolMap ResolvedSymbols; + size_t NotYetResolvedCount; + size_t NotYetReadyCount; }; -/// @brief SymbolResolver is a composable interface for looking up symbol flags +/// SymbolResolver is a composable interface for looking up symbol flags /// and addresses using the AsynchronousSymbolQuery type. It will /// eventually replace the LegacyJITSymbolResolver interface as the /// stardard ORC symbol resolver type. @@ -100,12 +408,12 @@ class SymbolResolver { public: virtual ~SymbolResolver() = default; - /// @brief Returns the flags for each symbol in Symbols that can be found, + /// Returns the flags for each symbol in Symbols that can be found, /// along with the set of symbol that could not be found. virtual SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) = 0; - /// @brief For each symbol in Symbols that can be found, assigns that symbols + /// For each symbol in Symbols that can be found, assigns that symbols /// value in Query. Returns the set of symbols that could not be found. virtual SymbolNameSet lookup(std::shared_ptr Query, SymbolNameSet Symbols) = 0; @@ -114,7 +422,7 @@ private: virtual void anchor(); }; -/// @brief Implements SymbolResolver with a pair of supplied function objects +/// Implements SymbolResolver with a pair of supplied function objects /// for convenience. See createSymbolResolver. template class LambdaSymbolResolver final : public SymbolResolver { @@ -139,7 +447,7 @@ private: LookupFn Lookup; }; -/// @brief Creates a SymbolResolver implementation from the pair of supplied +/// Creates a SymbolResolver implementation from the pair of supplied /// function objects. template std::unique_ptr(LookupFlags), std::forward(Lookup)); } -/// @brief A MaterializationUnit represents a set of symbol definitions that can -/// be materialized as a group, or individually discarded (when -/// overriding definitions are encountered). -/// -/// MaterializationUnits are used when providing lazy definitions of symbols to -/// VSOs. The VSO will call materialize when the address of a symbol is -/// requested via the lookup method. The VSO will call discard if a stronger -/// definition is added or already present. -class MaterializationUnit { -public: - virtual ~MaterializationUnit() {} - - /// @brief Return the set of symbols that this source provides. - virtual SymbolFlagsMap getSymbols() = 0; - - /// @brief Implementations of this method should materialize all symbols - /// in the materialzation unit, except for those that have been - /// previously discarded. - virtual Error materialize(VSO &V) = 0; - - /// @brief Implementations of this method should discard the given symbol - /// from the source (e.g. if the source is an LLVM IR Module and the - /// symbol is a function, delete the function body or mark it available - /// externally). - virtual void discard(VSO &V, SymbolStringPtr Name) = 0; - -private: - virtual void anchor(); -}; - -/// @brief Represents a dynamic linkage unit in a JIT process. +/// A symbol table that supports asynchoronous symbol queries. /// -/// VSO acts as a symbol table (symbol definitions can be set and the dylib -/// queried to find symbol addresses) and as a key for tracking resources -/// (since a VSO's address is fixed). +/// Represents a virtual shared object. Instances can not be copied or moved, so +/// their addresses may be used as keys for resource management. +/// VSO state changes must be made via an ExecutionSession to guarantee that +/// they are synchronized with respect to other VSO operations. class VSO { + friend class AsynchronousSymbolQuery; friend class ExecutionSession; - + friend class MaterializationResponsibility; public: - enum RelativeLinkageStrength { - NewDefinitionIsStronger, - DuplicateDefinition, - ExistingDefinitionIsStronger - }; - - using SetDefinitionsResult = - std::map; + using AsynchronousSymbolQuerySet = + std::set>; using MaterializationUnitList = std::vector>; - struct LookupResult { - MaterializationUnitList MaterializationUnits; - SymbolNameSet UnresolvedSymbols; - }; - - VSO() = default; + using VSOList = std::vector; VSO(const VSO &) = delete; VSO &operator=(const VSO &) = delete; VSO(VSO &&) = delete; VSO &operator=(VSO &&) = delete; - /// @brief Compare new linkage with existing linkage. - static RelativeLinkageStrength - compareLinkage(Optional OldFlags, JITSymbolFlags NewFlags); - - /// @brief Compare new linkage with an existing symbol's linkage. - RelativeLinkageStrength compareLinkage(SymbolStringPtr Name, - JITSymbolFlags NewFlags) const; - - /// @brief Adds the given symbols to the mapping as resolved, finalized - /// symbols. - /// - /// FIXME: We can take this by const-ref once symbol-based laziness is - /// removed. - Error define(SymbolMap NewSymbols); - - /// @brief Adds the given symbols to the mapping as lazy symbols. - Error defineLazy(std::unique_ptr Source); - - /// @brief Add the given symbol/address mappings to the dylib, but do not - /// mark the symbols as finalized yet. - void resolve(SymbolMap SymbolValues); + /// Get the name for this VSO. + const std::string &getName() const { return VSOName; } + + /// Get a reference to the ExecutionSession for this VSO. + ExecutionSessionBase &getExecutionSession() const { return ES; } + + /// Define all symbols provided by the materialization unit to be part + /// of the given VSO. + template + typename std::enable_if< + std::is_convertible< + typename std::decay::type, + std::unique_ptr>::value, + Error>::type + define(UniquePtrToMaterializationUnit &&MU) { + return ES.runSessionLocked([&, this]() -> Error { + assert(MU && "Can't define with a null MU"); + + if (auto Err = defineImpl(*MU)) + return Err; + + /// defineImpl succeeded. + auto UMI = std::make_shared(std::move(MU)); + for (auto &KV : UMI->MU->getSymbols()) + UnmaterializedInfos[KV.first] = UMI; + + return Error::success(); + }); + } - /// @brief Finalize the given symbols. - void finalize(SymbolNameSet SymbolsToFinalize); + /// Search the given VSO for the symbols in Symbols. If found, store + /// the flags for each symbol in Flags. Returns any unresolved symbols. + SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, const SymbolNameSet &Names); - /// @brief Look up the flags for the given symbols. + /// Search the given VSOs in order for the symbols in Symbols. Results + /// (once they become available) will be returned via the given Query. /// - /// Returns the flags for the give symbols, together with the set of symbols - /// not found. - SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, SymbolNameSet Symbols); + /// If any symbol is not found then the unresolved symbols will be returned, + /// and the query will not be applied. The Query is not failed and can be + /// re-used in a subsequent lookup once the symbols have been added, or + /// manually failed. + SymbolNameSet lookup(std::shared_ptr Q, + SymbolNameSet Names); - /// @brief Apply the given query to the given symbols in this VSO. - /// - /// For symbols in this VSO that have already been materialized, their address - /// will be set in the query immediately. - /// - /// For symbols in this VSO that have not been materialized, the query will be - /// recorded and the source for those symbols (plus the set of symbols to be - /// materialized by that source) will be returned as the MaterializationWork - /// field of the LookupResult. - /// - /// Any symbols not found in this VSO will be returned in the - /// UnresolvedSymbols field of the LookupResult. - LookupResult lookup(std::shared_ptr Query, - SymbolNameSet Symbols); + /// Dump current VSO state to OS. + void dump(raw_ostream &OS); private: - class MaterializationInfo { - public: - using QueryList = std::vector>; + using AsynchronousSymbolQueryList = + std::vector>; - MaterializationInfo(size_t SymbolsRemaining, - std::unique_ptr MU); + struct UnmaterializedInfo { + UnmaterializedInfo(std::unique_ptr MU) + : MU(std::move(MU)) {} - uint64_t SymbolsRemaining; std::unique_ptr MU; - SymbolMap Symbols; - std::map PendingResolution; - std::map PendingFinalization; }; - using MaterializationInfoSet = std::set>; - - using MaterializationInfoIterator = MaterializationInfoSet::iterator; + using UnmaterializedInfosMap = + std::map>; - class SymbolTableEntry { - public: - SymbolTableEntry(JITSymbolFlags SymbolFlags, - MaterializationInfoIterator MaterializationInfoItr); - SymbolTableEntry(JITEvaluatedSymbol Sym); - SymbolTableEntry(SymbolTableEntry &&Other); - ~SymbolTableEntry(); - - SymbolTableEntry &operator=(JITEvaluatedSymbol Sym); - - JITSymbolFlags getFlags() const; - void replaceWith(VSO &V, SymbolStringPtr Name, JITSymbolFlags Flags, - MaterializationInfoIterator NewMaterializationInfoItr); - std::unique_ptr - query(SymbolStringPtr Name, std::shared_ptr Query); - void resolve(VSO &V, SymbolStringPtr Name, JITEvaluatedSymbol Sym); - void finalize(VSO &V, SymbolStringPtr Name); - void discard(VSO &V, SymbolStringPtr Name); - - private: - void destroy(); - - JITSymbolFlags Flags; - MaterializationInfoIterator MII; - union { - JITTargetAddress Address; - MaterializationInfoIterator MaterializationInfoItr; - }; + struct MaterializingInfo { + AsynchronousSymbolQueryList PendingQueries; + SymbolDependenceMap Dependants; + SymbolDependenceMap UnfinalizedDependencies; + bool IsFinalized = false; }; - std::map Symbols; - MaterializationInfoSet MaterializationInfos; -}; + using MaterializingInfosMap = std::map; -/// @brief An ExecutionSession represents a running JIT program. -class ExecutionSession { -public: - using ErrorReporter = std::function; + VSO(ExecutionSessionBase &ES, std::string Name) + : ES(ES), VSOName(std::move(Name)) {} - /// @brief Construct an ExecutionEngine. - /// - /// SymbolStringPools may be shared between ExecutionSessions. - ExecutionSession(SymbolStringPool &SSP); + ExecutionSessionBase &ES; + std::string VSOName; + SymbolMap Symbols; + UnmaterializedInfosMap UnmaterializedInfos; + MaterializingInfosMap MaterializingInfos; - /// @brief Returns the SymbolStringPool for this ExecutionSession. - SymbolStringPool &getSymbolStringPool() const { return SSP; } + Error defineImpl(MaterializationUnit &MU); - /// @brief Set the error reporter function. - void setErrorReporter(ErrorReporter ReportError) { - this->ReportError = std::move(ReportError); - } + void detachQueryHelper(AsynchronousSymbolQuery &Q, + const SymbolNameSet &QuerySymbols); - /// @brief Report a error for this execution session. - /// - /// Unhandled errors can be sent here to log them. - void reportError(Error Err) { ReportError(std::move(Err)); } + void transferFinalizedNodeDependencies(MaterializingInfo &DependantMI, + const SymbolStringPtr &DependantName, + MaterializingInfo &FinalizedMI); - /// @brief Allocate a module key for a new module to add to the JIT. - VModuleKey allocateVModule(); + Error defineMaterializing(const SymbolFlagsMap &SymbolFlags); - /// @brief Return a module key to the ExecutionSession so that it can be - /// re-used. This should only be done once all resources associated - //// with the original key have been released. - void releaseVModule(VModuleKey Key); + void replace(std::unique_ptr MU); -public: - static void logErrorsToStdErr(Error Err); + SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags); - SymbolStringPool &SSP; - VModuleKey LastKey = 0; - ErrorReporter ReportError = logErrorsToStdErr; + void addDependencies(const SymbolFlagsMap &Dependents, + const SymbolDependenceMap &Dependencies); + + void resolve(const SymbolMap &Resolved); + + void finalize(const SymbolFlagsMap &Finalized); + + void notifyFailed(const SymbolNameSet &FailedSymbols); }; -/// Runs Materializers on the current thread and reports errors to the given -/// ExecutionSession. -class MaterializeOnCurrentThread { +/// An ExecutionSession represents a running JIT program. +class ExecutionSession : public ExecutionSessionBase { public: - MaterializeOnCurrentThread(ExecutionSession &ES) : ES(ES) {} + using ErrorReporter = std::function; - void operator()(VSO &V, std::unique_ptr MU) { - if (auto Err = MU->materialize(V)) - ES.reportError(std::move(Err)); - } + using DispatchMaterializationFunction = + std::function MU)>; + + /// Construct an ExecutionEngine. + /// + /// SymbolStringPools may be shared between ExecutionSessions. + ExecutionSession(std::shared_ptr SSP = nullptr) + : ExecutionSessionBase(std::move(SSP)) {} + + /// Add a new VSO to this ExecutionSession. + VSO &createVSO(std::string Name); private: - ExecutionSession &ES; + std::vector> VSOs; }; -/// Materialization function object wrapper for the lookup method. -using MaterializationDispatcher = - std::function S)>; +/// Look up the given names in the given VSOs. +/// VSOs will be searched in order and no VSO pointer may be null. +/// All symbols must be found within the given VSOs or an error +/// will be returned. +Expected lookup(const VSO::VSOList &VSOs, SymbolNameSet Names); -/// @brief Look up a set of symbols by searching a list of VSOs. -/// -/// All VSOs in the list should be non-null. -Expected lookup(const std::vector &VSOs, SymbolNameSet Names, - MaterializationDispatcher DispatchMaterialization); - -/// @brief Look up a symbol by searching a list of VSOs. -Expected -lookup(const std::vector VSOs, SymbolStringPtr Name, - MaterializationDispatcher DispatchMaterialization); +/// Look up a symbol by searching a list of VSOs. +Expected lookup(const VSO::VSOList &VSOs, + SymbolStringPtr Name); } // End namespace orc } // End namespace llvm diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index d466df8b0d5002e31578109c2aedaca2356cf272..0268177f38d68047fbb5ebb15041c6ec409011f5 100644 --- a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -36,14 +36,14 @@ class Value; namespace orc { -/// @brief This iterator provides a convenient way to iterate over the elements +/// This iterator provides a convenient way to iterate over the elements /// of an llvm.global_ctors/llvm.global_dtors instance. /// /// The easiest way to get hold of instances of this class is to use the /// getConstructors/getDestructors functions. class CtorDtorIterator { public: - /// @brief Accessor for an element of the global_ctors/global_dtors array. + /// Accessor for an element of the global_ctors/global_dtors array. /// /// This class provides a read-only view of the element with any casts on /// the function stripped away. @@ -56,23 +56,23 @@ public: Value *Data; }; - /// @brief Construct an iterator instance. If End is true then this iterator + /// Construct an iterator instance. If End is true then this iterator /// acts as the end of the range, otherwise it is the beginning. CtorDtorIterator(const GlobalVariable *GV, bool End); - /// @brief Test iterators for equality. + /// Test iterators for equality. bool operator==(const CtorDtorIterator &Other) const; - /// @brief Test iterators for inequality. + /// Test iterators for inequality. bool operator!=(const CtorDtorIterator &Other) const; - /// @brief Pre-increment iterator. + /// Pre-increment iterator. CtorDtorIterator& operator++(); - /// @brief Post-increment iterator. + /// Post-increment iterator. CtorDtorIterator operator++(int); - /// @brief Dereference iterator. The resulting value provides a read-only view + /// Dereference iterator. The resulting value provides a read-only view /// of this element of the global_ctors/global_dtors list. Element operator*() const; @@ -81,25 +81,25 @@ private: unsigned I; }; -/// @brief Create an iterator range over the entries of the llvm.global_ctors +/// Create an iterator range over the entries of the llvm.global_ctors /// array. iterator_range getConstructors(const Module &M); -/// @brief Create an iterator range over the entries of the llvm.global_ctors +/// Create an iterator range over the entries of the llvm.global_ctors /// array. iterator_range getDestructors(const Module &M); -/// @brief Convenience class for recording constructor/destructor names for +/// Convenience class for recording constructor/destructor names for /// later execution. template class CtorDtorRunner { public: - /// @brief Construct a CtorDtorRunner for the given range using the given + /// Construct a CtorDtorRunner for the given range using the given /// name mangling function. CtorDtorRunner(std::vector CtorDtorNames, VModuleKey K) : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} - /// @brief Run the recorded constructors/destructors through the given JIT + /// Run the recorded constructors/destructors through the given JIT /// layer. Error runViaLayer(JITLayerT &JITLayer) const { using CtorDtorTy = void (*)(); @@ -127,7 +127,7 @@ private: orc::VModuleKey K; }; -/// @brief Support class for static dtor execution. For hosted (in-process) JITs +/// Support class for static dtor execution. For hosted (in-process) JITs /// only! /// /// If a __cxa_atexit function isn't found C++ programs that use static diff --git a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h index 8a48c36f41417b085505afbc051d2be23be4f9ac..a8a88d7cb2d2c67eb00b94ed777f5aa619c85009 100644 --- a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h @@ -27,7 +27,7 @@ class JITSymbolResolver; namespace orc { -/// @brief Global mapping layer. +/// Global mapping layer. /// /// This layer overrides the findSymbol method to first search a local symbol /// table that the client can define. It can be used to inject new symbol @@ -38,13 +38,13 @@ template class GlobalMappingLayer { public: - /// @brief Handle to an added module. + /// Handle to an added module. using ModuleHandleT = typename BaseLayerT::ModuleHandleT; - /// @brief Construct an GlobalMappingLayer with the given BaseLayer + /// Construct an GlobalMappingLayer with the given BaseLayer GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} - /// @brief Add the given module to the JIT. + /// Add the given module to the JIT. /// @return A handle for the added modules. Expected addModule(std::shared_ptr M, @@ -52,20 +52,20 @@ public: return BaseLayer.addModule(std::move(M), std::move(Resolver)); } - /// @brief Remove the module set associated with the handle H. + /// Remove the module set associated with the handle H. Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); } - /// @brief Manually set the address to return for the given symbol. + /// Manually set the address to return for the given symbol. void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) { SymbolTable[Name] = Addr; } - /// @brief Remove the given symbol from the global mapping. + /// Remove the given symbol from the global mapping. void eraseGlobalMapping(const std::string &Name) { SymbolTable.erase(Name); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// /// This method will first search the local symbol table, returning /// any symbol found there. If the symbol is not found in the local @@ -81,7 +81,7 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the of the + /// Get the address of the given symbol in the context of the of the /// module represented by the handle H. This call is forwarded to the /// base layer's implementation. /// @param H The handle for the module to search in. @@ -94,7 +94,7 @@ public: return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the module set represented by the + /// Immediately emit and finalize the module set represented by the /// given handle. /// @param H Handle for module set to emit/finalize. Error emitAndFinalize(ModuleHandleT H) { diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index a7f9416475880dbfb8c16d13d2d9de3f721ca7c8..ad6481548d5997195332ad6830f1a9d9c2ca7e6e 100644 --- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -16,8 +16,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" #include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" #include #include @@ -27,7 +28,30 @@ class Module; namespace orc { -/// @brief Eager IR compiling layer. +class IRCompileLayer2 : public IRLayer { +public: + using CompileFunction = + std::function>(Module &)>; + + using NotifyCompiledFunction = + std::function)>; + + IRCompileLayer2(ExecutionSession &ES, ObjectLayer &BaseLayer, + CompileFunction Compile); + + void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); + + void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr M) override; + +private: + mutable std::mutex IRLayerMutex; + ObjectLayer &BaseLayer; + CompileFunction Compile; + NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction(); +}; + +/// Eager IR compiling layer. /// /// This layer immediately compiles each IR module added via addModule to an /// object file and adds this module file to the layer below, which must @@ -35,11 +59,11 @@ namespace orc { template class IRCompileLayer { public: - /// @brief Callback type for notifications when modules are compiled. + /// Callback type for notifications when modules are compiled. using NotifyCompiledCallback = std::function)>; - /// @brief Construct an IRCompileLayer with the given BaseLayer, which must + /// Construct an IRCompileLayer with the given BaseLayer, which must /// implement the ObjectLayer concept. IRCompileLayer( BaseLayerT &BaseLayer, CompileFtor Compile, @@ -47,15 +71,15 @@ public: : BaseLayer(BaseLayer), Compile(std::move(Compile)), NotifyCompiled(std::move(NotifyCompiled)) {} - /// @brief Get a reference to the compiler functor. + /// Get a reference to the compiler functor. CompileFtor& getCompiler() { return Compile; } - /// @brief (Re)set the NotifyCompiled callback. + /// (Re)set the NotifyCompiled callback. void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) { this->NotifyCompiled = std::move(NotifyCompiled); } - /// @brief Compile the module, and add the resulting object to the base layer + /// Compile the module, and add the resulting object to the base layer /// along with the given memory manager and symbol resolver. Error addModule(VModuleKey K, std::unique_ptr M) { if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M))) @@ -65,10 +89,10 @@ public: return Error::success(); } - /// @brief Remove the module associated with the VModuleKey K. + /// Remove the module associated with the VModuleKey K. Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -76,7 +100,7 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in compiled module represented + /// Get the address of the given symbol in compiled module represented /// by the handle H. This call is forwarded to the base layer's /// implementation. /// @param K The VModuleKey for the module to search in. @@ -89,7 +113,7 @@ public: return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the module represented by the given + /// Immediately emit and finalize the module represented by the given /// handle. /// @param K The VModuleKey for the module to emit/finalize. Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 4f1fe7ba0f593ec3c50b034eb37f8f000c03163e..a802b6db6dd56627e2b8123830803eabaddd2315 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -15,7 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" #include #include @@ -23,7 +23,25 @@ namespace llvm { class Module; namespace orc { -/// @brief IR mutating layer. +class IRTransformLayer2 : public IRLayer { +public: + + using TransformFunction = + std::function>(std::unique_ptr)>; + + IRTransformLayer2(ExecutionSession &ES, + IRLayer &BaseLayer, + TransformFunction Transform); + + void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr M) override; + +private: + IRLayer &BaseLayer; + TransformFunction Transform; +}; + +/// IR mutating layer. /// /// This layer applies a user supplied transform to each module that is added, /// then adds the transformed module to the layer below. @@ -31,12 +49,12 @@ template class IRTransformLayer { public: - /// @brief Construct an IRTransformLayer with the given BaseLayer + /// Construct an IRTransformLayer with the given BaseLayer IRTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform = TransformFtor()) : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - /// @brief Apply the transform functor to the module, then add the module to + /// Apply the transform functor to the module, then add the module to /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. @@ -44,10 +62,10 @@ public: return BaseLayer.addModule(std::move(K), Transform(std::move(M))); } - /// @brief Remove the module associated with the VModuleKey K. + /// Remove the module associated with the VModuleKey K. Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -55,7 +73,7 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the module + /// Get the address of the given symbol in the context of the module /// represented by the VModuleKey K. This call is forwarded to the base /// layer's implementation. /// @param K The VModuleKey for the module to search in. @@ -68,15 +86,15 @@ public: return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the module represented by the given + /// Immediately emit and finalize the module represented by the given /// VModuleKey. /// @param K The VModuleKey for the module to emit/finalize. Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } - /// @brief Access the transform functor directly. + /// Access the transform functor directly. TransformFtor& getTransform() { return Transform; } - /// @brief Access the mumate functor directly. + /// Access the mumate functor directly. const TransformFtor& getTransform() const { return Transform; } private: diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index 029b86a6d2cadeed84dd33d26b90881be53885a4..8b0b3fdb7df4b4343b0c8bc36406464d1638b119 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/Support/Error.h" #include "llvm/Support/Memory.h" #include "llvm/Support/Process.h" @@ -46,98 +47,29 @@ class Value; namespace orc { -/// @brief Target-independent base class for compile callback management. +/// Target-independent base class for compile callback management. class JITCompileCallbackManager { public: - using CompileFtor = std::function; - - /// @brief Handle to a newly created compile callback. Can be used to get an - /// IR constant representing the address of the trampoline, and to set - /// the compile action for the callback. - class CompileCallbackInfo { - public: - CompileCallbackInfo(JITTargetAddress Addr, CompileFtor &Compile) - : Addr(Addr), Compile(Compile) {} - - JITTargetAddress getAddress() const { return Addr; } - void setCompileAction(CompileFtor Compile) { - this->Compile = std::move(Compile); - } - - private: - JITTargetAddress Addr; - CompileFtor &Compile; - }; - - /// @brief Construct a JITCompileCallbackManager. + using CompileFunction = std::function; + + /// Construct a JITCompileCallbackManager. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. - JITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress) - : ErrorHandlerAddress(ErrorHandlerAddress) {} + JITCompileCallbackManager(ExecutionSession &ES, + JITTargetAddress ErrorHandlerAddress) + : ES(ES), CallbacksVSO(ES.createVSO("")), + ErrorHandlerAddress(ErrorHandlerAddress) {} virtual ~JITCompileCallbackManager() = default; - /// @brief Execute the callback for the given trampoline id. Called by the JIT - /// to compile functions on demand. - JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr) { - auto I = ActiveTrampolines.find(TrampolineAddr); - // FIXME: Also raise an error in the Orc error-handler when we finally have - // one. - if (I == ActiveTrampolines.end()) - return ErrorHandlerAddress; - - // Found a callback handler. Yank this trampoline out of the active list and - // put it back in the available trampolines list, then try to run the - // handler's compile and update actions. - // Moving the trampoline ID back to the available list first means there's - // at - // least one available trampoline if the compile action triggers a request - // for - // a new one. - auto Compile = std::move(I->second); - ActiveTrampolines.erase(I); - AvailableTrampolines.push_back(TrampolineAddr); - - if (auto Addr = Compile()) - return Addr; - - return ErrorHandlerAddress; - } - - /// @brief Reserve a compile callback. - Expected getCompileCallback() { - if (auto TrampolineAddrOrErr = getAvailableTrampolineAddr()) { - const auto &TrampolineAddr = *TrampolineAddrOrErr; - auto &Compile = this->ActiveTrampolines[TrampolineAddr]; - return CompileCallbackInfo(TrampolineAddr, Compile); - } else - return TrampolineAddrOrErr.takeError(); - } - - /// @brief Get a CompileCallbackInfo for an existing callback. - CompileCallbackInfo getCompileCallbackInfo(JITTargetAddress TrampolineAddr) { - auto I = ActiveTrampolines.find(TrampolineAddr); - assert(I != ActiveTrampolines.end() && "Not an active trampoline."); - return CompileCallbackInfo(I->first, I->second); - } + /// Reserve a compile callback. + Expected getCompileCallback(CompileFunction Compile); - /// @brief Release a compile callback. - /// - /// Note: Callbacks are auto-released after they execute. This method should - /// only be called to manually release a callback that is not going to - /// execute. - void releaseCompileCallback(JITTargetAddress TrampolineAddr) { - auto I = ActiveTrampolines.find(TrampolineAddr); - assert(I != ActiveTrampolines.end() && "Not an active trampoline."); - ActiveTrampolines.erase(I); - AvailableTrampolines.push_back(TrampolineAddr); - } + /// Execute the callback for the given trampoline id. Called by the JIT + /// to compile functions on demand. + JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr); protected: - JITTargetAddress ErrorHandlerAddress; - - using TrampolineMapT = std::map; - TrampolineMapT ActiveTrampolines; std::vector AvailableTrampolines; private: @@ -156,17 +88,25 @@ private: virtual Error grow() = 0; virtual void anchor(); + + std::mutex CCMgrMutex; + ExecutionSession &ES; + VSO &CallbacksVSO; + JITTargetAddress ErrorHandlerAddress; + std::map AddrToSymbol; + size_t NextCallbackId = 0; }; -/// @brief Manage compile callbacks for in-process JITs. +/// Manage compile callbacks for in-process JITs. template class LocalJITCompileCallbackManager : public JITCompileCallbackManager { public: - /// @brief Construct a InProcessJITCompileCallbackManager. + /// Construct a InProcessJITCompileCallbackManager. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. - LocalJITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress) - : JITCompileCallbackManager(ErrorHandlerAddress) { + LocalJITCompileCallbackManager(ExecutionSession &ES, + JITTargetAddress ErrorHandlerAddress) + : JITCompileCallbackManager(ES, ErrorHandlerAddress) { /// Set up the resolver block. std::error_code EC; ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( @@ -229,38 +169,38 @@ private: std::vector TrampolineBlocks; }; -/// @brief Base class for managing collections of named indirect stubs. +/// Base class for managing collections of named indirect stubs. class IndirectStubsManager { public: - /// @brief Map type for initializing the manager. See init. + /// Map type for initializing the manager. See init. using StubInitsMap = StringMap>; virtual ~IndirectStubsManager() = default; - /// @brief Create a single stub with the given name, target address and flags. + /// Create a single stub with the given name, target address and flags. virtual Error createStub(StringRef StubName, JITTargetAddress StubAddr, JITSymbolFlags StubFlags) = 0; - /// @brief Create StubInits.size() stubs with the given names, target + /// Create StubInits.size() stubs with the given names, target /// addresses, and flags. virtual Error createStubs(const StubInitsMap &StubInits) = 0; - /// @brief Find the stub with the given name. If ExportedStubsOnly is true, + /// Find the stub with the given name. If ExportedStubsOnly is true, /// this will only return a result if the stub's flags indicate that it /// is exported. - virtual JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) = 0; + virtual JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) = 0; - /// @brief Find the implementation-pointer for the stub. - virtual JITSymbol findPointer(StringRef Name) = 0; + /// Find the implementation-pointer for the stub. + virtual JITEvaluatedSymbol findPointer(StringRef Name) = 0; - /// @brief Change the value of the implementation pointer for the stub. + /// Change the value of the implementation pointer for the stub. virtual Error updatePointer(StringRef Name, JITTargetAddress NewAddr) = 0; private: virtual void anchor(); }; -/// @brief IndirectStubsManager implementation for the host architecture, e.g. +/// IndirectStubsManager implementation for the host architecture, e.g. /// OrcX86_64. (See OrcArchitectureSupport.h). template class LocalIndirectStubsManager : public IndirectStubsManager { @@ -286,7 +226,7 @@ public: return Error::success(); } - JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { + JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { auto I = StubIndexes.find(Name); if (I == StubIndexes.end()) return nullptr; @@ -295,13 +235,13 @@ public: assert(StubAddr && "Missing stub address"); auto StubTargetAddr = static_cast(reinterpret_cast(StubAddr)); - auto StubSymbol = JITSymbol(StubTargetAddr, I->second.second); + auto StubSymbol = JITEvaluatedSymbol(StubTargetAddr, I->second.second); if (ExportedStubsOnly && !StubSymbol.getFlags().isExported()) return nullptr; return StubSymbol; } - JITSymbol findPointer(StringRef Name) override { + JITEvaluatedSymbol findPointer(StringRef Name) override { auto I = StubIndexes.find(Name); if (I == StubIndexes.end()) return nullptr; @@ -310,7 +250,7 @@ public: assert(PtrAddr && "Missing pointer address"); auto PtrTargetAddr = static_cast(reinterpret_cast(PtrAddr)); - return JITSymbol(PtrTargetAddr, I->second.second); + return JITEvaluatedSymbol(PtrTargetAddr, I->second.second); } Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override { @@ -354,45 +294,45 @@ private: StringMap> StubIndexes; }; -/// @brief Create a local compile callback manager. +/// Create a local compile callback manager. /// /// The given target triple will determine the ABI, and the given /// ErrorHandlerAddress will be used by the resulting compile callback /// manager if a compile callback fails. std::unique_ptr -createLocalCompileCallbackManager(const Triple &T, +createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress); -/// @brief Create a local indriect stubs manager builder. +/// Create a local indriect stubs manager builder. /// /// The given target triple will determine the ABI. std::function()> createLocalIndirectStubsManagerBuilder(const Triple &T); -/// @brief Build a function pointer of FunctionType with the given constant +/// Build a function pointer of FunctionType with the given constant /// address. /// /// Usage example: Turn a trampoline address into a function pointer constant /// for use in a stub. Constant *createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr); -/// @brief Create a function pointer with the given type, name, and initializer +/// Create a function pointer with the given type, name, and initializer /// in the given Module. GlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer); -/// @brief Turn a function declaration into a stub function that makes an +/// Turn a function declaration into a stub function that makes an /// indirect call using the given function pointer. void makeStub(Function &F, Value &ImplPointer); -/// @brief Raise linkage types and rename as necessary to ensure that all +/// Raise linkage types and rename as necessary to ensure that all /// symbols are accessible for other modules. /// /// This should be called before partitioning a module to ensure that the /// partitions retain access to each other's symbols. void makeAllSymbolsExternallyAccessible(Module &M); -/// @brief Clone a function declaration into a new module. +/// Clone a function declaration into a new module. /// /// This function can be used as the first step towards creating a callback /// stub (see makeStub), or moving a function body (see moveFunctionBody). @@ -407,7 +347,7 @@ void makeAllSymbolsExternallyAccessible(Module &M); Function *cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap = nullptr); -/// @brief Move the body of function 'F' to a cloned function declaration in a +/// Move the body of function 'F' to a cloned function declaration in a /// different module (See related cloneFunctionDecl). /// /// If the target function declaration is not supplied via the NewF parameter @@ -419,11 +359,11 @@ void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, ValueMaterializer *Materializer = nullptr, Function *NewF = nullptr); -/// @brief Clone a global variable declaration into a new module. +/// Clone a global variable declaration into a new module. GlobalVariable *cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap = nullptr); -/// @brief Move global variable GV from its parent module to cloned global +/// Move global variable GV from its parent module to cloned global /// declaration in a different module. /// /// If the target global declaration is not supplied via the NewGV parameter @@ -436,11 +376,11 @@ void moveGlobalVariableInitializer(GlobalVariable &OrigGV, ValueMaterializer *Materializer = nullptr, GlobalVariable *NewGV = nullptr); -/// @brief Clone a global alias declaration into a new module. +/// Clone a global alias declaration into a new module. GlobalAlias *cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap); -/// @brief Clone module flags metadata into the destination module. +/// Clone module flags metadata into the destination module. void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap); diff --git a/include/llvm/ExecutionEngine/Orc/Layer.h b/include/llvm/ExecutionEngine/Orc/Layer.h new file mode 100644 index 0000000000000000000000000000000000000000..0010fae99a74b62e6d95fc504da7c964e6f2e400 --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/Layer.h @@ -0,0 +1,142 @@ +//===---------------- Layer.h -- Layer interfaces --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Layer interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_LAYER_H +#define LLVM_EXECUTIONENGINE_ORC_LAYER_H + +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/IR/Module.h" + +namespace llvm { +namespace orc { + +/// Mangles symbol names then uniques them in the context of an +/// ExecutionSession. +// +// FIXME: This may be more at home in Core.h. +class MangleAndInterner { +public: + MangleAndInterner(ExecutionSession &ES, const DataLayout &DL); + SymbolStringPtr operator()(StringRef Name); +private: + ExecutionSession &ES; + const DataLayout &DL; +}; + +/// Interface for layers that accept LLVM IR. +class IRLayer { +public: + IRLayer(ExecutionSession &ES); + virtual ~IRLayer(); + + /// Returns the ExecutionSession for this layer. + ExecutionSession &getExecutionSession() { return ES; } + + /// Adds a MaterializationUnit representing the given IR to the given VSO. + virtual Error add(VSO &V, VModuleKey K, std::unique_ptr M); + + /// Emit should materialize the given IR. + virtual void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr M) = 0; + +private: + ExecutionSession &ES; +}; + +/// IRMaterializationUnit is a convenient base class for MaterializationUnits +/// wrapping LLVM IR. Represents materialization responsibility for all symbols +/// in the given module. If symbols are overridden by other definitions, then +/// their linkage is changed to available-externally. +class IRMaterializationUnit : public MaterializationUnit { +public: + using SymbolNameToDefinitionMap = std::map; + + /// Create an IRMaterializationLayer. Scans the module to build the + /// SymbolFlags and SymbolToDefinition maps. + IRMaterializationUnit(ExecutionSession &ES, std::unique_ptr M); + + /// Create an IRMaterializationLayer from a module, and pre-existing + /// SymbolFlags and SymbolToDefinition maps. The maps must provide + /// entries for each definition in M. + /// This constructor is useful for delegating work from one + /// IRMaterializationUnit to another. + IRMaterializationUnit(std::unique_ptr M, SymbolFlagsMap SymbolFlags, + SymbolNameToDefinitionMap SymbolToDefinition); + +protected: + std::unique_ptr M; + SymbolNameToDefinitionMap SymbolToDefinition; + +private: + void discard(const VSO &V, SymbolStringPtr Name) override; +}; + +/// MaterializationUnit that materializes modules by calling the 'emit' method +/// on the given IRLayer. +class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { +public: + BasicIRLayerMaterializationUnit(IRLayer &L, VModuleKey K, + std::unique_ptr M); +private: + + void materialize(MaterializationResponsibility R) override; + + IRLayer &L; + VModuleKey K; +}; + +/// Interface for Layers that accept object files. +class ObjectLayer { +public: + ObjectLayer(ExecutionSession &ES); + virtual ~ObjectLayer(); + + /// Returns the execution session for this layer. + ExecutionSession &getExecutionSession() { return ES; } + + /// Adds a MaterializationUnit representing the given IR to the given VSO. + virtual Error add(VSO &V, VModuleKey K, std::unique_ptr O); + + /// Emit should materialize the given IR. + virtual void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr O) = 0; + +private: + ExecutionSession &ES; +}; + +/// Materializes the given object file (represented by a MemoryBuffer +/// instance) by calling 'emit' on the given ObjectLayer. +class BasicObjectLayerMaterializationUnit : public MaterializationUnit { +public: + + + /// The MemoryBuffer should represent a valid object file. + /// If there is any chance that the file is invalid it should be validated + /// prior to constructing a BasicObjectLayerMaterializationUnit. + BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K, + std::unique_ptr O); + +private: + void materialize(MaterializationResponsibility R) override; + void discard(const VSO &V, SymbolStringPtr Name) override; + + ObjectLayer &L; + VModuleKey K; + std::unique_ptr O; +}; + +} // End namespace orc +} // End namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 4117a9226eee2e2c6d3c9343e2b0ce80f393af4c..46761b0ca7e189cee5028c510a93379aad37b859 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -33,7 +33,7 @@ namespace llvm { namespace orc { -/// @brief Lazy-emitting IR layer. +/// Lazy-emitting IR layer. /// /// This layer accepts LLVM IR Modules (via addModule), but does not /// immediately emit them the layer below. Instead, emissing to the base layer @@ -196,10 +196,10 @@ private: public: - /// @brief Construct a lazy emitting layer. + /// Construct a lazy emitting layer. LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} - /// @brief Add the given module to the lazy emitting layer. + /// Add the given module to the lazy emitting layer. Error addModule(VModuleKey K, std::unique_ptr M) { assert(!ModuleMap.count(K) && "VModuleKey K already in use"); ModuleMap[K] = @@ -207,7 +207,7 @@ public: return Error::success(); } - /// @brief Remove the module represented by the given handle. + /// Remove the module represented by the given handle. /// /// This method will free the memory associated with the given module, both /// in this layer, and the base layer. @@ -219,7 +219,7 @@ public: return EDM->removeModuleFromBaseLayer(BaseLayer); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -239,7 +239,7 @@ public: return nullptr; } - /// @brief Get the address of the given symbol in the context of the of + /// Get the address of the given symbol in the context of the of /// compiled modules represented by the key K. JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, bool ExportedSymbolsOnly) { @@ -247,7 +247,7 @@ public: return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer); } - /// @brief Immediately emit and finalize the module represented by the given + /// Immediately emit and finalize the module represented by the given /// key. Error emitAndFinalize(VModuleKey K) { assert(ModuleMap.count(K) && "VModuleKey K not valid here"); diff --git a/include/llvm/ExecutionEngine/Orc/Legacy.h b/include/llvm/ExecutionEngine/Orc/Legacy.h index b2b389ad339b4d5dca7d95a3c0b386ecb8300590..343daa48432229405dda216c9afce6889c182d8e 100644 --- a/include/llvm/ExecutionEngine/Orc/Legacy.h +++ b/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -22,7 +22,8 @@ namespace orc { class JITSymbolResolverAdapter : public JITSymbolResolver { public: - JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R); + JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R, + MaterializationResponsibility *MR); Expected lookupFlags(const LookupSet &Symbols) override; Expected lookup(const LookupSet &Symbols) override; @@ -30,9 +31,10 @@ private: ExecutionSession &ES; std::set ResolvedStrings; SymbolResolver &R; + MaterializationResponsibility *MR; }; -/// @brief Use the given legacy-style FindSymbol function (i.e. a function that +/// Use the given legacy-style FindSymbol function (i.e. a function that /// takes a const std::string& or StringRef and returns a JITSymbol) to /// find the flags for each symbol in Symbols and store their flags in /// SymbolFlags. If any JITSymbol returned by FindSymbol is in an error @@ -58,49 +60,58 @@ Expected lookupFlagsWithLegacyFn(SymbolFlagsMap &SymbolFlags, return SymbolsNotFound; } -/// @brief Use the given legacy-style FindSymbol function (i.e. a function that +/// Use the given legacy-style FindSymbol function (i.e. a function that /// takes a const std::string& or StringRef and returns a JITSymbol) to /// find the address and flags for each symbol in Symbols and store the /// result in Query. If any JITSymbol returned by FindSymbol is in an -/// error then Query.setFailed(...) is called with that error and the +/// error then Query.notifyFailed(...) is called with that error and the /// function returns immediately. On success, returns the set of symbols /// not found. /// /// Useful for implementing lookup bodies that query legacy resolvers. template -SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query, - const SymbolNameSet &Symbols, - FindSymbolFn FindSymbol) { +SymbolNameSet +lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, + const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) { SymbolNameSet SymbolsNotFound; + bool NewSymbolsResolved = false; for (auto &S : Symbols) { if (JITSymbol Sym = FindSymbol(*S)) { if (auto Addr = Sym.getAddress()) { - Query.setDefinition(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - Query.notifySymbolFinalized(); + Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); + Query.notifySymbolReady(); + NewSymbolsResolved = true; } else { - Query.setFailed(Addr.takeError()); + ES.failQuery(Query, Addr.takeError()); return SymbolNameSet(); } } else if (auto Err = Sym.takeError()) { - Query.setFailed(std::move(Err)); + ES.failQuery(Query, std::move(Err)); return SymbolNameSet(); } else SymbolsNotFound.insert(S); } + if (NewSymbolsResolved && Query.isFullyResolved()) + Query.handleFullyResolved(); + + if (NewSymbolsResolved && Query.isFullyReady()) + Query.handleFullyReady(); + return SymbolsNotFound; } -/// @brief An ORC SymbolResolver implementation that uses a legacy +/// An ORC SymbolResolver implementation that uses a legacy /// findSymbol-like function to perform lookup; template class LegacyLookupFnResolver final : public SymbolResolver { public: using ErrorReporter = std::function; - LegacyLookupFnResolver(LegacyLookupFn LegacyLookup, ErrorReporter ReportError) - : LegacyLookup(std::move(LegacyLookup)), + LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, + ErrorReporter ReportError) + : ES(ES), LegacyLookup(std::move(LegacyLookup)), ReportError(std::move(ReportError)) {} SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, @@ -116,20 +127,21 @@ public: SymbolNameSet lookup(std::shared_ptr Query, SymbolNameSet Symbols) final { - return lookupWithLegacyFn(*Query, Symbols, LegacyLookup); + return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup); } private: + ExecutionSession &ES; LegacyLookupFn LegacyLookup; ErrorReporter ReportError; }; template std::shared_ptr> -createLegacyLookupResolver(LegacyLookupFn LegacyLookup, +createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, std::function ErrorReporter) { return std::make_shared>( - std::move(LegacyLookup), std::move(ErrorReporter)); + ES, std::move(LegacyLookup), std::move(ErrorReporter)); } } // End namespace orc diff --git a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index cfc3922ebb58ef302657cdf778493a81cbdb5b86..c6b43a9c8ed6b8e91c54bfc06c3d60561443fca8 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -15,7 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" #include #include #include @@ -23,7 +23,24 @@ namespace llvm { namespace orc { -/// @brief Object mutating layer. +class ObjectTransformLayer2 : public ObjectLayer { +public: + using TransformFunction = + std::function>( + std::unique_ptr)>; + + ObjectTransformLayer2(ExecutionSession &ES, ObjectLayer &BaseLayer, + TransformFunction Transform); + + void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr O) override; + +private: + ObjectLayer &BaseLayer; + TransformFunction Transform; +}; + +/// Object mutating layer. /// /// This layer accepts sets of ObjectFiles (via addObject). It /// immediately applies the user supplied functor to each object, then adds @@ -31,12 +48,12 @@ namespace orc { template class ObjectTransformLayer { public: - /// @brief Construct an ObjectTransformLayer with the given BaseLayer + /// Construct an ObjectTransformLayer with the given BaseLayer ObjectTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform = TransformFtor()) : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - /// @brief Apply the transform functor to each object in the object set, then + /// Apply the transform functor to each object in the object set, then /// add the resulting set of objects to the base layer, along with the /// memory manager and symbol resolver. /// @@ -45,10 +62,10 @@ public: return BaseLayer.addObject(std::move(K), Transform(std::move(Obj))); } - /// @brief Remove the object set associated with the VModuleKey K. + /// Remove the object set associated with the VModuleKey K. Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -56,7 +73,7 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the set of + /// Get the address of the given symbol in the context of the set of /// objects represented by the VModuleKey K. This call is forwarded to /// the base layer's implementation. /// @param K The VModuleKey associated with the object set to search in. @@ -69,21 +86,21 @@ public: return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the object set represented by the + /// Immediately emit and finalize the object set represented by the /// given VModuleKey K. Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } - /// @brief Map section addresses for the objects associated with the + /// Map section addresses for the objects associated with the /// VModuleKey K. void mapSectionAddress(VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) { BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr); } - /// @brief Access the transform functor directly. + /// Access the transform functor directly. TransformFtor &getTransform() { return Transform; } - /// @brief Access the mumate functor directly. + /// Access the mumate functor directly. const TransformFtor &getTransform() const { return Transform; } private: diff --git a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h index e1b55649b9f2c6f6c82cd7762025954b30d61386..581c598aff6278550645394ad513bcefff974b98 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h @@ -71,7 +71,7 @@ public: } }; -/// @brief Provide information about stub blocks generated by the +/// Provide information about stub blocks generated by the /// makeIndirectStubsBlock function. template class GenericIndirectStubsInfo { public: @@ -92,16 +92,16 @@ public: return *this; } - /// @brief Number of stubs in this block. + /// Number of stubs in this block. unsigned getNumStubs() const { return NumStubs; } - /// @brief Get a pointer to the stub at the given index, which must be in + /// Get a pointer to the stub at the given index, which must be in /// the range 0 .. getNumStubs() - 1. void *getStub(unsigned Idx) const { return static_cast(StubsMem.base()) + Idx * StubSize; } - /// @brief Get a pointer to the implementation-pointer at the given index, + /// Get a pointer to the implementation-pointer at the given index, /// which must be in the range 0 .. getNumStubs() - 1. void **getPtr(unsigned Idx) const { char *PtrsBase = static_cast(StubsMem.base()) + NumStubs * StubSize; @@ -124,18 +124,18 @@ public: using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, void *TrampolineId); - /// @brief Write the resolver code into the given memory. The user is be + /// Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr); - /// @brief Write the requsted number of trampolines into the given memory, + /// Write the requsted number of trampolines into the given memory, /// which must be big enough to hold 1 pointer, plus NumTrampolines /// trampolines. static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines); - /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to + /// Emit at least MinStubs worth of indirect call stubs, rounded out to /// the nearest page size. /// /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k @@ -145,7 +145,7 @@ public: unsigned MinStubs, void *InitialPtrVal); }; -/// @brief X86_64 code that's common to all ABIs. +/// X86_64 code that's common to all ABIs. /// /// X86_64 supports lazy JITing. class OrcX86_64_Base { @@ -155,13 +155,13 @@ public: using IndirectStubsInfo = GenericIndirectStubsInfo<8>; - /// @brief Write the requsted number of trampolines into the given memory, + /// Write the requsted number of trampolines into the given memory, /// which must be big enough to hold 1 pointer, plus NumTrampolines /// trampolines. static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines); - /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to + /// Emit at least MinStubs worth of indirect call stubs, rounded out to /// the nearest page size. /// /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k @@ -171,7 +171,7 @@ public: unsigned MinStubs, void *InitialPtrVal); }; -/// @brief X86_64 support for SysV ABI (Linux, MacOSX). +/// X86_64 support for SysV ABI (Linux, MacOSX). /// /// X86_64_SysV supports lazy JITing. class OrcX86_64_SysV : public OrcX86_64_Base { @@ -181,13 +181,13 @@ public: using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, void *TrampolineId); - /// @brief Write the resolver code into the given memory. The user is be + /// Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr); }; -/// @brief X86_64 support for Win32. +/// X86_64 support for Win32. /// /// X86_64_Win32 supports lazy JITing. class OrcX86_64_Win32 : public OrcX86_64_Base { @@ -197,13 +197,13 @@ public: using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, void *TrampolineId); - /// @brief Write the resolver code into the given memory. The user is be + /// Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr); }; -/// @brief I386 support. +/// I386 support. /// /// I386 supports lazy JITing. class OrcI386 { @@ -217,18 +217,18 @@ public: using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, void *TrampolineId); - /// @brief Write the resolver code into the given memory. The user is be + /// Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr); - /// @brief Write the requsted number of trampolines into the given memory, + /// Write the requsted number of trampolines into the given memory, /// which must be big enough to hold 1 pointer, plus NumTrampolines /// trampolines. static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines); - /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to + /// Emit at least MinStubs worth of indirect call stubs, rounded out to /// the nearest page size. /// /// E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k diff --git a/include/llvm/ExecutionEngine/Orc/OrcError.h b/include/llvm/ExecutionEngine/Orc/OrcError.h index c2ff41e421e70d02f4e0b62c8d7c281208cc6b97..dc60e8d74e9755f89dbf9a392c3bd5b6b614c627 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcError.h +++ b/include/llvm/ExecutionEngine/Orc/OrcError.h @@ -22,7 +22,8 @@ namespace orc { enum class OrcErrorCode : int { // RPC Errors - DuplicateDefinition = 1, + UnknownORCError = 1, + DuplicateDefinition, JITSymbolNotFound, RemoteAllocatorDoesNotExist, RemoteAllocatorIdAlreadyInUse, diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h index 7179e5ff66fdd6ed78e72599bce49762bccc60e6..739e5ba47c1214a56f4a6ab0ba4175029e21bf80 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h @@ -63,7 +63,7 @@ public: public: ~RemoteRTDyldMemoryManager() { Client.destroyRemoteAllocator(Id); - DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n"); + LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n"); } RemoteRTDyldMemoryManager(const RemoteRTDyldMemoryManager &) = delete; @@ -79,9 +79,9 @@ public: Unmapped.back().CodeAllocs.emplace_back(Size, Alignment); uint8_t *Alloc = reinterpret_cast( Unmapped.back().CodeAllocs.back().getLocalAddress()); - DEBUG(dbgs() << "Allocator " << Id << " allocated code for " - << SectionName << ": " << Alloc << " (" << Size - << " bytes, alignment " << Alignment << ")\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated code for " + << SectionName << ": " << Alloc << " (" << Size + << " bytes, alignment " << Alignment << ")\n"); return Alloc; } @@ -92,18 +92,18 @@ public: Unmapped.back().RODataAllocs.emplace_back(Size, Alignment); uint8_t *Alloc = reinterpret_cast( Unmapped.back().RODataAllocs.back().getLocalAddress()); - DEBUG(dbgs() << "Allocator " << Id << " allocated ro-data for " - << SectionName << ": " << Alloc << " (" << Size - << " bytes, alignment " << Alignment << ")\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated ro-data for " + << SectionName << ": " << Alloc << " (" << Size + << " bytes, alignment " << Alignment << ")\n"); return Alloc; } // else... Unmapped.back().RWDataAllocs.emplace_back(Size, Alignment); uint8_t *Alloc = reinterpret_cast( Unmapped.back().RWDataAllocs.back().getLocalAddress()); - DEBUG(dbgs() << "Allocator " << Id << " allocated rw-data for " - << SectionName << ": " << Alloc << " (" << Size - << " bytes, alignment " << Alignment << ")\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated rw-data for " + << SectionName << ": " << Alloc << " (" << Size + << " bytes, alignment " << Alignment << ")\n"); return Alloc; } @@ -113,36 +113,36 @@ public: uint32_t RWDataAlign) override { Unmapped.push_back(ObjectAllocs()); - DEBUG(dbgs() << "Allocator " << Id << " reserved:\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " reserved:\n"); if (CodeSize != 0) { Unmapped.back().RemoteCodeAddr = Client.reserveMem(Id, CodeSize, CodeAlign); - DEBUG(dbgs() << " code: " - << format("0x%016x", Unmapped.back().RemoteCodeAddr) - << " (" << CodeSize << " bytes, alignment " << CodeAlign - << ")\n"); + LLVM_DEBUG(dbgs() << " code: " + << format("0x%016x", Unmapped.back().RemoteCodeAddr) + << " (" << CodeSize << " bytes, alignment " + << CodeAlign << ")\n"); } if (RODataSize != 0) { Unmapped.back().RemoteRODataAddr = Client.reserveMem(Id, RODataSize, RODataAlign); - DEBUG(dbgs() << " ro-data: " - << format("0x%016x", Unmapped.back().RemoteRODataAddr) - << " (" << RODataSize << " bytes, alignment " - << RODataAlign << ")\n"); + LLVM_DEBUG(dbgs() << " ro-data: " + << format("0x%016x", Unmapped.back().RemoteRODataAddr) + << " (" << RODataSize << " bytes, alignment " + << RODataAlign << ")\n"); } if (RWDataSize != 0) { Unmapped.back().RemoteRWDataAddr = Client.reserveMem(Id, RWDataSize, RWDataAlign); - DEBUG(dbgs() << " rw-data: " - << format("0x%016x", Unmapped.back().RemoteRWDataAddr) - << " (" << RWDataSize << " bytes, alignment " - << RWDataAlign << ")\n"); + LLVM_DEBUG(dbgs() << " rw-data: " + << format("0x%016x", Unmapped.back().RemoteRWDataAddr) + << " (" << RWDataSize << " bytes, alignment " + << RWDataAlign << ")\n"); } } @@ -162,7 +162,7 @@ public: void notifyObjectLoaded(RuntimeDyld &Dyld, const object::ObjectFile &Obj) override { - DEBUG(dbgs() << "Allocator " << Id << " applied mappings:\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " applied mappings:\n"); for (auto &ObjAllocs : Unmapped) { mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs, ObjAllocs.RemoteCodeAddr); @@ -176,7 +176,7 @@ public: } bool finalizeMemory(std::string *ErrMsg = nullptr) override { - DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n"); + LLVM_DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n"); for (auto &ObjAllocs : Unfinalized) { if (copyAndProtect(ObjAllocs.CodeAllocs, ObjAllocs.RemoteCodeAddr, @@ -261,7 +261,7 @@ public: RemoteRTDyldMemoryManager(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id) : Client(Client), Id(Id) { - DEBUG(dbgs() << "Created remote allocator " << Id << "\n"); + LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n"); } // Maps all allocations in Allocs to aligned blocks @@ -270,8 +270,9 @@ public: for (auto &Alloc : Allocs) { NextAddr = alignTo(NextAddr, Alloc.getAlign()); Dyld.mapSectionAddress(Alloc.getLocalAddress(), NextAddr); - DEBUG(dbgs() << " " << static_cast(Alloc.getLocalAddress()) - << " -> " << format("0x%016x", NextAddr) << "\n"); + LLVM_DEBUG(dbgs() << " " + << static_cast(Alloc.getLocalAddress()) + << " -> " << format("0x%016x", NextAddr) << "\n"); Alloc.setRemoteAddress(NextAddr); // Only advance NextAddr if it was non-null to begin with, @@ -290,22 +291,23 @@ public: assert(!Allocs.empty() && "No sections in allocated segment"); for (auto &Alloc : Allocs) { - DEBUG(dbgs() << " copying section: " - << static_cast(Alloc.getLocalAddress()) << " -> " - << format("0x%016x", Alloc.getRemoteAddress()) << " (" - << Alloc.getSize() << " bytes)\n";); + LLVM_DEBUG(dbgs() << " copying section: " + << static_cast(Alloc.getLocalAddress()) + << " -> " + << format("0x%016x", Alloc.getRemoteAddress()) + << " (" << Alloc.getSize() << " bytes)\n";); if (Client.writeMem(Alloc.getRemoteAddress(), Alloc.getLocalAddress(), Alloc.getSize())) return true; } - DEBUG(dbgs() << " setting " - << (Permissions & sys::Memory::MF_READ ? 'R' : '-') - << (Permissions & sys::Memory::MF_WRITE ? 'W' : '-') - << (Permissions & sys::Memory::MF_EXEC ? 'X' : '-') - << " permissions on block: " - << format("0x%016x", RemoteSegmentAddr) << "\n"); + LLVM_DEBUG(dbgs() << " setting " + << (Permissions & sys::Memory::MF_READ ? 'R' : '-') + << (Permissions & sys::Memory::MF_WRITE ? 'W' : '-') + << (Permissions & sys::Memory::MF_EXEC ? 'X' : '-') + << " permissions on block: " + << format("0x%016x", RemoteSegmentAddr) << "\n"); if (Client.setProtections(Id, RemoteSegmentAddr, Permissions)) return true; } @@ -356,25 +358,25 @@ public: return Error::success(); } - JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { + JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { auto I = StubIndexes.find(Name); if (I == StubIndexes.end()) return nullptr; auto Key = I->second.first; auto Flags = I->second.second; - auto StubSymbol = JITSymbol(getStubAddr(Key), Flags); + auto StubSymbol = JITEvaluatedSymbol(getStubAddr(Key), Flags); if (ExportedStubsOnly && !StubSymbol.getFlags().isExported()) return nullptr; return StubSymbol; } - JITSymbol findPointer(StringRef Name) override { + JITEvaluatedSymbol findPointer(StringRef Name) override { auto I = StubIndexes.find(Name); if (I == StubIndexes.end()) return nullptr; auto Key = I->second.first; auto Flags = I->second.second; - return JITSymbol(getPtrAddr(Key), Flags); + return JITEvaluatedSymbol(getPtrAddr(Key), Flags); } Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override { @@ -449,8 +451,9 @@ public: class RemoteCompileCallbackManager : public JITCompileCallbackManager { public: RemoteCompileCallbackManager(OrcRemoteTargetClient &Client, + ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress) - : JITCompileCallbackManager(ErrorHandlerAddress), Client(Client) {} + : JITCompileCallbackManager(ES, ErrorHandlerAddress), Client(Client) {} private: Error grow() override { @@ -475,10 +478,10 @@ public: /// Channel is the ChannelT instance to communicate on. It is assumed that /// the channel is ready to be read from and written to. static Expected> - Create(rpc::RawByteChannel &Channel, std::function ReportError) { + Create(rpc::RawByteChannel &Channel, ExecutionSession &ES) { Error Err = Error::success(); auto Client = std::unique_ptr( - new OrcRemoteTargetClient(Channel, std::move(ReportError), Err)); + new OrcRemoteTargetClient(Channel, ES, Err)); if (Err) return std::move(Err); return std::move(Client); @@ -487,7 +490,8 @@ public: /// Call the int(void) function at the given address in the target and return /// its result. Expected callIntVoid(JITTargetAddress Addr) { - DEBUG(dbgs() << "Calling int(*)(void) " << format("0x%016x", Addr) << "\n"); + LLVM_DEBUG(dbgs() << "Calling int(*)(void) " << format("0x%016x", Addr) + << "\n"); return callB(Addr); } @@ -495,16 +499,16 @@ public: /// return its result. Expected callMain(JITTargetAddress Addr, const std::vector &Args) { - DEBUG(dbgs() << "Calling int(*)(int, char*[]) " << format("0x%016x", Addr) - << "\n"); + LLVM_DEBUG(dbgs() << "Calling int(*)(int, char*[]) " + << format("0x%016x", Addr) << "\n"); return callB(Addr, Args); } /// Call the void() function at the given address in the target and wait for /// it to finish. Error callVoidVoid(JITTargetAddress Addr) { - DEBUG(dbgs() << "Calling void(*)(void) " << format("0x%016x", Addr) - << "\n"); + LLVM_DEBUG(dbgs() << "Calling void(*)(void) " << format("0x%016x", Addr) + << "\n"); return callB(Addr); } @@ -531,12 +535,14 @@ public: Expected enableCompileCallbacks(JITTargetAddress ErrorHandlerAddress) { + assert(!CallbackManager && "CallbackManager already obtained"); + // Emit the resolver block on the JIT server. if (auto Err = callB()) return std::move(Err); // Create the callback manager. - CallbackManager.emplace(*this, ErrorHandlerAddress); + CallbackManager.emplace(*this, ES, ErrorHandlerAddress); RemoteCompileCallbackManager &Mgr = *CallbackManager; return Mgr; } @@ -554,10 +560,10 @@ public: Error terminateSession() { return callB(); } private: - OrcRemoteTargetClient(rpc::RawByteChannel &Channel, - std::function ReportError, Error &Err) + OrcRemoteTargetClient(rpc::RawByteChannel &Channel, ExecutionSession &ES, + Error &Err) : rpc::SingleThreadedRPCEndpoint(Channel, true), - ReportError(std::move(ReportError)) { + ES(ES) { ErrorAsOutParameter EAO(&Err); addHandler( @@ -577,7 +583,7 @@ private: void deregisterEHFrames(JITTargetAddress Addr, uint32_t Size) { if (auto Err = callB(Addr, Size)) - ReportError(std::move(Err)); + ES.reportError(std::move(Err)); } void destroyRemoteAllocator(ResourceIdMgr::ResourceId Id) { @@ -592,7 +598,7 @@ private: void destroyIndirectStubsManager(ResourceIdMgr::ResourceId Id) { IndirectStubOwnerIds.release(Id); if (auto Err = callB(Id)) - ReportError(std::move(Err)); + ES.reportError(std::move(Err)); } Expected> @@ -625,7 +631,7 @@ private: if (auto AddrOrErr = callB(Id, Size, Align)) return *AddrOrErr; else { - ReportError(AddrOrErr.takeError()); + ES.reportError(AddrOrErr.takeError()); return 0; } } @@ -633,7 +639,7 @@ private: bool setProtections(ResourceIdMgr::ResourceId Id, JITTargetAddress RemoteSegAddr, unsigned ProtFlags) { if (auto Err = callB(Id, RemoteSegAddr, ProtFlags)) { - ReportError(std::move(Err)); + ES.reportError(std::move(Err)); return true; } else return false; @@ -641,7 +647,7 @@ private: bool writeMem(JITTargetAddress Addr, const char *Src, uint64_t Size) { if (auto Err = callB(DirectBufferWriter(Src, Addr, Size))) { - ReportError(std::move(Err)); + ES.reportError(std::move(Err)); return true; } else return false; @@ -653,6 +659,7 @@ private: static Error doNothing() { return Error::success(); } + ExecutionSession &ES; std::function ReportError; std::string RemoteTargetTriple; uint32_t RemotePointerSize = 0; diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h index cf419d33004cb6c46ef5667fd63f9578eb50d5ac..acbc1682fa5d06772b1c8e86e8d25efd563c451e 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -161,9 +161,9 @@ private: IntVoidFnTy Fn = reinterpret_cast(static_cast(Addr)); - DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); + LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); int Result = Fn(); - DEBUG(dbgs() << " Result = " << Result << "\n"); + LLVM_DEBUG(dbgs() << " Result = " << Result << "\n"); return Result; } @@ -180,15 +180,13 @@ private: for (auto &Arg : Args) ArgV[Idx++] = Arg.c_str(); ArgV[ArgC] = 0; - DEBUG( - for (int Idx = 0; Idx < ArgC; ++Idx) { - llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n"; - } - ); + LLVM_DEBUG(for (int Idx = 0; Idx < ArgC; ++Idx) { + llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n"; + }); - DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); + LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); int Result = Fn(ArgC, ArgV.get()); - DEBUG(dbgs() << " Result = " << Result << "\n"); + LLVM_DEBUG(dbgs() << " Result = " << Result << "\n"); return Result; } @@ -199,9 +197,9 @@ private: VoidVoidFnTy Fn = reinterpret_cast(static_cast(Addr)); - DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); + LLVM_DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); Fn(); - DEBUG(dbgs() << " Complete.\n"); + LLVM_DEBUG(dbgs() << " Complete.\n"); return Error::success(); } @@ -211,7 +209,7 @@ private: if (I != Allocators.end()) return errorCodeToError( orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse)); - DEBUG(dbgs() << " Created allocator " << Id << "\n"); + LLVM_DEBUG(dbgs() << " Created allocator " << Id << "\n"); Allocators[Id] = Allocator(); return Error::success(); } @@ -221,15 +219,16 @@ private: if (I != IndirectStubsOwners.end()) return errorCodeToError( orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse)); - DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n"); + LLVM_DEBUG(dbgs() << " Create indirect stubs owner " << Id << "\n"); IndirectStubsOwners[Id] = ISBlockOwnerList(); return Error::success(); } Error handleDeregisterEHFrames(JITTargetAddress TAddr, uint32_t Size) { uint8_t *Addr = reinterpret_cast(static_cast(TAddr)); - DEBUG(dbgs() << " Registering EH frames at " << format("0x%016x", TAddr) - << ", Size = " << Size << " bytes\n"); + LLVM_DEBUG(dbgs() << " Registering EH frames at " + << format("0x%016x", TAddr) << ", Size = " << Size + << " bytes\n"); EHFramesDeregister(Addr, Size); return Error::success(); } @@ -240,7 +239,7 @@ private: return errorCodeToError( orcError(OrcErrorCode::RemoteAllocatorDoesNotExist)); Allocators.erase(I); - DEBUG(dbgs() << " Destroyed allocator " << Id << "\n"); + LLVM_DEBUG(dbgs() << " Destroyed allocator " << Id << "\n"); return Error::success(); } @@ -256,8 +255,8 @@ private: Expected> handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id, uint32_t NumStubsRequired) { - DEBUG(dbgs() << " ISMgr " << Id << " request " << NumStubsRequired - << " stubs.\n"); + LLVM_DEBUG(dbgs() << " ISMgr " << Id << " request " << NumStubsRequired + << " stubs.\n"); auto StubOwnerItr = IndirectStubsOwners.find(Id); if (StubOwnerItr == IndirectStubsOwners.end()) @@ -328,8 +327,8 @@ private: Expected handleGetSymbolAddress(const std::string &Name) { JITTargetAddress Addr = SymbolLookup(Name); - DEBUG(dbgs() << " Symbol '" << Name << "' = " << format("0x%016x", Addr) - << "\n"); + LLVM_DEBUG(dbgs() << " Symbol '" << Name + << "' = " << format("0x%016x", Addr) << "\n"); return Addr; } @@ -340,12 +339,13 @@ private: uint32_t PageSize = sys::Process::getPageSize(); uint32_t TrampolineSize = TargetT::TrampolineSize; uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize; - DEBUG(dbgs() << " Remote info:\n" - << " triple = '" << ProcessTriple << "'\n" - << " pointer size = " << PointerSize << "\n" - << " page size = " << PageSize << "\n" - << " trampoline size = " << TrampolineSize << "\n" - << " indirect stub size = " << IndirectStubSize << "\n"); + LLVM_DEBUG(dbgs() << " Remote info:\n" + << " triple = '" << ProcessTriple << "'\n" + << " pointer size = " << PointerSize << "\n" + << " page size = " << PageSize << "\n" + << " trampoline size = " << TrampolineSize << "\n" + << " indirect stub size = " << IndirectStubSize + << "\n"); return std::make_tuple(ProcessTriple, PointerSize, PageSize, TrampolineSize, IndirectStubSize); } @@ -354,8 +354,8 @@ private: uint64_t Size) { uint8_t *Src = reinterpret_cast(static_cast(RSrc)); - DEBUG(dbgs() << " Reading " << Size << " bytes from " - << format("0x%016x", RSrc) << "\n"); + LLVM_DEBUG(dbgs() << " Reading " << Size << " bytes from " + << format("0x%016x", RSrc) << "\n"); std::vector Buffer; Buffer.resize(Size); @@ -367,8 +367,9 @@ private: Error handleRegisterEHFrames(JITTargetAddress TAddr, uint32_t Size) { uint8_t *Addr = reinterpret_cast(static_cast(TAddr)); - DEBUG(dbgs() << " Registering EH frames at " << format("0x%016x", TAddr) - << ", Size = " << Size << " bytes\n"); + LLVM_DEBUG(dbgs() << " Registering EH frames at " + << format("0x%016x", TAddr) << ", Size = " << Size + << " bytes\n"); EHFramesRegister(Addr, Size); return Error::success(); } @@ -384,8 +385,9 @@ private: if (auto Err = Allocator.allocate(LocalAllocAddr, Size, Align)) return std::move(Err); - DEBUG(dbgs() << " Allocator " << Id << " reserved " << LocalAllocAddr - << " (" << Size << " bytes, alignment " << Align << ")\n"); + LLVM_DEBUG(dbgs() << " Allocator " << Id << " reserved " << LocalAllocAddr + << " (" << Size << " bytes, alignment " << Align + << ")\n"); JITTargetAddress AllocAddr = static_cast( reinterpret_cast(LocalAllocAddr)); @@ -401,10 +403,11 @@ private: orcError(OrcErrorCode::RemoteAllocatorDoesNotExist)); auto &Allocator = I->second; void *LocalAddr = reinterpret_cast(static_cast(Addr)); - DEBUG(dbgs() << " Allocator " << Id << " set permissions on " << LocalAddr - << " to " << (Flags & sys::Memory::MF_READ ? 'R' : '-') - << (Flags & sys::Memory::MF_WRITE ? 'W' : '-') - << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n"); + LLVM_DEBUG(dbgs() << " Allocator " << Id << " set permissions on " + << LocalAddr << " to " + << (Flags & sys::Memory::MF_READ ? 'R' : '-') + << (Flags & sys::Memory::MF_WRITE ? 'W' : '-') + << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n"); return Allocator.setProtections(LocalAddr, Flags); } @@ -414,14 +417,14 @@ private: } Error handleWriteMem(DirectBufferWriter DBW) { - DEBUG(dbgs() << " Writing " << DBW.getSize() << " bytes to " - << format("0x%016x", DBW.getDst()) << "\n"); + LLVM_DEBUG(dbgs() << " Writing " << DBW.getSize() << " bytes to " + << format("0x%016x", DBW.getDst()) << "\n"); return Error::success(); } Error handleWritePtr(JITTargetAddress Addr, JITTargetAddress PtrVal) { - DEBUG(dbgs() << " Writing pointer *" << format("0x%016x", Addr) << " = " - << format("0x%016x", PtrVal) << "\n"); + LLVM_DEBUG(dbgs() << " Writing pointer *" << format("0x%016x", Addr) + << " = " << format("0x%016x", PtrVal) << "\n"); uintptr_t *Ptr = reinterpret_cast(static_cast(Addr)); *Ptr = static_cast(PtrVal); diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index c278cb176853ba3f88faaa0006b05bd2b3f5d781..47bd90bb1bada3960d66eebf64369f636fc38d0b 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -1631,7 +1631,7 @@ RPCAsyncDispatch rpcAsyncDispatch(RPCEndpointT &Endpoint) { return RPCAsyncDispatch(Endpoint); } -/// \brief Allows a set of asynchrounous calls to be dispatched, and then +/// Allows a set of asynchrounous calls to be dispatched, and then /// waited on as a group. class ParallelCallGroup { public: @@ -1640,7 +1640,7 @@ public: ParallelCallGroup(const ParallelCallGroup &) = delete; ParallelCallGroup &operator=(const ParallelCallGroup &) = delete; - /// \brief Make as asynchronous call. + /// Make as asynchronous call. template Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler, const ArgTs &... Args) { @@ -1669,7 +1669,7 @@ public: return AsyncDispatch(std::move(WrappedHandler), Args...); } - /// \brief Blocks until all calls have been completed and their return value + /// Blocks until all calls have been completed and their return value /// handlers run. void wait() { std::unique_lock Lock(M); @@ -1683,21 +1683,21 @@ private: uint32_t NumOutstandingCalls = 0; }; -/// @brief Convenience class for grouping RPC Functions into APIs that can be +/// Convenience class for grouping RPC Functions into APIs that can be /// negotiated as a block. /// template class APICalls { public: - /// @brief Test whether this API contains Function F. + /// Test whether this API contains Function F. template class Contains { public: static const bool value = false; }; - /// @brief Negotiate all functions in this API. + /// Negotiate all functions in this API. template static Error negotiate(RPCEndpoint &R) { return Error::success(); diff --git a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 8f0d9fa6eb641028f7d8d1ef7186df8f44c83eee..84ceea40be07f65851580f7d8a592154cce03bde 100644 --- a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" #include "llvm/ExecutionEngine/Orc/Legacy.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" @@ -35,13 +36,66 @@ namespace llvm { namespace orc { +class RTDyldObjectLinkingLayer2 : public ObjectLayer { +public: + /// Functor for receiving object-loaded notifications. + using NotifyLoadedFunction = + std::function; + + /// Functor for receiving finalization notifications. + using NotifyFinalizedFunction = std::function; + + struct Resources { + std::shared_ptr MemMgr; + std::shared_ptr Resolver; + }; + + using ResourcesGetterFunction = std::function; + + /// Construct an ObjectLinkingLayer with the given NotifyLoaded, + /// and NotifyFinalized functors. + RTDyldObjectLinkingLayer2( + ExecutionSession &ES, ResourcesGetterFunction GetResources, + NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(), + NotifyFinalizedFunction NotifyFinalized = NotifyFinalizedFunction()); + + /// Emit the object. + void emit(MaterializationResponsibility R, VModuleKey K, + std::unique_ptr O) override; + + /// Map section addresses for the object associated with the + /// VModuleKey K. + void mapSectionAddress(VModuleKey K, const void *LocalAddress, + JITTargetAddress TargetAddr) const; + + /// Set the 'ProcessAllSections' flag. + /// + /// If set to true, all sections in each object file will be allocated using + /// the memory manager, rather than just the sections required for execution. + /// + /// This is kludgy, and may be removed in the future. + void setProcessAllSections(bool ProcessAllSections) { + this->ProcessAllSections = ProcessAllSections; + } + +private: + mutable std::mutex RTDyldLayerMutex; + ResourcesGetterFunction GetResources; + NotifyLoadedFunction NotifyLoaded; + NotifyFinalizedFunction NotifyFinalized; + bool ProcessAllSections; + std::map ActiveRTDylds; + std::map> MemMgrs; +}; + class RTDyldObjectLinkingLayerBase { public: using ObjectPtr = std::unique_ptr; protected: - /// @brief Holds an object to be allocated/linked as a unit in the JIT. + /// Holds an object to be allocated/linked as a unit in the JIT. /// /// An instance of this class will be created for each object added /// via JITObjectLayer::addObject. Deleting the instance (via @@ -81,7 +135,7 @@ protected: }; }; -/// @brief Bare bones object linking layer. +/// Bare bones object linking layer. /// /// This class is intended to be used as the base layer for a JIT. It allows /// object files to be loaded into memory, linked, and the addresses of their @@ -92,13 +146,18 @@ public: using RTDyldObjectLinkingLayerBase::ObjectPtr; - /// @brief Functor for receiving object-loaded notifications. + /// Functor for receiving object-loaded notifications. using NotifyLoadedFtor = std::function; - /// @brief Functor for receiving finalization notifications. - using NotifyFinalizedFtor = std::function; + /// Functor for receiving finalization notifications. + using NotifyFinalizedFtor = + std::function; + + /// Functor for receiving deallocation notifications. + using NotifyFreedFtor = std::function; private: using OwnedObject = object::OwningBinary; @@ -110,21 +169,27 @@ private: OwnedObject Obj, MemoryManagerPtrT MemMgr, std::shared_ptr Resolver, bool ProcessAllSections) - : MemMgr(std::move(MemMgr)), + : K(std::move(K)), + Parent(Parent), + MemMgr(std::move(MemMgr)), PFC(llvm::make_unique( - Parent, std::move(K), std::move(Obj), std::move(Resolver), + std::move(Obj), std::move(Resolver), ProcessAllSections)) { buildInitialSymbolTable(PFC->Obj); } ~ConcreteLinkedObject() override { + if (this->Parent.NotifyFreed) + this->Parent.NotifyFreed(K, *ObjForNotify.getBinary()); + MemMgr->deregisterEHFrames(); } Error finalize() override { assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - JITSymbolResolverAdapter ResolverAdapter(PFC->Parent.ES, *PFC->Resolver); + JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver, + nullptr); PFC->RTDyld = llvm::make_unique(*MemMgr, ResolverAdapter); PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections); @@ -140,8 +205,8 @@ private: SymbolTable[KV.first] = KV.second; } - if (PFC->Parent.NotifyLoaded) - PFC->Parent.NotifyLoaded(PFC->K, *PFC->Obj.getBinary(), *Info); + if (Parent.NotifyLoaded) + Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info); PFC->RTDyld->finalizeWithMemoryManagerLocking(); @@ -149,10 +214,12 @@ private: return make_error(PFC->RTDyld->getErrorString(), inconvertibleErrorCode()); - if (PFC->Parent.NotifyFinalized) - PFC->Parent.NotifyFinalized(PFC->K); + if (Parent.NotifyFinalized) + Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info); // Release resources. + if (this->Parent.NotifyFreed) + ObjForNotify = std::move(PFC->Obj); // needed for callback PFC = nullptr; return Error::success(); } @@ -195,23 +262,23 @@ private: // Contains the information needed prior to finalization: the object files, // memory manager, resolver, and flags needed for RuntimeDyld. struct PreFinalizeContents { - PreFinalizeContents(RTDyldObjectLinkingLayer &Parent, VModuleKey K, - OwnedObject Obj, + PreFinalizeContents(OwnedObject Obj, std::shared_ptr Resolver, bool ProcessAllSections) - : Parent(Parent), K(std::move(K)), Obj(std::move(Obj)), + : Obj(std::move(Obj)), Resolver(std::move(Resolver)), ProcessAllSections(ProcessAllSections) {} - RTDyldObjectLinkingLayer &Parent; - VModuleKey K; OwnedObject Obj; std::shared_ptr Resolver; bool ProcessAllSections; std::unique_ptr RTDyld; }; + VModuleKey K; + RTDyldObjectLinkingLayer &Parent; MemoryManagerPtrT MemMgr; + OwnedObject ObjForNotify; std::unique_ptr PFC; }; @@ -235,18 +302,21 @@ public: using ResourcesGetter = std::function; - /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded, + /// Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyFinalized functors. RTDyldObjectLinkingLayer( ExecutionSession &ES, ResourcesGetter GetResources, NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), - NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor()) + NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), + NotifyFreedFtor NotifyFreed = NotifyFreedFtor()) : ES(ES), GetResources(std::move(GetResources)), NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) { + NotifyFinalized(std::move(NotifyFinalized)), + NotifyFreed(std::move(NotifyFreed)), + ProcessAllSections(false) { } - /// @brief Set the 'ProcessAllSections' flag. + /// Set the 'ProcessAllSections' flag. /// /// If set to true, all sections in each object file will be allocated using /// the memory manager, rather than just the sections required for execution. @@ -256,7 +326,7 @@ public: this->ProcessAllSections = ProcessAllSections; } - /// @brief Add an object to the JIT. + /// Add an object to the JIT. Error addObject(VModuleKey K, ObjectPtr ObjBuffer) { auto Obj = @@ -275,7 +345,7 @@ public: return Error::success(); } - /// @brief Remove the object associated with VModuleKey K. + /// Remove the object associated with VModuleKey K. /// /// All memory allocated for the object will be freed, and the sections and /// symbols it provided will no longer be available. No attempt is made to @@ -290,7 +360,7 @@ public: return Error::success(); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. @@ -304,7 +374,7 @@ public: return nullptr; } - /// @brief Search for the given named symbol in the context of the loaded + /// Search for the given named symbol in the context of the loaded /// object represented by the VModuleKey K. /// @param K The VModuleKey for the object to search in. /// @param Name The name of the symbol to search for. @@ -317,7 +387,7 @@ public: return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly); } - /// @brief Map section addresses for the object associated with the + /// Map section addresses for the object associated with the /// VModuleKey K. void mapSectionAddress(VModuleKey K, const void *LocalAddress, JITTargetAddress TargetAddr) { @@ -325,7 +395,7 @@ public: LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr); } - /// @brief Immediately emit and finalize the object represented by the given + /// Immediately emit and finalize the object represented by the given /// VModuleKey. /// @param K VModuleKey for object to emit/finalize. Error emitAndFinalize(VModuleKey K) { @@ -340,6 +410,7 @@ private: ResourcesGetter GetResources; NotifyLoadedFtor NotifyLoaded; NotifyFinalizedFtor NotifyFinalized; + NotifyFreedFtor NotifyFreed; bool ProcessAllSections = false; }; diff --git a/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h b/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h index b95faaa5d8def1bde5d48475dbf3173342dc043a..955e77607a18b76bdff50d08262b6e246ceded72 100644 --- a/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h @@ -322,7 +322,7 @@ public: *this, &ThisT::lookupInLogicalDylib); } - /// @brief Add an object to the JIT. + /// Add an object to the JIT. /// /// @return A handle that can be used to refer to the loaded object (for /// symbol searching, finalization, freeing memory, etc.). @@ -340,26 +340,26 @@ public: return HandleOrErr.takeError(); } - /// @brief Remove the given object from the JIT. + /// Remove the given object from the JIT. Error removeObject(ObjHandleT H) { return this->Remote.template callB(H); } - /// @brief Search for the given named symbol. + /// Search for the given named symbol. JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { return remoteToJITSymbol( this->Remote.template callB(Name, ExportedSymbolsOnly)); } - /// @brief Search for the given named symbol within the given context. + /// Search for the given named symbol within the given context. JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) { return remoteToJITSymbol( this->Remote.template callB(H, Name, ExportedSymbolsOnly)); } - /// @brief Immediately emit and finalize the object with the given handle. + /// Immediately emit and finalize the object with the given handle. Error emitAndFinalize(ObjHandleT H) { return this->Remote.template callB(H); } diff --git a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h index da40d1caaabef8357c0c3f4725d774bf5c8f4ee3..4c45cfd199dd21c5982003d86d67a5b9a2f022dd 100644 --- a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h +++ b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h @@ -23,17 +23,20 @@ namespace orc { class SymbolStringPtr; -/// @brief String pool for symbol names used by the JIT. +/// String pool for symbol names used by the JIT. class SymbolStringPool { friend class SymbolStringPtr; public: - /// @brief Create a symbol string pointer from the given string. + /// Destroy a SymbolStringPool. + ~SymbolStringPool(); + + /// Create a symbol string pointer from the given string. SymbolStringPtr intern(StringRef S); - /// @brief Remove from the pool any entries that are no longer referenced. + /// Remove from the pool any entries that are no longer referenced. void clearDeadEntries(); - /// @brief Returns true if the pool is empty. + /// Returns true if the pool is empty. bool empty() const; private: using RefCountType = std::atomic; @@ -43,7 +46,7 @@ private: PoolMap Pool; }; -/// @brief Pointer to a pooled string representing a symbol name. +/// Pointer to a pooled string representing a symbol name. class SymbolStringPtr { friend class SymbolStringPool; friend bool operator==(const SymbolStringPtr &LHS, @@ -109,6 +112,13 @@ inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) { return LHS.S < RHS.S; } +inline SymbolStringPool::~SymbolStringPool() { +#ifndef NDEBUG + clearDeadEntries(); + assert(Pool.empty() && "Dangling references at pool destruction time"); +#endif // NDEBUG +} + inline SymbolStringPtr SymbolStringPool::intern(StringRef S) { std::lock_guard Lock(PoolMutex); PoolMap::iterator I; diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h index ee75202d2b621a9ddfd821403286a3cbd7e206a9..23d651f6d1b63b1239ee350f24c3778bf6b10bd5 100644 --- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -47,6 +47,9 @@ public: /// newly loaded object. virtual void notifyObjectLoaded(ExecutionEngine *EE, const object::ObjectFile &) {} + +private: + void anchor() override; }; // RuntimeDyld clients often want to handle the memory management of @@ -142,6 +145,9 @@ protected: }; typedef std::vector EHFrameInfos; EHFrameInfos EHFrames; + +private: + void anchor() override; }; // Create wrappers for C Binding types (see CBindingWrapping.h). diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 14da5af020611a97ad048ff1076439c8cb5c20be..5dd5add1bb393620074e6c734bf605d97ca4d350 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -65,7 +65,7 @@ protected: void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: - /// \brief Information about the loaded object. + /// Information about the loaded object. class LoadedObjectInfo : public llvm::LoadedObjectInfo { friend class RuntimeDyldImpl; @@ -88,7 +88,7 @@ public: ObjSectionToIDMap ObjSecToIDMap; }; - /// \brief Memory Management. + /// Memory Management. class MemoryManager { friend class RuntimeDyld; @@ -170,7 +170,7 @@ public: bool FinalizationLocked = false; }; - /// \brief Construct a RuntimeDyld instance. + /// Construct a RuntimeDyld instance. RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver); RuntimeDyld(const RuntimeDyld &) = delete; RuntimeDyld &operator=(const RuntimeDyld &) = delete; diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index de89f405af4c4b15d7e29525c6445861ff7385f2..13fc5fd5a3e74328f4afc72abd9c3fd24d042303 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -27,7 +27,7 @@ class RuntimeDyld; class RuntimeDyldCheckerImpl; class raw_ostream; -/// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has +/// RuntimeDyld invariant checker for verifying that RuntimeDyld has /// correctly applied relocations. /// /// The RuntimeDyldChecker class evaluates expressions against an attached @@ -74,22 +74,22 @@ public: MCInstPrinter *InstPrinter, raw_ostream &ErrStream); ~RuntimeDyldChecker(); - // \brief Get the associated RTDyld instance. + // Get the associated RTDyld instance. RuntimeDyld& getRTDyld(); - // \brief Get the associated RTDyld instance. + // Get the associated RTDyld instance. const RuntimeDyld& getRTDyld() const; - /// \brief Check a single expression against the attached RuntimeDyld + /// Check a single expression against the attached RuntimeDyld /// instance. bool check(StringRef CheckExpr) const; - /// \brief Scan the given memory buffer for lines beginning with the string + /// Scan the given memory buffer for lines beginning with the string /// in RulePrefix. The remainder of the line is passed to the check /// method to be evaluated as an expression. bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const; - /// \brief Returns the address of the requested section (or an error message + /// Returns the address of the requested section (or an error message /// in the second element of the pair if the address cannot be found). /// /// if 'LocalAddress' is true, this returns the address of the section @@ -99,7 +99,7 @@ public: StringRef SectionName, bool LocalAddress); - /// \brief If there is a section at the given local address, return its load + /// If there is a section at the given local address, return its load /// address, otherwise return none. Optional getSectionLoadAddress(void *LocalAddress) const; diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h index d76e37113c66b1d6ca2e902acbdc912c217e465b..3cf131c27778e0bc23e914a85c135010222a405a 100644 --- a/include/llvm/ExecutionEngine/SectionMemoryManager.h +++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h @@ -111,7 +111,7 @@ public: void operator=(const SectionMemoryManager &) = delete; ~SectionMemoryManager() override; - /// \brief Allocates a memory block of (at least) the given size suitable for + /// Allocates a memory block of (at least) the given size suitable for /// executable code. /// /// The value of \p Alignment must be a power of two. If \p Alignment is zero @@ -120,7 +120,7 @@ public: unsigned SectionID, StringRef SectionName) override; - /// \brief Allocates a memory block of (at least) the given size suitable for + /// Allocates a memory block of (at least) the given size suitable for /// executable code. /// /// The value of \p Alignment must be a power of two. If \p Alignment is zero @@ -129,7 +129,7 @@ public: unsigned SectionID, StringRef SectionName, bool isReadOnly) override; - /// \brief Update section-specific memory permissions and other attributes. + /// Update section-specific memory permissions and other attributes. /// /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation @@ -142,7 +142,7 @@ public: /// \returns true if an error occurred, false otherwise. bool finalizeMemory(std::string *ErrMsg = nullptr) override; - /// \brief Invalidate instruction cache for code sections. + /// Invalidate instruction cache for code sections. /// /// Some platforms with separate data cache and instruction cache require /// explicit cache flush, otherwise JIT code manipulations (like resolved @@ -182,6 +182,8 @@ private: std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup, unsigned Permissions); + void anchor() override; + MemoryGroup CodeMem; MemoryGroup RWDataMem; MemoryGroup RODataMem; diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 660fc589ddb581b8001eac3d25cba2346ec20b0f..4f0667f1bdfe6d91e3336fe5a7854a1c832e9a75 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // /// \file -/// \brief This file contains the simple types necessary to represent the +/// This file contains the simple types necessary to represent the /// attributes associated with functions and their calls. // //===----------------------------------------------------------------------===// @@ -22,6 +22,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include #include @@ -43,7 +44,7 @@ class Type; //===----------------------------------------------------------------------===// /// \class -/// \brief Functions, function parameters, and return types can have attributes +/// Functions, function parameters, and return types can have attributes /// to indicate how they should be treated by optimizations and code /// generation. This class represents one of those attributes. It's light-weight /// and should be passed around by-value. @@ -70,7 +71,7 @@ public: // IR-Level Attributes None, ///< No attributes have been set #define GET_ATTR_ENUM - #include "llvm/IR/Attributes.gen" + #include "llvm/IR/Attributes.inc" EndAttrKinds ///< Sentinal value useful for loops }; @@ -86,12 +87,12 @@ public: // Attribute Construction //===--------------------------------------------------------------------===// - /// \brief Return a uniquified Attribute object. + /// Return a uniquified Attribute object. static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0); static Attribute get(LLVMContext &Context, StringRef Kind, StringRef Val = StringRef()); - /// \brief Return a uniquified Attribute object that has the specific + /// Return a uniquified Attribute object that has the specific /// alignment set. static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align); static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align); @@ -107,51 +108,51 @@ public: // Attribute Accessors //===--------------------------------------------------------------------===// - /// \brief Return true if the attribute is an Attribute::AttrKind type. + /// Return true if the attribute is an Attribute::AttrKind type. bool isEnumAttribute() const; - /// \brief Return true if the attribute is an integer attribute. + /// Return true if the attribute is an integer attribute. bool isIntAttribute() const; - /// \brief Return true if the attribute is a string (target-dependent) + /// Return true if the attribute is a string (target-dependent) /// attribute. bool isStringAttribute() const; - /// \brief Return true if the attribute is present. + /// Return true if the attribute is present. bool hasAttribute(AttrKind Val) const; - /// \brief Return true if the target-dependent attribute is present. + /// Return true if the target-dependent attribute is present. bool hasAttribute(StringRef Val) const; - /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). This + /// Return the attribute's kind as an enum (Attribute::AttrKind). This /// requires the attribute to be an enum or integer attribute. Attribute::AttrKind getKindAsEnum() const; - /// \brief Return the attribute's value as an integer. This requires that the + /// Return the attribute's value as an integer. This requires that the /// attribute be an integer attribute. uint64_t getValueAsInt() const; - /// \brief Return the attribute's kind as a string. This requires the + /// Return the attribute's kind as a string. This requires the /// attribute to be a string attribute. StringRef getKindAsString() const; - /// \brief Return the attribute's value as a string. This requires the + /// Return the attribute's value as a string. This requires the /// attribute to be a string attribute. StringRef getValueAsString() const; - /// \brief Returns the alignment field of an attribute as a byte alignment + /// Returns the alignment field of an attribute as a byte alignment /// value. unsigned getAlignment() const; - /// \brief Returns the stack alignment field of an attribute as a byte + /// Returns the stack alignment field of an attribute as a byte /// alignment value. unsigned getStackAlignment() const; - /// \brief Returns the number of dereferenceable bytes from the + /// Returns the number of dereferenceable bytes from the /// dereferenceable attribute. uint64_t getDereferenceableBytes() const; - /// \brief Returns the number of dereferenceable_or_null bytes from the + /// Returns the number of dereferenceable_or_null bytes from the /// dereferenceable_or_null attribute. uint64_t getDereferenceableOrNullBytes() const; @@ -159,27 +160,27 @@ public: /// if not known). std::pair> getAllocSizeArgs() const; - /// \brief The Attribute is converted to a string of equivalent mnemonic. This + /// The Attribute is converted to a string of equivalent mnemonic. This /// is, presumably, for writing out the mnemonics for the assembly writer. std::string getAsString(bool InAttrGrp = false) const; - /// \brief Equality and non-equality operators. + /// Equality and non-equality operators. bool operator==(Attribute A) const { return pImpl == A.pImpl; } bool operator!=(Attribute A) const { return pImpl != A.pImpl; } - /// \brief Less-than operator. Useful for sorting the attributes list. + /// Less-than operator. Useful for sorting the attributes list. bool operator<(Attribute A) const; void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(pImpl); } - /// \brief Return a raw pointer that uniquely identifies this attribute. + /// Return a raw pointer that uniquely identifies this attribute. void *getRawPointer() const { return pImpl; } - /// \brief Get an attribute from a raw pointer created by getRawPointer. + /// Get an attribute from a raw pointer created by getRawPointer. static Attribute fromRawPointer(void *RawPtr) { return Attribute(reinterpret_cast(RawPtr)); } @@ -289,7 +290,7 @@ public: //===----------------------------------------------------------------------===// /// \class -/// \brief Provide DenseMapInfo for AttributeSet. +/// Provide DenseMapInfo for AttributeSet. template <> struct DenseMapInfo { static AttributeSet getEmptyKey() { auto Val = static_cast(-1); @@ -313,7 +314,7 @@ template <> struct DenseMapInfo { //===----------------------------------------------------------------------===// /// \class -/// \brief This class holds the attributes for a function, its return value, and +/// This class holds the attributes for a function, its return value, and /// its parameters. You access the attributes for each of them via an index into /// the AttributeList object. The function attributes are at index /// `AttributeList::FunctionIndex', the return value is at index @@ -334,18 +335,18 @@ private: friend class AttributeSetNode; template friend struct DenseMapInfo; - /// \brief The attributes that we are managing. This can be null to represent + /// The attributes that we are managing. This can be null to represent /// the empty attributes list. AttributeListImpl *pImpl = nullptr; public: - /// \brief Create an AttributeList with the specified parameters in it. + /// Create an AttributeList with the specified parameters in it. static AttributeList get(LLVMContext &C, ArrayRef> Attrs); static AttributeList get(LLVMContext &C, ArrayRef> Attrs); - /// \brief Create an AttributeList from attribute sets for a function, its + /// Create an AttributeList from attribute sets for a function, its /// return value, and all of its arguments. static AttributeList get(LLVMContext &C, AttributeSet FnAttrs, AttributeSet RetAttrs, @@ -363,7 +364,7 @@ public: // AttributeList Construction and Mutation //===--------------------------------------------------------------------===// - /// \brief Return an AttributeList with the specified parameters in it. + /// Return an AttributeList with the specified parameters in it. static AttributeList get(LLVMContext &C, ArrayRef Attrs); static AttributeList get(LLVMContext &C, unsigned Index, ArrayRef Kinds); @@ -372,12 +373,12 @@ public: static AttributeList get(LLVMContext &C, unsigned Index, const AttrBuilder &B); - /// \brief Add an attribute to the attribute set at the given index. + /// Add an attribute to the attribute set at the given index. /// Returns a new list because attribute lists are immutable. AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const; - /// \brief Add an attribute to the attribute set at the given index. + /// Add an attribute to the attribute set at the given index. /// Returns a new list because attribute lists are immutable. AttributeList addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, StringRef Value = StringRef()) const; @@ -386,7 +387,7 @@ public: /// Returns a new list because attribute lists are immutable. AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute A) const; - /// \brief Add attributes to the attribute set at the given index. + /// Add attributes to the attribute set at the given index. /// Returns a new list because attribute lists are immutable. AttributeList addAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &B) const; @@ -418,47 +419,47 @@ public: return addAttributes(C, ArgNo + FirstArgIndex, B); } - /// \brief Remove the specified attribute at the specified index from this + /// Remove the specified attribute at the specified index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const; - /// \brief Remove the specified attribute at the specified index from this + /// Remove the specified attribute at the specified index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeAttribute(LLVMContext &C, unsigned Index, StringRef Kind) const; - /// \brief Remove the specified attributes at the specified index from this + /// Remove the specified attributes at the specified index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const; - /// \brief Remove all attributes at the specified index from this + /// Remove all attributes at the specified index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeAttributes(LLVMContext &C, unsigned Index) const; - /// \brief Remove the specified attribute at the specified arg index from this + /// Remove the specified attribute at the specified arg index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const { return removeAttribute(C, ArgNo + FirstArgIndex, Kind); } - /// \brief Remove the specified attribute at the specified arg index from this + /// Remove the specified attribute at the specified arg index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind) const { return removeAttribute(C, ArgNo + FirstArgIndex, Kind); } - /// \brief Remove the specified attribute at the specified arg index from this + /// Remove the specified attribute at the specified arg index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo, const AttrBuilder &AttrsToRemove) const { return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove); } - /// \brief Remove all attributes at the specified arg index from this + /// Remove all attributes at the specified arg index from this /// attribute list. Returns a new list because attribute lists are immutable. AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo) const { return removeAttributes(C, ArgNo + FirstArgIndex); @@ -476,12 +477,12 @@ public: return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes); } - /// \brief Add the dereferenceable_or_null attribute to the attribute set at + /// Add the dereferenceable_or_null attribute to the attribute set at /// the given index. Returns a new list because attribute lists are immutable. AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const; - /// \brief Add the dereferenceable_or_null attribute to the attribute set at + /// Add the dereferenceable_or_null attribute to the attribute set at /// the given arg index. Returns a new list because attribute lists are /// immutable. AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C, @@ -508,102 +509,102 @@ public: // AttributeList Accessors //===--------------------------------------------------------------------===// - /// \brief Retrieve the LLVM context. + /// Retrieve the LLVM context. LLVMContext &getContext() const; - /// \brief The attributes for the specified index are returned. + /// The attributes for the specified index are returned. AttributeSet getAttributes(unsigned Index) const; - /// \brief The attributes for the argument or parameter at the given index are + /// The attributes for the argument or parameter at the given index are /// returned. AttributeSet getParamAttributes(unsigned ArgNo) const; - /// \brief The attributes for the ret value are returned. + /// The attributes for the ret value are returned. AttributeSet getRetAttributes() const; - /// \brief The function attributes are returned. + /// The function attributes are returned. AttributeSet getFnAttributes() const; - /// \brief Return true if the attribute exists at the given index. + /// Return true if the attribute exists at the given index. bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const; - /// \brief Return true if the attribute exists at the given index. + /// Return true if the attribute exists at the given index. bool hasAttribute(unsigned Index, StringRef Kind) const; - /// \brief Return true if attribute exists at the given index. + /// Return true if attribute exists at the given index. bool hasAttributes(unsigned Index) const; - /// \brief Return true if the attribute exists for the given argument + /// Return true if the attribute exists for the given argument bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { return hasAttribute(ArgNo + FirstArgIndex, Kind); } - /// \brief Return true if the attribute exists for the given argument + /// Return true if the attribute exists for the given argument bool hasParamAttr(unsigned ArgNo, StringRef Kind) const { return hasAttribute(ArgNo + FirstArgIndex, Kind); } - /// \brief Return true if attributes exists for the given argument + /// Return true if attributes exists for the given argument bool hasParamAttrs(unsigned ArgNo) const { return hasAttributes(ArgNo + FirstArgIndex); } - /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but + /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but /// may be faster. bool hasFnAttribute(Attribute::AttrKind Kind) const; - /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but + /// Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but /// may be faster. bool hasFnAttribute(StringRef Kind) const; - /// \brief Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind). + /// Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind). bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const; - /// \brief Return true if the specified attribute is set for at least one + /// Return true if the specified attribute is set for at least one /// parameter or for the return value. If Index is not nullptr, the index /// of a parameter with the specified attribute is provided. bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index = nullptr) const; - /// \brief Return the attribute object that exists at the given index. + /// Return the attribute object that exists at the given index. Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const; - /// \brief Return the attribute object that exists at the given index. + /// Return the attribute object that exists at the given index. Attribute getAttribute(unsigned Index, StringRef Kind) const; - /// \brief Return the attribute object that exists at the arg index. + /// Return the attribute object that exists at the arg index. Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const { return getAttribute(ArgNo + FirstArgIndex, Kind); } - /// \brief Return the attribute object that exists at the given index. + /// Return the attribute object that exists at the given index. Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const { return getAttribute(ArgNo + FirstArgIndex, Kind); } - /// \brief Return the alignment of the return value. + /// Return the alignment of the return value. unsigned getRetAlignment() const; - /// \brief Return the alignment for the specified function parameter. + /// Return the alignment for the specified function parameter. unsigned getParamAlignment(unsigned ArgNo) const; - /// \brief Get the stack alignment. + /// Get the stack alignment. unsigned getStackAlignment(unsigned Index) const; - /// \brief Get the number of dereferenceable bytes (or zero if unknown). + /// Get the number of dereferenceable bytes (or zero if unknown). uint64_t getDereferenceableBytes(unsigned Index) const; - /// \brief Get the number of dereferenceable bytes (or zero if unknown) of an + /// Get the number of dereferenceable bytes (or zero if unknown) of an /// arg. uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { return getDereferenceableBytes(ArgNo + FirstArgIndex); } - /// \brief Get the number of dereferenceable_or_null bytes (or zero if + /// Get the number of dereferenceable_or_null bytes (or zero if /// unknown). uint64_t getDereferenceableOrNullBytes(unsigned Index) const; - /// \brief Get the number of dereferenceable_or_null bytes (or zero if + /// Get the number of dereferenceable_or_null bytes (or zero if /// unknown) of an arg. uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex); @@ -613,7 +614,7 @@ public: std::pair> getAllocSizeArgs(unsigned Index) const; - /// \brief Return the attributes at the index as a string. + /// Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; //===--------------------------------------------------------------------===// @@ -635,12 +636,12 @@ public: bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } - /// \brief Return a raw pointer that uniquely identifies this attribute list. + /// Return a raw pointer that uniquely identifies this attribute list. void *getRawPointer() const { return pImpl; } - /// \brief Return true if there are no attributes. + /// Return true if there are no attributes. bool isEmpty() const { return pImpl == nullptr; } void dump() const; @@ -648,7 +649,7 @@ public: //===----------------------------------------------------------------------===// /// \class -/// \brief Provide DenseMapInfo for AttributeList. +/// Provide DenseMapInfo for AttributeList. template <> struct DenseMapInfo { static AttributeList getEmptyKey() { auto Val = static_cast(-1); @@ -674,7 +675,7 @@ template <> struct DenseMapInfo { //===----------------------------------------------------------------------===// /// \class -/// \brief This class is used in conjunction with the Attribute::get method to +/// This class is used in conjunction with the Attribute::get method to /// create an Attribute object. The object itself is uniquified. The Builder's /// value, however, is not. So this can be used as a quick way to test for /// equality, presence of attributes, etc. @@ -699,65 +700,65 @@ public: void clear(); - /// \brief Add an attribute to the builder. + /// Add an attribute to the builder. AttrBuilder &addAttribute(Attribute::AttrKind Val); - /// \brief Add the Attribute object to the builder. + /// Add the Attribute object to the builder. AttrBuilder &addAttribute(Attribute A); - /// \brief Add the target-dependent attribute to the builder. + /// Add the target-dependent attribute to the builder. AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef()); - /// \brief Remove an attribute from the builder. + /// Remove an attribute from the builder. AttrBuilder &removeAttribute(Attribute::AttrKind Val); - /// \brief Remove the attributes from the builder. + /// Remove the attributes from the builder. AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex); - /// \brief Remove the target-dependent attribute to the builder. + /// Remove the target-dependent attribute to the builder. AttrBuilder &removeAttribute(StringRef A); - /// \brief Add the attributes from the builder. + /// Add the attributes from the builder. AttrBuilder &merge(const AttrBuilder &B); - /// \brief Remove the attributes from the builder. + /// Remove the attributes from the builder. AttrBuilder &remove(const AttrBuilder &B); - /// \brief Return true if the builder has any attribute that's in the + /// Return true if the builder has any attribute that's in the /// specified builder. bool overlaps(const AttrBuilder &B) const; - /// \brief Return true if the builder has the specified attribute. + /// Return true if the builder has the specified attribute. bool contains(Attribute::AttrKind A) const { assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!"); return Attrs[A]; } - /// \brief Return true if the builder has the specified target-dependent + /// Return true if the builder has the specified target-dependent /// attribute. bool contains(StringRef A) const; - /// \brief Return true if the builder has IR-level attributes. + /// Return true if the builder has IR-level attributes. bool hasAttributes() const; - /// \brief Return true if the builder has any attribute that's in the + /// Return true if the builder has any attribute that's in the /// specified attribute. bool hasAttributes(AttributeList A, uint64_t Index) const; - /// \brief Return true if the builder has an alignment attribute. + /// Return true if the builder has an alignment attribute. bool hasAlignmentAttr() const; - /// \brief Retrieve the alignment attribute, if it exists. + /// Retrieve the alignment attribute, if it exists. uint64_t getAlignment() const { return Alignment; } - /// \brief Retrieve the stack alignment attribute, if it exists. + /// Retrieve the stack alignment attribute, if it exists. uint64_t getStackAlignment() const { return StackAlignment; } - /// \brief Retrieve the number of dereferenceable bytes, if the + /// Retrieve the number of dereferenceable bytes, if the /// dereferenceable attribute exists (zero is returned otherwise). uint64_t getDereferenceableBytes() const { return DerefBytes; } - /// \brief Retrieve the number of dereferenceable_or_null bytes, if the + /// Retrieve the number of dereferenceable_or_null bytes, if the /// dereferenceable_or_null attribute exists (zero is returned otherwise). uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; } @@ -765,19 +766,19 @@ public: /// doesn't exist, pair(0, 0) is returned. std::pair> getAllocSizeArgs() const; - /// \brief This turns an int alignment (which must be a power of 2) into the + /// This turns an int alignment (which must be a power of 2) into the /// form used internally in Attribute. AttrBuilder &addAlignmentAttr(unsigned Align); - /// \brief This turns an int stack alignment (which must be a power of 2) into + /// This turns an int stack alignment (which must be a power of 2) into /// the form used internally in Attribute. AttrBuilder &addStackAlignmentAttr(unsigned Align); - /// \brief This turns the number of dereferenceable bytes into the form used + /// This turns the number of dereferenceable bytes into the form used /// internally in Attribute. AttrBuilder &addDereferenceableAttr(uint64_t Bytes); - /// \brief This turns the number of dereferenceable_or_null bytes into the + /// This turns the number of dereferenceable_or_null bytes into the /// form used internally in Attribute. AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes); @@ -789,7 +790,7 @@ public: /// Attribute.getIntValue(). AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); - /// \brief Return true if the builder contains no target-independent + /// Return true if the builder contains no target-independent /// attributes. bool empty() const { return Attrs.none(); } @@ -822,14 +823,14 @@ public: namespace AttributeFuncs { -/// \brief Which attributes cannot be applied to a type. +/// Which attributes cannot be applied to a type. AttrBuilder typeIncompatible(Type *Ty); /// \returns Return true if the two functions have compatible target-independent /// attributes for inlining purposes. bool areInlineCompatible(const Function &Caller, const Function &Callee); -/// \brief Merge caller's and callee's attributes. +/// Merge caller's and callee's attributes. void mergeAttributesForInlining(Function &Caller, const Function &Callee); } // end namespace AttributeFuncs diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td index 554f0df768aba7980c85b84f8b45ba6ec303da66..564ab0a3f3f44a8d78217a6b43bd7ff5d5a6c975 100644 --- a/include/llvm/IR/Attributes.td +++ b/include/llvm/IR/Attributes.td @@ -136,6 +136,9 @@ def ReturnsTwice : EnumAttr<"returns_twice">; /// Safe Stack protection. def SafeStack : EnumAttr<"safestack">; +/// Shadow Call Stack protection. +def ShadowCallStack : EnumAttr<"shadowcallstack">; + /// Sign extended before/after call. def SExt : EnumAttr<"signext">; @@ -211,6 +214,7 @@ def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; +def : CompatRule<"isEqual">; class MergeRule { // The name of the function called to merge the attributes of the caller and diff --git a/include/llvm/IR/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h index 3f406f0cf1969a6d33f2abae69312ae8d4a997b3..8cf574c6a1386575974ba049d41d50d86085ce92 100644 --- a/include/llvm/IR/AutoUpgrade.h +++ b/include/llvm/IR/AutoUpgrade.h @@ -37,6 +37,10 @@ namespace llvm { /// intrinsic function with a call to the specified new function. void UpgradeIntrinsicCall(CallInst *CI, Function *NewFn); + // This upgrades the comment for objc retain release markers in inline asm + // calls + void UpgradeInlineAsmString(std::string *AsmStr); + /// This is an auto-upgrade hook for any old intrinsic function syntaxes /// which need to have both the function updated as well as all calls updated /// to the new function. This should only be run in a post-processing fashion @@ -51,6 +55,10 @@ namespace llvm { /// module is modified. bool UpgradeModuleFlags(Module &M); + /// This checks for objc retain release marker which should be upgraded. It + /// returns true if module is modified. + bool UpgradeRetainReleaseMarker(Module &M); + void UpgradeSectionAttributes(Module &M); /// If the given TBAA tag uses the scalar TBAA format, create a new node diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 77cfc9776df0e5ea1e4255895522f9a685793800..c942ec83f668cd1f8f0d190e8dabb1900ae53e1e 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -41,7 +41,7 @@ class PHINode; class TerminatorInst; class ValueSymbolTable; -/// \brief LLVM Basic Block Representation +/// LLVM Basic Block Representation /// /// This represents a single basic block in LLVM. A basic block is simply a /// container of instructions that execute sequentially. Basic blocks are Values @@ -70,7 +70,7 @@ private: void setParent(Function *parent); - /// \brief Constructor. + /// Constructor. /// /// If the function parameter is specified, the basic block is automatically /// inserted at either the end of the function (if InsertBefore is null), or @@ -84,7 +84,7 @@ public: BasicBlock &operator=(const BasicBlock &) = delete; ~BasicBlock(); - /// \brief Get the context in which this basic block lives. + /// Get the context in which this basic block lives. LLVMContext &getContext() const; /// Instruction iterators... @@ -93,7 +93,7 @@ public: using reverse_iterator = InstListType::reverse_iterator; using const_reverse_iterator = InstListType::const_reverse_iterator; - /// \brief Creates a new BasicBlock. + /// Creates a new BasicBlock. /// /// If the Parent parameter is specified, the basic block is automatically /// inserted at either the end of the function (if InsertBefore is 0), or @@ -104,12 +104,12 @@ public: return new BasicBlock(Context, Name, Parent, InsertBefore); } - /// \brief Return the enclosing method, or null if none. + /// Return the enclosing method, or null if none. const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } - /// \brief Return the module owning the function this basic block belongs to, - /// or nullptr it the function does not have a module. + /// Return the module owning the function this basic block belongs to, or + /// nullptr if the function does not have a module. /// /// Note: this is undefined behavior if the block does not have a parent. const Module *getModule() const; @@ -118,34 +118,34 @@ public: static_cast(this)->getModule()); } - /// \brief Returns the terminator instruction if the block is well formed or - /// null if the block is not well formed. + /// Returns the terminator instruction if the block is well formed or null + /// if the block is not well formed. const TerminatorInst *getTerminator() const LLVM_READONLY; TerminatorInst *getTerminator() { return const_cast( static_cast(this)->getTerminator()); } - /// \brief Returns the call instruction calling @llvm.experimental.deoptimize - /// prior to the terminating return instruction of this basic block, if such a - /// call is present. Otherwise, returns null. + /// Returns the call instruction calling \@llvm.experimental.deoptimize + /// prior to the terminating return instruction of this basic block, if such + /// a call is present. Otherwise, returns null. const CallInst *getTerminatingDeoptimizeCall() const; CallInst *getTerminatingDeoptimizeCall() { return const_cast( static_cast(this)->getTerminatingDeoptimizeCall()); } - /// \brief Returns the call instruction marked 'musttail' prior to the - /// terminating return instruction of this basic block, if such a call is - /// present. Otherwise, returns null. + /// Returns the call instruction marked 'musttail' prior to the terminating + /// return instruction of this basic block, if such a call is present. + /// Otherwise, returns null. const CallInst *getTerminatingMustTailCall() const; CallInst *getTerminatingMustTailCall() { return const_cast( static_cast(this)->getTerminatingMustTailCall()); } - /// \brief Returns a pointer to the first instruction in this block that is - /// not a PHINode instruction. + /// Returns a pointer to the first instruction in this block that is not a + /// PHINode instruction. /// /// When adding instructions to the beginning of the basic block, they should /// be added before the returned value, not before the first instruction, @@ -156,23 +156,23 @@ public: static_cast(this)->getFirstNonPHI()); } - /// \brief Returns a pointer to the first instruction in this block that is not - /// a PHINode or a debug intrinsic. + /// Returns a pointer to the first instruction in this block that is not a + /// PHINode or a debug intrinsic. const Instruction* getFirstNonPHIOrDbg() const; Instruction* getFirstNonPHIOrDbg() { return const_cast( static_cast(this)->getFirstNonPHIOrDbg()); } - /// \brief Returns a pointer to the first instruction in this block that is not - /// a PHINode, a debug intrinsic, or a lifetime intrinsic. + /// Returns a pointer to the first instruction in this block that is not a + /// PHINode, a debug intrinsic, or a lifetime intrinsic. const Instruction* getFirstNonPHIOrDbgOrLifetime() const; Instruction* getFirstNonPHIOrDbgOrLifetime() { return const_cast( static_cast(this)->getFirstNonPHIOrDbgOrLifetime()); } - /// \brief Returns an iterator to the first instruction in this block that is + /// Returns an iterator to the first instruction in this block that is /// suitable for inserting a non-PHI instruction. /// /// In particular, it skips all PHIs and LandingPad instructions. @@ -182,23 +182,35 @@ public: ->getFirstInsertionPt().getNonConst(); } - /// \brief Unlink 'this' from the containing function, but do not delete it. + /// Return a const iterator range over the instructions in the block, skipping + /// any debug instructions. + iterator_range>> + instructionsWithoutDebug() const; + + /// Return an iterator range over the instructions in the block, skipping any + /// debug instructions. + iterator_range>> + instructionsWithoutDebug(); + + /// Unlink 'this' from the containing function, but do not delete it. void removeFromParent(); - /// \brief Unlink 'this' from the containing function and delete it. + /// Unlink 'this' from the containing function and delete it. /// // \returns an iterator pointing to the element after the erased one. SymbolTableList::iterator eraseFromParent(); - /// \brief Unlink this basic block from its current function and insert it - /// into the function that \p MovePos lives in, right before \p MovePos. + /// Unlink this basic block from its current function and insert it into + /// the function that \p MovePos lives in, right before \p MovePos. void moveBefore(BasicBlock *MovePos); - /// \brief Unlink this basic block from its current function and insert it + /// Unlink this basic block from its current function and insert it /// right after \p MovePos in the function \p MovePos lives in. void moveAfter(BasicBlock *MovePos); - /// \brief Insert unlinked basic block into a function. + /// Insert unlinked basic block into a function. /// /// Inserts an unlinked basic block into \c Parent. If \c InsertBefore is /// provided, inserts before that basic block, otherwise inserts at the end. @@ -206,7 +218,7 @@ public: /// \pre \a getParent() is \c nullptr. void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr); - /// \brief Return the predecessor of this block if it has a single predecessor + /// Return the predecessor of this block if it has a single predecessor /// block. Otherwise return a null pointer. const BasicBlock *getSinglePredecessor() const; BasicBlock *getSinglePredecessor() { @@ -214,7 +226,7 @@ public: static_cast(this)->getSinglePredecessor()); } - /// \brief Return the predecessor of this block if it has a unique predecessor + /// Return the predecessor of this block if it has a unique predecessor /// block. Otherwise return a null pointer. /// /// Note that unique predecessor doesn't mean single edge, there can be @@ -226,7 +238,7 @@ public: static_cast(this)->getUniquePredecessor()); } - /// \brief Return the successor of this block if it has a single successor. + /// Return the successor of this block if it has a single successor. /// Otherwise return a null pointer. /// /// This method is analogous to getSinglePredecessor above. @@ -236,7 +248,7 @@ public: static_cast(this)->getSingleSuccessor()); } - /// \brief Return the successor of this block if it has a unique successor. + /// Return the successor of this block if it has a unique successor. /// Otherwise return a null pointer. /// /// This method is analogous to getUniquePredecessor above. @@ -310,28 +322,28 @@ public: } iterator_range phis(); - /// \brief Return the underlying instruction list container. + /// Return the underlying instruction list container. /// /// Currently you need to access the underlying instruction list container /// directly if you want to modify it. const InstListType &getInstList() const { return InstList; } InstListType &getInstList() { return InstList; } - /// \brief Returns a pointer to a member of the instruction list. + /// Returns a pointer to a member of the instruction list. static InstListType BasicBlock::*getSublistAccess(Instruction*) { return &BasicBlock::InstList; } - /// \brief Returns a pointer to the symbol table if one exists. + /// Returns a pointer to the symbol table if one exists. ValueSymbolTable *getValueSymbolTable(); - /// \brief Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool classof(const Value *V) { return V->getValueID() == Value::BasicBlockVal; } - /// \brief Cause all subinstructions to "let go" of all the references that - /// said subinstructions are maintaining. + /// Cause all subinstructions to "let go" of all the references that said + /// subinstructions are maintaining. /// /// This allows one to 'delete' a whole class at a time, even though there may /// be circular references... first all references are dropped, and all use @@ -340,8 +352,8 @@ public: /// except operator delete. void dropAllReferences(); - /// \brief Notify the BasicBlock that the predecessor \p Pred is no longer - /// able to reach it. + /// Notify the BasicBlock that the predecessor \p Pred is no longer able to + /// reach it. /// /// This is actually not used to update the Predecessor list, but is actually /// used to update the PHI nodes that reside in the block. Note that this @@ -350,8 +362,7 @@ public: bool canSplitPredecessors() const; - /// \brief Split the basic block into two basic blocks at the specified - /// instruction. + /// Split the basic block into two basic blocks at the specified instruction. /// /// Note that all instructions BEFORE the specified iterator stay as part of /// the original basic block, an unconditional branch is added to the original @@ -371,37 +382,37 @@ public: return splitBasicBlock(I->getIterator(), BBName); } - /// \brief Returns true if there are any uses of this basic block other than + /// Returns true if there are any uses of this basic block other than /// direct branches, switches, etc. to it. bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; } - /// \brief Update all phi nodes in this basic block's successors to refer to - /// basic block \p New instead of to it. + /// Update all phi nodes in this basic block's successors to refer to basic + /// block \p New instead of to it. void replaceSuccessorsPhiUsesWith(BasicBlock *New); - /// \brief Return true if this basic block is an exception handling block. + /// Return true if this basic block is an exception handling block. bool isEHPad() const { return getFirstNonPHI()->isEHPad(); } - /// \brief Return true if this basic block is a landing pad. + /// Return true if this basic block is a landing pad. /// /// Being a ``landing pad'' means that the basic block is the destination of /// the 'unwind' edge of an invoke instruction. bool isLandingPad() const; - /// \brief Return the landingpad instruction associated with the landing pad. + /// Return the landingpad instruction associated with the landing pad. const LandingPadInst *getLandingPadInst() const; LandingPadInst *getLandingPadInst() { return const_cast( static_cast(this)->getLandingPadInst()); } - /// \brief Return true if it is legal to hoist instructions into this block. + /// Return true if it is legal to hoist instructions into this block. bool isLegalToHoistInto() const; Optional getIrrLoopHeaderWeight() const; private: - /// \brief Increment the internal refcount of the number of BlockAddresses + /// Increment the internal refcount of the number of BlockAddresses /// referencing this BasicBlock by \p Amt. /// /// This is almost always 0, sometimes one possibly, but almost never 2, and @@ -412,8 +423,8 @@ private: "Refcount wrap-around"); } - /// \brief Shadow Value::setValueSubclassData with a private forwarding method - /// so that any future subclasses cannot accidentally use it. + /// Shadow Value::setValueSubclassData with a private forwarding method so + /// that any future subclasses cannot accidentally use it. void setValueSubclassData(unsigned short D) { Value::setValueSubclassData(D); } diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index e259e42e1ce4c6348b449df2d939734fe74c98a5..f4988e7f1fecc6d3fe3a1496c380036422da1a9d 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -107,6 +107,9 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) { inline bool pred_empty(const BasicBlock *BB) { return pred_begin(BB) == pred_end(BB); } +inline unsigned pred_size(const BasicBlock *BB) { + return std::distance(pred_begin(BB), pred_end(BB)); +} inline pred_range predecessors(BasicBlock *BB) { return pred_range(pred_begin(BB), pred_end(BB)); } @@ -140,6 +143,9 @@ inline succ_const_iterator succ_end(const BasicBlock *BB) { inline bool succ_empty(const BasicBlock *BB) { return succ_begin(BB) == succ_end(BB); } +inline unsigned succ_size(const BasicBlock *BB) { + return std::distance(succ_begin(BB), succ_end(BB)); +} inline succ_range successors(BasicBlock *BB) { return succ_range(succ_begin(BB), succ_end(BB)); } diff --git a/include/llvm/IR/CMakeLists.txt b/include/llvm/IR/CMakeLists.txt index cf75d5800b74fb78fbcb0363a711da2c73e1f62f..7c4d3e83d261f38110c0a7e9c72c8d5800c8f299 100644 --- a/include/llvm/IR/CMakeLists.txt +++ b/include/llvm/IR/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Attributes.td) -tablegen(LLVM Attributes.gen -gen-attrs) +tablegen(LLVM Attributes.inc -gen-attrs) set(LLVM_TARGET_DEFINITIONS Intrinsics.td) -tablegen(LLVM Intrinsics.gen -gen-intrinsic) +tablegen(LLVM Intrinsics.inc -gen-intrinsic) add_public_tablegen_target(intrinsics_gen) diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 84fe836adc353ba54268d8a1e398940fa7b9593a..b9c02d7ed424b77e85a3abaa7c0999ba3d51bdfe 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -26,7 +26,7 @@ namespace CallingConv { /// A set of enums which specify the assigned numeric values for known llvm /// calling conventions. - /// @brief LLVM Calling Convention Representation + /// LLVM Calling Convention Representation enum { /// C - The default llvm calling convention, compatible with C. This /// convention is the only calling convention that supports varargs calls. @@ -139,11 +139,11 @@ namespace CallingConv { /// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins Intel_OCL_BI = 77, - /// \brief The C convention as specified in the x86-64 supplement to the + /// The C convention as specified in the x86-64 supplement to the /// System V ABI, used on most non-Windows systems. X86_64_SysV = 78, - /// \brief The C convention as implemented on Windows/x86-64 and + /// The C convention as implemented on Windows/x86-64 and /// AArch64. This convention differs from the more common /// \c X86_64_SysV convention in a number of ways, most notably in /// that XMM registers used to pass arguments are shadowed by GPRs, @@ -153,17 +153,17 @@ namespace CallingConv { /// registers to variadic functions. Win64 = 79, - /// \brief MSVC calling convention that passes vectors and vector aggregates + /// MSVC calling convention that passes vectors and vector aggregates /// in SSE registers. X86_VectorCall = 80, - /// \brief Calling convention used by HipHop Virtual Machine (HHVM) to + /// Calling convention used by HipHop Virtual Machine (HHVM) to /// perform calls to and from translation cache, and for calling PHP /// functions. /// HHVM calling convention supports tail/sibling call elimination. HHVM = 81, - /// \brief HHVM calling convention for invoking C/C++ helpers. + /// HHVM calling convention for invoking C/C++ helpers. HHVM_C = 82, /// X86_INTR - x86 hardware interrupt context. Callee may take one or two diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 6048160d8e637147bbb5368037e60758cea796e3..af5d5481e1fc4aa4d17bf1a71c4ee4d597109803 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -38,7 +38,7 @@ class APInt; /// structurally equivalent constants will always have the same address. /// Constants are created on demand as needed and never deleted: thus clients /// don't have to worry about the lifetime of the objects. -/// @brief LLVM Constant Representation +/// LLVM Constant Representation class Constant : public User { protected: Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) @@ -153,7 +153,7 @@ public: /// @returns the value for an integer or vector of integer constant of the /// given type that has all its bits set to true. - /// @brief Get the all ones value + /// Get the all ones value static Constant *getAllOnesValue(Type* Ty); /// Return the value for an integer or pointer constant, or a vector thereof, diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 6889e2658244d1cc0c39eabc2889c2e77d4154b4..1adda3269abca76b711dfbad212ae8d2183b3b67 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -54,7 +54,7 @@ public: /// Initialize a range to hold the single specified value. ConstantRange(APInt Value); - /// @brief Initialize a range of values explicitly. This will assert out if + /// Initialize a range of values explicitly. This will assert out if /// Lower==Upper and Lower != Min or Max value for its type. It will also /// assert out if the two APInt's are not the same bit width. ConstantRange(APInt Lower, APInt Upper); diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 1a7596d42767206c8bfaa0e957d6cd9f9972d4b0..d2e5f2acc2480f9c7b47ddec0eb03bb0ef84b954 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -80,7 +80,7 @@ public: //===----------------------------------------------------------------------===// /// This is the shared class of boolean and integer constants. This class /// represents both boolean and integral constants. -/// @brief Class for constant integers. +/// Class for constant integers. class ConstantInt final : public ConstantData { friend class Constant; @@ -107,7 +107,7 @@ public: /// to fit the type, unless isSigned is true, in which case the value will /// be interpreted as a 64-bit signed integer and sign-extended to fit /// the type. - /// @brief Get a ConstantInt for a specific value. + /// Get a ConstantInt for a specific value. static ConstantInt *get(IntegerType *Ty, uint64_t V, bool isSigned = false); @@ -115,7 +115,7 @@ public: /// value V will be canonicalized to a an unsigned APInt. Accessing it with /// either getSExtValue() or getZExtValue() will yield a correctly sized and /// signed value for the type Ty. - /// @brief Get a ConstantInt for a specific signed value. + /// Get a ConstantInt for a specific signed value. static ConstantInt *getSigned(IntegerType *Ty, int64_t V); static Constant *getSigned(Type *Ty, int64_t V); @@ -134,7 +134,7 @@ public: /// Return the constant as an APInt value reference. This allows clients to /// obtain a full-precision copy of the value. - /// @brief Return the constant's value. + /// Return the constant's value. inline const APInt &getValue() const { return Val; } @@ -145,7 +145,7 @@ public: /// Return the constant as a 64-bit unsigned integer value after it /// has been zero extended as appropriate for the type of this constant. Note /// that this method can assert if the value does not fit in 64 bits. - /// @brief Return the zero extended value. + /// Return the zero extended value. inline uint64_t getZExtValue() const { return Val.getZExtValue(); } @@ -153,7 +153,7 @@ public: /// Return the constant as a 64-bit integer value after it has been sign /// extended as appropriate for the type of this constant. Note that /// this method can assert if the value does not fit in 64 bits. - /// @brief Return the sign extended value. + /// Return the sign extended value. inline int64_t getSExtValue() const { return Val.getSExtValue(); } @@ -161,7 +161,7 @@ public: /// A helper method that can be used to determine if the constant contained /// within is equal to a constant. This only works for very small values, /// because this is all that can be represented with all types. - /// @brief Determine if this constant's value is same as an unsigned char. + /// Determine if this constant's value is same as an unsigned char. bool equalsInt(uint64_t V) const { return Val == V; } @@ -181,7 +181,7 @@ public: /// the signed version avoids callers having to convert a signed quantity /// to the appropriate unsigned type before calling the method. /// @returns true if V is a valid value for type Ty - /// @brief Determine if the value is in range for the given type. + /// Determine if the value is in range for the given type. static bool isValueValidForType(Type *Ty, uint64_t V); static bool isValueValidForType(Type *Ty, int64_t V); @@ -197,7 +197,7 @@ public: /// This is just a convenience method to make client code smaller for a /// common case. It also correctly performs the comparison without the /// potential for an assertion from getZExtValue(). - /// @brief Determine if the value is one. + /// Determine if the value is one. bool isOne() const { return Val.isOneValue(); } @@ -205,7 +205,7 @@ public: /// This function will return true iff every bit in this constant is set /// to true. /// @returns true iff this constant's bits are all set to true. - /// @brief Determine if the value is all ones. + /// Determine if the value is all ones. bool isMinusOne() const { return Val.isAllOnesValue(); } @@ -214,7 +214,7 @@ public: /// value that may be represented by the constant's type. /// @returns true iff this is the largest value that may be represented /// by this type. - /// @brief Determine if the value is maximal. + /// Determine if the value is maximal. bool isMaxValue(bool isSigned) const { if (isSigned) return Val.isMaxSignedValue(); @@ -226,7 +226,7 @@ public: /// value that may be represented by this constant's type. /// @returns true if this is the smallest value that may be represented by /// this type. - /// @brief Determine if the value is minimal. + /// Determine if the value is minimal. bool isMinValue(bool isSigned) const { if (isSigned) return Val.isMinSignedValue(); @@ -238,7 +238,7 @@ public: /// active bits bigger than 64 bits or a value greater than the given uint64_t /// value. /// @returns true iff this constant is greater or equal to the given number. - /// @brief Determine if the value is greater or equal to the given number. + /// Determine if the value is greater or equal to the given number. bool uge(uint64_t Num) const { return Val.uge(Num); } @@ -247,12 +247,12 @@ public: /// return it, otherwise return the limit value. This causes the value /// to saturate to the limit. /// @returns the min of the value of the constant and the specified value - /// @brief Get the constant's value with a saturation limit + /// Get the constant's value with a saturation limit uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const { return Val.getLimitedValue(Limit); } - /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. + /// Methods to support type inquiry through isa, cast, and dyn_cast. static bool classof(const Value *V) { return V->getValueID() == ConstantIntVal; } @@ -815,7 +815,7 @@ public: /// Return the ConstantTokenNone. static ConstantTokenNone *get(LLVMContext &Context); - /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. + /// Methods to support type inquiry through isa, cast, and dyn_cast. static bool classof(const Value *V) { return V->getValueID() == ConstantTokenNoneVal; } @@ -1022,7 +1022,7 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); - /// \brief Convenience function for getting a Cast operation. + /// Convenience function for getting a Cast operation. /// /// \param ops The opcode for the conversion /// \param C The constant to be converted @@ -1031,62 +1031,62 @@ public: static Constant *getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced = false); - // @brief Create a ZExt or BitCast cast constant expression + // Create a ZExt or BitCast cast constant expression static Constant *getZExtOrBitCast( Constant *C, ///< The constant to zext or bitcast Type *Ty ///< The type to zext or bitcast C to ); - // @brief Create a SExt or BitCast cast constant expression + // Create a SExt or BitCast cast constant expression static Constant *getSExtOrBitCast( Constant *C, ///< The constant to sext or bitcast Type *Ty ///< The type to sext or bitcast C to ); - // @brief Create a Trunc or BitCast cast constant expression + // Create a Trunc or BitCast cast constant expression static Constant *getTruncOrBitCast( Constant *C, ///< The constant to trunc or bitcast Type *Ty ///< The type to trunc or bitcast C to ); - /// @brief Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant + /// Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant /// expression. static Constant *getPointerCast( Constant *C, ///< The pointer value to be casted (operand 0) Type *Ty ///< The type to which cast should be made ); - /// @brief Create a BitCast or AddrSpaceCast for a pointer type depending on + /// Create a BitCast or AddrSpaceCast for a pointer type depending on /// the address space. static Constant *getPointerBitCastOrAddrSpaceCast( Constant *C, ///< The constant to addrspacecast or bitcast Type *Ty ///< The type to bitcast or addrspacecast C to ); - /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts + /// Create a ZExt, Bitcast or Trunc for integer -> integer casts static Constant *getIntegerCast( Constant *C, ///< The integer constant to be casted Type *Ty, ///< The integer type to cast to bool isSigned ///< Whether C should be treated as signed or not ); - /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts + /// Create a FPExt, Bitcast or FPTrunc for fp -> fp casts static Constant *getFPCast( Constant *C, ///< The integer constant to be casted Type *Ty ///< The integer type to cast to ); - /// @brief Return true if this is a convert constant expression + /// Return true if this is a convert constant expression bool isCast() const; - /// @brief Return true if this is a compare constant expression + /// Return true if this is a compare constant expression bool isCompare() const; - /// @brief Return true if this is an insertvalue or extractvalue expression, + /// Return true if this is an insertvalue or extractvalue expression, /// and the getIndices() method may be used. bool hasIndices() const; - /// @brief Return true if this is a getelementptr expression and all + /// Return true if this is a getelementptr expression and all /// the index operands are compile-time known integers within the /// corresponding notional static array extents. Note that this is /// not equivalant to, a subset of, or a superset of the "inbounds" @@ -1106,7 +1106,7 @@ public: static Constant *get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags = 0, Type *OnlyIfReducedTy = nullptr); - /// \brief Return an ICmp or FCmp comparison operator constant expression. + /// Return an ICmp or FCmp comparison operator constant expression. /// /// \param OnlyIfReduced see \a getWithOperands() docs. static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2, diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index aa8a8ec19ac09b5e1c57914e47c8454edb4d4c59..06c9421ec1d61bb2548a0ff1a2439441b60fb4c8 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -46,6 +46,7 @@ namespace llvm { DICompileUnit *CUNode; ///< The one compile unit created by this DIBuiler. Function *DeclareFn; ///< llvm.dbg.declare Function *ValueFn; ///< llvm.dbg.value + Function *LabelFn; ///< llvm.dbg.label SmallVector AllEnumTypes; /// Track the RetainTypes, since they can be updated later on. @@ -69,6 +70,9 @@ namespace llvm { /// copy. DenseMap> PreservedVariables; + /// Each subprogram's preserved labels. + DenseMap> PreservedLabels; + /// Create a temporary. /// /// Create an \a temporary node and track it in \a UnresolvedNodes. @@ -79,6 +83,10 @@ namespace llvm { DIExpression *Expr, const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore); + /// Internal helper for insertLabel. + Instruction *insertLabel(DILabel *LabelInfo, const DILocation *DL, + BasicBlock *InsertBB, Instruction *InsertBefore); + /// Internal helper for insertDbgValueIntrinsic. Instruction * insertDbgValueIntrinsic(llvm::Value *Val, DILocalVariable *VarInfo, @@ -237,10 +245,11 @@ namespace llvm { /// \param Ty Original type. /// \param BaseTy Base type. Ty is inherits from base. /// \param BaseOffset Base offset. + /// \param VBPtrOffset Virtual base pointer offset. /// \param Flags Flags to describe inheritance attribute, /// e.g. private DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy, - uint64_t BaseOffset, + uint64_t BaseOffset, uint32_t VBPtrOffset, DINode::DIFlags Flags); /// Create debugging information entry for a member. @@ -506,12 +515,15 @@ namespace llvm { DINode::DIFlags Flags = DINode::FlagZero, unsigned CC = 0); - /// Create a new DIType* with "artificial" flag set. - DIType *createArtificialType(DIType *Ty); + /// Create a distinct clone of \p SP with FlagArtificial set. + static DISubprogram *createArtificialSubprogram(DISubprogram *SP); - /// Create a new DIType* with the "object pointer" - /// flag set. - DIType *createObjectPointerType(DIType *Ty); + /// Create a uniqued clone of \p Ty with FlagArtificial set. + static DIType *createArtificialType(DIType *Ty); + + /// Create a uniqued clone of \p Ty with FlagObjectPointer and + /// FlagArtificial set. + static DIType *createObjectPointerType(DIType *Ty); /// Create a permanent forward-declared type. DICompositeType *createForwardDecl(unsigned Tag, StringRef Name, @@ -591,6 +603,14 @@ namespace llvm { DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0); + /// Create a new descriptor for an label. + /// + /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually + /// leads to a \a DISubprogram. + DILabel * + createLabel(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, + bool AlwaysPreserve = false); + /// Create a new descriptor for a parameter variable. /// /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually @@ -782,6 +802,20 @@ namespace llvm { DIExpression *Expr, const DILocation *DL, Instruction *InsertBefore); + /// Insert a new llvm.dbg.label intrinsic call. + /// \param LabelInfo Label's debug info descriptor. + /// \param DL Debug info location. + /// \param InsertBefore Location for the new intrinsic. + Instruction *insertLabel(DILabel *LabelInfo, const DILocation *DL, + Instruction *InsertBefore); + + /// Insert a new llvm.dbg.label intrinsic call. + /// \param LabelInfo Label's debug info descriptor. + /// \param DL Debug info location. + /// \param InsertAtEnd Location for the new intrinsic. + Instruction *insertLabel(DILabel *LabelInfo, const DILocation *DL, + BasicBlock *InsertAtEnd); + /// Insert a new llvm.dbg.value intrinsic call. /// \param Val llvm::Value of the variable /// \param VarInfo Variable's debug info descriptor. diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index c48e140f3a6112fdd2e268d814e2ffa6a6076ac2..d796a65e61293631fa0d468f76ef823a0d4096bc 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -61,7 +61,7 @@ enum AlignTypeEnum { // sunk down to an FTTI element that is queried rather than a global // preference. -/// \brief Layout alignment element. +/// Layout alignment element. /// /// Stores the alignment data associated with a given alignment type (integer, /// vector, float) and type bit width. @@ -69,7 +69,7 @@ enum AlignTypeEnum { /// \note The unusual order of elements in the structure attempts to reduce /// padding and make the structure slightly more cache friendly. struct LayoutAlignElem { - /// \brief Alignment type from \c AlignTypeEnum + /// Alignment type from \c AlignTypeEnum unsigned AlignType : 8; unsigned TypeBitWidth : 24; unsigned ABIAlign : 16; @@ -81,7 +81,7 @@ struct LayoutAlignElem { bool operator==(const LayoutAlignElem &rhs) const; }; -/// \brief Layout pointer alignment element. +/// Layout pointer alignment element. /// /// Stores the alignment data associated with a given pointer and address space. /// @@ -102,7 +102,7 @@ struct PointerAlignElem { bool operator==(const PointerAlignElem &rhs) const; }; -/// \brief A parsed version of the target data layout string in and methods for +/// A parsed version of the target data layout string in and methods for /// querying it. /// /// The target data layout string is specified *by the target* - a frontend @@ -129,7 +129,7 @@ private: SmallVector LegalIntWidths; - /// \brief Primitive type alignment data. This is sorted by type and bit + /// Primitive type alignment data. This is sorted by type and bit /// width during construction. using AlignmentsTy = SmallVector; AlignmentsTy Alignments; @@ -143,7 +143,7 @@ private: AlignmentsTy::iterator findAlignmentLowerBound(AlignTypeEnum AlignType, uint32_t BitWidth); - /// \brief The string representation used to create this DataLayout + /// The string representation used to create this DataLayout std::string StringRepresentation; using PointersTy = SmallVector; @@ -221,7 +221,7 @@ public: bool isLittleEndian() const { return !BigEndian; } bool isBigEndian() const { return BigEndian; } - /// \brief Returns the string representation of the DataLayout. + /// Returns the string representation of the DataLayout. /// /// This representation is in the same format accepted by the string /// constructor above. This should not be used to compare two DataLayout as @@ -230,10 +230,10 @@ public: return StringRepresentation; } - /// \brief Test if the DataLayout was constructed from an empty string. + /// Test if the DataLayout was constructed from an empty string. bool isDefault() const { return StringRepresentation.empty(); } - /// \brief Returns true if the specified type is known to be a native integer + /// Returns true if the specified type is known to be a native integer /// type supported by the CPU. /// /// For example, i64 is not native on most 32-bit CPUs and i37 is not native @@ -309,7 +309,7 @@ public: static const char *getManglingComponent(const Triple &T); - /// \brief Returns true if the specified type fits in a native integer type + /// Returns true if the specified type fits in a native integer type /// supported by the CPU. /// /// For example, if the CPU only supports i32 as a native integer type, then @@ -398,13 +398,13 @@ public: /// [*] The alloc size depends on the alignment, and thus on the target. /// These values are for x86-32 linux. - /// \brief Returns the number of bits necessary to hold the specified type. + /// Returns the number of bits necessary to hold the specified type. /// /// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must /// have a size (Type::isSized() must return true). uint64_t getTypeSizeInBits(Type *Ty) const; - /// \brief Returns the maximum number of bytes that may be overwritten by + /// Returns the maximum number of bytes that may be overwritten by /// storing the specified type. /// /// For example, returns 5 for i36 and 10 for x86_fp80. @@ -412,7 +412,7 @@ public: return (getTypeSizeInBits(Ty) + 7) / 8; } - /// \brief Returns the maximum number of bits that may be overwritten by + /// Returns the maximum number of bits that may be overwritten by /// storing the specified type; always a multiple of 8. /// /// For example, returns 40 for i36 and 80 for x86_fp80. @@ -420,7 +420,7 @@ public: return 8 * getTypeStoreSize(Ty); } - /// \brief Returns the offset in bytes between successive objects of the + /// Returns the offset in bytes between successive objects of the /// specified type, including alignment padding. /// /// This is the amount that alloca reserves for this type. For example, @@ -430,7 +430,7 @@ public: return alignTo(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); } - /// \brief Returns the offset in bits between successive objects of the + /// Returns the offset in bits between successive objects of the /// specified type, including alignment padding; always a multiple of 8. /// /// This is the amount that alloca reserves for this type. For example, @@ -439,69 +439,69 @@ public: return 8 * getTypeAllocSize(Ty); } - /// \brief Returns the minimum ABI-required alignment for the specified type. + /// Returns the minimum ABI-required alignment for the specified type. unsigned getABITypeAlignment(Type *Ty) const; - /// \brief Returns the minimum ABI-required alignment for an integer type of + /// Returns the minimum ABI-required alignment for an integer type of /// the specified bitwidth. unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const; - /// \brief Returns the preferred stack/global alignment for the specified + /// Returns the preferred stack/global alignment for the specified /// type. /// /// This is always at least as good as the ABI alignment. unsigned getPrefTypeAlignment(Type *Ty) const; - /// \brief Returns the preferred alignment for the specified type, returned as + /// Returns the preferred alignment for the specified type, returned as /// log2 of the value (a shift amount). unsigned getPreferredTypeAlignmentShift(Type *Ty) const; - /// \brief Returns an integer type with size at least as big as that of a + /// Returns an integer type with size at least as big as that of a /// pointer in the given address space. IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const; - /// \brief Returns an integer (vector of integer) type with size at least as + /// Returns an integer (vector of integer) type with size at least as /// big as that of a pointer of the given pointer (vector of pointer) type. Type *getIntPtrType(Type *) const; - /// \brief Returns the smallest integer type with size at least as big as + /// Returns the smallest integer type with size at least as big as /// Width bits. Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; - /// \brief Returns the largest legal integer type, or null if none are set. + /// Returns the largest legal integer type, or null if none are set. Type *getLargestLegalIntType(LLVMContext &C) const { unsigned LargestSize = getLargestLegalIntTypeSizeInBits(); return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize); } - /// \brief Returns the size of largest legal integer type size, or 0 if none + /// Returns the size of largest legal integer type size, or 0 if none /// are set. unsigned getLargestLegalIntTypeSizeInBits() const; - /// \brief Returns the type of a GEP index. + /// Returns the type of a GEP index. /// If it was not specified explicitly, it will be the integer type of the /// pointer width - IntPtrType. Type *getIndexType(Type *PtrTy) const; - /// \brief Returns the offset from the beginning of the type for the specified + /// Returns the offset from the beginning of the type for the specified /// indices. /// /// Note that this takes the element type, not the pointer type. /// This is used to implement getelementptr. int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef Indices) const; - /// \brief Returns a StructLayout object, indicating the alignment of the + /// Returns a StructLayout object, indicating the alignment of the /// struct, its size, and the offsets of its fields. /// /// Note that this information is lazily cached. const StructLayout *getStructLayout(StructType *Ty) const; - /// \brief Returns the preferred alignment of the specified global. + /// Returns the preferred alignment of the specified global. /// /// This includes an explicitly requested alignment (if the global has one). unsigned getPreferredAlignment(const GlobalVariable *GV) const; - /// \brief Returns the preferred alignment of the specified global, returned + /// Returns the preferred alignment of the specified global, returned /// in log form. /// /// This includes an explicitly requested alignment (if the global has one). @@ -536,7 +536,7 @@ public: /// NB: Padding in nested element is not taken into account. bool hasPadding() const { return IsPadded; } - /// \brief Given a valid byte offset into the structure, returns the structure + /// Given a valid byte offset into the structure, returns the structure /// index that contains it. unsigned getElementContainingOffset(uint64_t Offset) const; diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 1d8e7e2855fd1b7a4302c10e454e41967714cb4c..01178af3c9ff58f0861772ef8f15c2abfa7e292b 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -28,10 +28,10 @@ class DbgDeclareInst; class DbgValueInst; class Module; -/// \brief Find subprogram that is enclosing this scope. +/// Find subprogram that is enclosing this scope. DISubprogram *getDISubprogram(const MDNode *Scope); -/// \brief Strip debug info in the module if it exists. +/// Strip debug info in the module if it exists. /// /// To do this, we remove all calls to the debugger intrinsics and any named /// metadata for debugging. We also remove debug locations for instructions. @@ -51,10 +51,10 @@ bool stripDebugInfo(Function &F); /// All debug type metadata nodes are unreachable and garbage collected. bool stripNonLineTableDebugInfo(Module &M); -/// \brief Return Debug Info Metadata Version by checking module flags. +/// Return Debug Info Metadata Version by checking module flags. unsigned getDebugMetadataVersionFromModule(const Module &M); -/// \brief Utility to find all debug info in a module. +/// Utility to find all debug info in a module. /// /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To /// list debug info MDNodes used by an instruction, DebugInfoFinder uses @@ -64,30 +64,33 @@ unsigned getDebugMetadataVersionFromModule(const Module &M); /// used by the CUs. class DebugInfoFinder { public: - /// \brief Process entire module and collect debug info anchors. + /// Process entire module and collect debug info anchors. void processModule(const Module &M); + /// Process a single instruction and collect debug info anchors. + void processInstruction(const Module &M, const Instruction &I); - /// \brief Process DbgDeclareInst. + /// Process DbgDeclareInst. void processDeclare(const Module &M, const DbgDeclareInst *DDI); - /// \brief Process DbgValueInst. + /// Process DbgValueInst. void processValue(const Module &M, const DbgValueInst *DVI); - /// \brief Process debug info location. + /// Process debug info location. void processLocation(const Module &M, const DILocation *Loc); - /// \brief Clear all lists. + /// Clear all lists. void reset(); private: void InitializeTypeMap(const Module &M); - void processType(DIType *DT); - void processSubprogram(DISubprogram *SP); + void processCompileUnit(DICompileUnit *CU); void processScope(DIScope *Scope); + void processSubprogram(DISubprogram *SP); + void processType(DIType *DT); bool addCompileUnit(DICompileUnit *CU); bool addGlobalVariable(DIGlobalVariableExpression *DIG); + bool addScope(DIScope *Scope); bool addSubprogram(DISubprogram *SP); bool addType(DIType *DT); - bool addScope(DIScope *Scope); public: using compile_unit_iterator = diff --git a/include/llvm/IR/DebugInfoFlags.def b/include/llvm/IR/DebugInfoFlags.def index 676b97833879116f317d11a5ee04c13306bde7fa..e3707d487544dd9287099a1a77193767ed27308b 100644 --- a/include/llvm/IR/DebugInfoFlags.def +++ b/include/llvm/IR/DebugInfoFlags.def @@ -46,6 +46,7 @@ HANDLE_DI_FLAG((1 << 21), MainSubprogram) HANDLE_DI_FLAG((1 << 22), TypePassByValue) HANDLE_DI_FLAG((1 << 23), TypePassByReference) HANDLE_DI_FLAG((1 << 24), FixedEnum) +HANDLE_DI_FLAG((1 << 25), Thunk) // To avoid needing a dedicated value for IndirectVirtualBase, we use // the bitwise or of Virtual and FwdDecl, which does not otherwise @@ -55,7 +56,7 @@ HANDLE_DI_FLAG((1 << 2) | (1 << 5), IndirectVirtualBase) #ifdef DI_FLAG_LARGEST_NEEDED // intended to be used with ADT/BitmaskEnum.h // NOTE: always must be equal to largest flag, check this when adding new flag -HANDLE_DI_FLAG((1 << 24), Largest) +HANDLE_DI_FLAG((1 << 25), Largest) #undef DI_FLAG_LARGEST_NEEDED #endif diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index e2210bbcda0752be9ec7b5e597fb17769adb2104..1e3aebb5edec965d18adf6acda597f49fb03ff44 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -232,6 +232,7 @@ public: case DITemplateValueParameterKind: case DIGlobalVariableKind: case DILocalVariableKind: + case DILabelKind: case DIObjCPropertyKind: case DIImportedEntityKind: case DIModuleKind: @@ -678,9 +679,11 @@ public: Metadata *getRawScope() const { return getOperand(1); } MDString *getRawName() const { return getOperandAs(2); } - void setFlags(DIFlags NewFlags) { - assert(!isUniqued() && "Cannot set flags on uniqued nodes"); - Flags = NewFlags; + /// Returns a new temporary DIType with updated Flags + TempDIType cloneWithFlags(DIFlags NewFlags) const { + auto NewTy = clone(); + NewTy->Flags = NewFlags; + return NewTy; } bool isPrivate() const { @@ -790,7 +793,7 @@ class DIDerivedType : public DIType { friend class LLVMContextImpl; friend class MDNode; - /// \brief The DWARF address space of the memory pointed to or referenced by a + /// The DWARF address space of the memory pointed to or referenced by a /// pointer or reference type respectively. Optional DWARFAddressSpace; @@ -865,7 +868,8 @@ public: /// Get extra data associated with this derived type. /// /// Class type for pointer-to-members, objective-c property node for ivars, - /// or global constant wrapper for static members. + /// global constant wrapper for static members, or virtual base pointer offset + /// for inheritance. /// /// TODO: Separate out types that need this extra operand: pointer-to-member /// types and member fields (static members and ivars). @@ -883,6 +887,14 @@ public: return dyn_cast_or_null(getExtraData()); } + uint32_t getVBPtrOffset() const { + assert(getTag() == dwarf::DW_TAG_inheritance); + if (auto *CM = cast_or_null(getExtraData())) + if (auto *CI = dyn_cast_or_null(CM->getValue())) + return static_cast(CI->getZExtValue()); + return 0; + } + Constant *getStorageOffsetInBits() const { assert(getTag() == dwarf::DW_TAG_member && isBitField()); if (auto *C = cast_or_null(getExtraData())) @@ -1497,26 +1509,25 @@ public: /// discriminator. inline const DILocation *cloneWithDuplicationFactor(unsigned DF) const; + enum { NoGeneratedLocation = false, WithGeneratedLocation = true }; + /// When two instructions are combined into a single instruction we also /// need to combine the original locations into a single location. /// /// When the locations are the same we can use either location. When they - /// differ, we need a third location which is distinct from either. If - /// they have the same file/line but have a different discriminator we - /// could create a location with a new discriminator. If they are from - /// different files/lines the location is ambiguous and can't be - /// represented in a single line entry. In this case, no location - /// should be set, unless the merged instruction is a call, which we will - /// set the merged debug location as line 0 of the nearest common scope - /// where 2 locations are inlined from. This only applies to Instruction; - /// for MachineInstruction, as it is post-inline, we will treat the call - /// instruction the same way as other instructions. + /// differ, we need a third location which is distinct from either. If they + /// have the same file/line but have a different discriminator we could + /// create a location with a new discriminator. If they are from different + /// files/lines the location is ambiguous and can't be represented in a line + /// entry. In this case, if \p GenerateLocation is true, we will set the + /// merged debug location as line 0 of the nearest common scope where the two + /// locations are inlined from. /// - /// \p ForInst: The Instruction the merged DILocation is for. If the - /// Instruction is unavailable or non-existent, use nullptr. + /// \p GenerateLocation: Whether the merged location can be generated when + /// \p LocA and \p LocB differ. static const DILocation * getMergedLocation(const DILocation *LocA, const DILocation *LocB, - const Instruction *ForInst = nullptr); + bool GenerateLocation = NoGeneratedLocation); /// Returns the base discriminator for a given encoded discriminator \p D. static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) { @@ -1610,13 +1621,13 @@ class DISubprogram : public DILocalScope { unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, - DILocalVariableArray Variables, DITypeArray ThrownTypes, + DINodeArray RetainedNodes, DITypeArray ThrownTypes, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams.get(), Declaration, Variables.get(), + Unit, TemplateParams.get(), Declaration, RetainedNodes.get(), ThrownTypes.get(), Storage, ShouldCreate); } static DISubprogram * @@ -1625,7 +1636,7 @@ class DISubprogram : public DILocalScope { bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, - Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, + Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { @@ -1634,7 +1645,7 @@ class DISubprogram : public DILocalScope { isDefinition(), getScopeLine(), getContainingType(), getVirtuality(), getVirtualIndex(), getThisAdjustment(), getFlags(), isOptimized(), getUnit(), - getTemplateParams(), getDeclaration(), getVariables(), + getTemplateParams(), getDeclaration(), getRetainedNodes(), getThrownTypes()); } @@ -1648,12 +1659,12 @@ public: bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, - DILocalVariableArray Variables = nullptr, + DINodeArray RetainedNodes = nullptr, DITypeArray ThrownTypes = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, Variables, ThrownTypes)) + TemplateParams, Declaration, RetainedNodes, ThrownTypes)) DEFINE_MDNODE_GET( DISubprogram, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, @@ -1661,15 +1672,22 @@ public: unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr, - Metadata *Declaration = nullptr, Metadata *Variables = nullptr, + Metadata *Declaration = nullptr, Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, - Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables, + Flags, IsOptimized, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)) TempDISubprogram clone() const { return cloneImpl(); } + /// Returns a new temporary DISubprogram with updated Flags + TempDISubprogram cloneWithFlags(DIFlags NewFlags) const { + auto NewSP = clone(); + NewSP->Flags = NewFlags; + return NewSP; + } + public: unsigned getLine() const { return Line; } unsigned getVirtuality() const { return Virtuality; } @@ -1712,6 +1730,11 @@ public: /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn bool isNoReturn() const { return getFlags() & FlagNoReturn; } + // Check if this routine is a compiler-generated thunk. + // + // Returns true if this subprogram is a thunk generated by the compiler. + bool isThunk() const { return getFlags() & FlagThunk; } + DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } StringRef getName() const { return getStringOperand(2); } @@ -1734,8 +1757,8 @@ public: DISubprogram *getDeclaration() const { return cast_or_null(getRawDeclaration()); } - DILocalVariableArray getVariables() const { - return cast_or_null(getRawVariables()); + DINodeArray getRetainedNodes() const { + return cast_or_null(getRawRetainedNodes()); } DITypeArray getThrownTypes() const { return cast_or_null(getRawThrownTypes()); @@ -1747,7 +1770,7 @@ public: Metadata *getRawType() const { return getOperand(4); } Metadata *getRawUnit() const { return getOperand(5); } Metadata *getRawDeclaration() const { return getOperand(6); } - Metadata *getRawVariables() const { return getOperand(7); } + Metadata *getRawRetainedNodes() const { return getOperand(7); } Metadata *getRawContainingType() const { return getNumOperands() > 8 ? getOperandAs(8) : nullptr; } @@ -2398,9 +2421,9 @@ public: /// Prepend \p DIExpr with the given opcodes and optionally turn it into a /// stack value. - static DIExpression *doPrepend(const DIExpression *DIExpr, - SmallVectorImpl &Ops, - bool StackValue = false); + static DIExpression *prependOpcodes(const DIExpression *DIExpr, + SmallVectorImpl &Ops, + bool StackValue = false); /// Create a DIExpression to describe one part of an aggregate variable that /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation @@ -2603,6 +2626,76 @@ public: } }; +/// Label. +/// +class DILabel : public DINode { + friend class LLVMContextImpl; + friend class MDNode; + + unsigned Line; + + DILabel(LLVMContext &C, StorageType Storage, unsigned Line, + ArrayRef Ops) + : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {} + ~DILabel() = default; + + static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, + StringRef Name, DIFile *File, unsigned Line, + StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, + Line, Storage, ShouldCreate); + } + static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, + MDString *Name, Metadata *File, unsigned Line, + StorageType Storage, + bool ShouldCreate = true); + + TempDILabel cloneImpl() const { + return getTemporary(getContext(), getScope(), getName(), getFile(), + getLine()); + } + +public: + DEFINE_MDNODE_GET(DILabel, + (DILocalScope * Scope, StringRef Name, DIFile *File, + unsigned Line), + (Scope, Name, File, Line)) + DEFINE_MDNODE_GET(DILabel, + (Metadata * Scope, MDString *Name, Metadata *File, + unsigned Line), + (Scope, Name, File, Line)) + + TempDILabel clone() const { return cloneImpl(); } + + /// Get the local scope for this label. + /// + /// Labels must be defined in a local scope. + DILocalScope *getScope() const { + return cast_or_null(getRawScope()); + } + unsigned getLine() const { return Line; } + StringRef getName() const { return getStringOperand(1); } + DIFile *getFile() const { return cast_or_null(getRawFile()); } + + Metadata *getRawScope() const { return getOperand(0); } + MDString *getRawName() const { return getOperandAs(1); } + Metadata *getRawFile() const { return getOperand(2); } + + /// Check that a location is valid for this label. + /// + /// Check that \c DL exists, is in the same subprogram, and has the same + /// inlined-at location as \c this. (Otherwise, it's not a valid attachment + /// to a \a DbgInfoIntrinsic.) + bool isValidLocationForIntrinsic(const DILocation *DL) const { + return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram(); + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DILabelKind; + } +}; + class DIObjCProperty : public DINode { friend class LLVMContextImpl; friend class MDNode; diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h index eef1212abc4b7d97849a4161792dff205b312142..9f619ffc5c4d304ac1f067e7da42a0d7a8a54d2f 100644 --- a/include/llvm/IR/DebugLoc.h +++ b/include/llvm/IR/DebugLoc.h @@ -24,7 +24,7 @@ namespace llvm { class raw_ostream; class DILocation; - /// \brief A debug info location. + /// A debug info location. /// /// This class is a wrapper around a tracking reference to an \a DILocation /// pointer. @@ -37,10 +37,10 @@ namespace llvm { public: DebugLoc() = default; - /// \brief Construct from an \a DILocation. + /// Construct from an \a DILocation. DebugLoc(const DILocation *L); - /// \brief Construct from an \a MDNode. + /// Construct from an \a MDNode. /// /// Note: if \c N is not an \a DILocation, a verifier check will fail, and /// accessors will crash. However, construction from other nodes is @@ -48,7 +48,7 @@ namespace llvm { /// IR. explicit DebugLoc(const MDNode *N); - /// \brief Get the underlying \a DILocation. + /// Get the underlying \a DILocation. /// /// \pre !*this or \c isa(getAsMDNode()). /// @{ @@ -58,7 +58,7 @@ namespace llvm { DILocation &operator*() const { return *get(); } /// @} - /// \brief Check for null. + /// Check for null. /// /// Check for null in a way that is safe with broken debug info. Unlike /// the conversion to \c DILocation, this doesn't require that \c Loc is of @@ -66,10 +66,10 @@ namespace llvm { /// \a Instruction::hasMetadata(). explicit operator bool() const { return Loc; } - /// \brief Check whether this has a trivial destructor. + /// Check whether this has a trivial destructor. bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); } - /// \brief Create a new DebugLoc. + /// Create a new DebugLoc. /// /// Create a new DebugLoc at the specified line/col and scope/inline. This /// forwards to \a DILocation::get(). @@ -95,12 +95,12 @@ namespace llvm { MDNode *getScope() const; DILocation *getInlinedAt() const; - /// \brief Get the fully inlined-at scope for a DebugLoc. + /// Get the fully inlined-at scope for a DebugLoc. /// /// Gets the inlined-at scope for a DebugLoc. MDNode *getInlinedAtScope() const; - /// \brief Find the debug info location for the start of the function. + /// Find the debug info location for the start of the function. /// /// Walk up the scope chain of given debug loc and find line number info /// for the function. @@ -109,7 +109,7 @@ namespace llvm { /// find the subprogram, and then DILocation::get(). DebugLoc getFnDebugLoc() const; - /// \brief Return \c this as a bar \a MDNode. + /// Return \c this as a bar \a MDNode. MDNode *getAsMDNode() const { return Loc; } bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; } @@ -117,7 +117,7 @@ namespace llvm { void dump() const; - /// \brief prints source location /path/to/file.exe:line:col @[inlined at] + /// prints source location /path/to/file.exe:line:col @[inlined at] void print(raw_ostream &OS) const; }; diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 6e5e085873ab862731daf09efd36b0e51078a55c..fc7d436423ef7e4ae9015fb6b4d36fc2275c8e83 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -36,7 +36,7 @@ class LLVMContext; /// Class to represent integer types. Note that this class is also used to /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and /// Int64Ty. -/// @brief Integer representation type +/// Integer representation type class IntegerType : public Type { friend class LLVMContextImpl; @@ -59,10 +59,10 @@ public: /// If an IntegerType with the same NumBits value was previously instantiated, /// that instance will be returned. Otherwise a new one will be created. Only /// one instance with a given NumBits value is ever created. - /// @brief Get or create an IntegerType instance. + /// Get or create an IntegerType instance. static IntegerType *get(LLVMContext &C, unsigned NumBits); - /// @brief Get the number of bits in this IntegerType + /// Get the number of bits in this IntegerType unsigned getBitWidth() const { return getSubclassData(); } /// Return a bitmask with ones set for all of the bits that can be set by an @@ -79,13 +79,13 @@ public: /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc. /// @returns a bit mask with ones set for all the bits of this type. - /// @brief Get a bit mask for this type. + /// Get a bit mask for this type. APInt getMask() const; /// This method determines if the width of this IntegerType is a power-of-2 /// in terms of 8 bit bytes. /// @returns true if this is a power-of-2 byte width. - /// @brief Is this a power-of-2 byte-width IntegerType ? + /// Is this a power-of-2 byte-width IntegerType ? bool isPowerOf2ByteWidth() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. diff --git a/include/llvm/IR/DiagnosticHandler.h b/include/llvm/IR/DiagnosticHandler.h index 9256d4850df19e9d17d9243a4f00d342bfeb51d0..51873bea3d413598207109aa541aeff339de2773 100644 --- a/include/llvm/IR/DiagnosticHandler.h +++ b/include/llvm/IR/DiagnosticHandler.h @@ -18,7 +18,7 @@ namespace llvm { class DiagnosticInfo; -/// \brief This is the base class for diagnostic handling in LLVM. +/// This is the base class for diagnostic handling in LLVM. /// The handleDiagnostics method must be overriden by the subclasses to handle /// diagnostic. The *RemarkEnabled methods can be overriden to control /// which remarks are enabled. diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index bfec2be36c33f757fac7fd9de940445ebd60ff9c..81d4ae84bf01253fb83cc79c77ab469d1b8575e1 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -39,7 +39,7 @@ class LLVMContext; class Module; class SMDiagnostic; -/// \brief Defines the different supported severity of a diagnostic. +/// Defines the different supported severity of a diagnostic. enum DiagnosticSeverity : char { DS_Error, DS_Warning, @@ -49,7 +49,7 @@ enum DiagnosticSeverity : char { DS_Note }; -/// \brief Defines the different supported kind of a diagnostic. +/// Defines the different supported kind of a diagnostic. /// This enum should be extended with a new ID for each added concrete subclass. enum DiagnosticKind { DK_InlineAsm, @@ -79,7 +79,7 @@ enum DiagnosticKind { DK_FirstPluginKind }; -/// \brief Get the next available kind ID for a plugin diagnostic. +/// Get the next available kind ID for a plugin diagnostic. /// Each time this function is called, it returns a different number. /// Therefore, a plugin that wants to "identify" its own classes /// with a dynamic identifier, just have to use this method to get a new ID @@ -89,7 +89,7 @@ enum DiagnosticKind { /// DiagnosticKind values. int getNextAvailablePluginDiagnosticKind(); -/// \brief This is the base abstract class for diagnostic reporting in +/// This is the base abstract class for diagnostic reporting in /// the backend. /// The print method must be overloaded by the subclasses to print a /// user-friendly message in the client of the backend (let us call it a @@ -389,20 +389,20 @@ private: DiagnosticLocation Loc; }; -/// \brief Common features for diagnostics dealing with optimization remarks +/// Common features for diagnostics dealing with optimization remarks /// that are used by both IR and MIR passes. class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase { public: - /// \brief Used to set IsVerbose via the stream interface. + /// Used to set IsVerbose via the stream interface. struct setIsVerbose {}; - /// \brief When an instance of this is inserted into the stream, the arguments + /// When an instance of this is inserted into the stream, the arguments /// following will not appear in the remark printed in the compiler output /// (-Rpass) but only in the optimization record file /// (-fsave-optimization-record). struct setExtraArgs {}; - /// \brief Used in the streaming interface as the general argument type. It + /// Used in the streaming interface as the general argument type. It /// internally converts everything into a key-value pair. struct Argument { std::string Key; @@ -504,7 +504,7 @@ protected: /// The remark is expected to be noisy. bool IsVerbose = false; - /// \brief If positive, the index of the first argument that only appear in + /// If positive, the index of the first argument that only appear in /// the optimization records and not in the remark printed in the compiler /// output. int FirstExtraArgIndex = -1; @@ -587,7 +587,7 @@ operator<<(RemarkT &R, return R; } -/// \brief Common features for diagnostics dealing with optimization remarks +/// Common features for diagnostics dealing with optimization remarks /// that are used by IR passes. class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { public: @@ -609,7 +609,7 @@ public: Loc), CodeRegion(CodeRegion) {} - /// \brief This is ctor variant allows a pass to build an optimization remark + /// This is ctor variant allows a pass to build an optimization remark /// from an existing remark. /// /// This is useful when a transformation pass (e.g LV) wants to emit a remark @@ -712,7 +712,7 @@ public: const DiagnosticLocation &Loc, const Value *CodeRegion); - /// \brief Same as above but \p Inst is used to derive code region and debug + /// Same as above but \p Inst is used to derive code region and debug /// location. OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, const Instruction *Inst); @@ -753,7 +753,7 @@ public: const DiagnosticLocation &Loc, const Value *CodeRegion); - /// \brief This is ctor variant allows a pass to build an optimization remark + /// This is ctor variant allows a pass to build an optimization remark /// from an existing remark. /// /// This is useful when a transformation pass (e.g LV) wants to emit a remark @@ -764,7 +764,7 @@ public: const OptimizationRemarkAnalysis &Orig) : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {} - /// \brief Same as above but \p Inst is used to derive code region and debug + /// Same as above but \p Inst is used to derive code region and debug /// location. OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, const Instruction *Inst); diff --git a/include/llvm/IR/DiagnosticPrinter.h b/include/llvm/IR/DiagnosticPrinter.h index 59c83291affac81921072f2f64be79975da7fca5..25c47cdd1a1208bf5de7683f70d7f8718dea10c7 100644 --- a/include/llvm/IR/DiagnosticPrinter.h +++ b/include/llvm/IR/DiagnosticPrinter.h @@ -28,7 +28,7 @@ class StringRef; class Twine; class Value; -/// \brief Interface for custom diagnostic printing. +/// Interface for custom diagnostic printing. class DiagnosticPrinter { public: virtual ~DiagnosticPrinter() = default; @@ -58,7 +58,7 @@ public: virtual DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) = 0; }; -/// \brief Basic diagnostic printer that uses an underlying raw_ostream. +/// Basic diagnostic printer that uses an underlying raw_ostream. class DiagnosticPrinterRawOStream : public DiagnosticPrinter { protected: raw_ostream &Stream; diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index f6811bc44708e37f986f679f709fa26a915a34d9..f9e992b0ef0c936b1869ab5d139eb3fd261ef100 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -121,7 +121,7 @@ template <> struct DenseMapInfo { } }; -/// \brief Concrete subclass of DominatorTreeBase that is used to compute a +/// Concrete subclass of DominatorTreeBase that is used to compute a /// normal dominator tree. /// /// Definition: A block is said to be forward statically reachable if there is @@ -153,7 +153,7 @@ class DominatorTree : public DominatorTreeBase { // Ensure base-class overloads are visible. using Base::dominates; - /// \brief Return true if Def dominates a use in User. + /// Return true if Def dominates a use in User. /// /// This performs the special checks necessary if Def and User are in the same /// basic block. Note that Def doesn't dominate a use in Def itself! @@ -171,7 +171,7 @@ class DominatorTree : public DominatorTreeBase { // Ensure base class overloads are visible. using Base::isReachableFromEntry; - /// \brief Provide an overload for a Use. + /// Provide an overload for a Use. bool isReachableFromEntry(const Use &U) const; // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`. @@ -221,20 +221,20 @@ template <> struct GraphTraits } }; -/// \brief Analysis pass which computes a \c DominatorTree. +/// Analysis pass which computes a \c DominatorTree. class DominatorTreeAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; static AnalysisKey Key; public: - /// \brief Provide the result typedef for this analysis pass. + /// Provide the result typedef for this analysis pass. using Result = DominatorTree; - /// \brief Run the analysis pass over a function and produce a dominator tree. + /// Run the analysis pass over a function and produce a dominator tree. DominatorTree run(Function &F, FunctionAnalysisManager &); }; -/// \brief Printer pass for the \c DominatorTree. +/// Printer pass for the \c DominatorTree. class DominatorTreePrinterPass : public PassInfoMixin { raw_ostream &OS; @@ -245,12 +245,12 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Verifier pass for the \c DominatorTree. +/// Verifier pass for the \c DominatorTree. struct DominatorTreeVerifierPass : PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; -/// \brief Legacy analysis pass which computes a \c DominatorTree. +/// Legacy analysis pass which computes a \c DominatorTree. class DominatorTreeWrapperPass : public FunctionPass { DominatorTree DT; @@ -278,7 +278,7 @@ public: }; //===------------------------------------- -/// \brief Class to defer updates to a DominatorTree. +/// Class to defer updates to a DominatorTree. /// /// Definition: Applying updates to every edge insertion and deletion is /// expensive and not necessary. When one needs the DominatorTree for analysis @@ -308,40 +308,40 @@ class DeferredDominance { public: DeferredDominance(DominatorTree &DT_) : DT(DT_) {} - /// \brief Queues multiple updates and discards duplicates. + /// Queues multiple updates and discards duplicates. void applyUpdates(ArrayRef Updates); - /// \brief Helper method for a single edge insertion. It's almost always + /// Helper method for a single edge insertion. It's almost always /// better to batch updates and call applyUpdates to quickly remove duplicate /// edges. This is best used when there is only a single insertion needed to /// update Dominators. void insertEdge(BasicBlock *From, BasicBlock *To); - /// \brief Helper method for a single edge deletion. It's almost always better + /// Helper method for a single edge deletion. It's almost always better /// to batch updates and call applyUpdates to quickly remove duplicate edges. /// This is best used when there is only a single deletion needed to update /// Dominators. void deleteEdge(BasicBlock *From, BasicBlock *To); - /// \brief Delays the deletion of a basic block until a flush() event. + /// Delays the deletion of a basic block until a flush() event. void deleteBB(BasicBlock *DelBB); - /// \brief Returns true if DelBB is awaiting deletion at a flush() event. + /// Returns true if DelBB is awaiting deletion at a flush() event. bool pendingDeletedBB(BasicBlock *DelBB); - /// \brief Returns true if pending DT updates are queued for a flush() event. + /// Returns true if pending DT updates are queued for a flush() event. bool pending(); - /// \brief Flushes all pending updates and block deletions. Returns a + /// Flushes all pending updates and block deletions. Returns a /// correct DominatorTree reference to be used by the caller for analysis. DominatorTree &flush(); - /// \brief Drops all internal state and forces a (slow) recalculation of the + /// Drops all internal state and forces a (slow) recalculation of the /// DominatorTree based on the current state of the LLVM IR in F. This should /// only be used in corner cases such as the Entry block of F being deleted. void recalculate(Function &F); - /// \brief Debug method to help view the state of pending updates. + /// Debug method to help view the state of pending updates. LLVM_DUMP_METHOD void dump() const; private: diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index ec9d370bc3c083478f26dba9f67f39d4bd98fef2..029172e7ba8b72e50adbeb56ebb673b9dbb4a152 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -141,6 +141,11 @@ public: // Provide fast operand accessors. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// Returns the number of non-debug IR instructions in this function. + /// This is equivalent to the sum of the sizes of each basic block contained + /// within this function. + unsigned getInstructionCount(); + /// Returns the FunctionType for me. FunctionType *getFunctionType() const { return cast(getValueType()); @@ -181,7 +186,7 @@ public: static Intrinsic::ID lookupIntrinsicID(StringRef Name); - /// \brief Recalculate the ID for this function if it is an Intrinsic defined + /// Recalculate the ID for this function if it is an Intrinsic defined /// in llvm/Intrinsics.h. Sets the intrinsic ID to Intrinsic::not_intrinsic /// if the name of this function does not match an intrinsic in that header. /// Note, this method does not need to be called directly, as it is called @@ -201,34 +206,34 @@ public: setValueSubclassData((getSubclassDataFromValue() & 0xc00f) | (ID << 4)); } - /// @brief Return the attribute list for this Function. + /// Return the attribute list for this Function. AttributeList getAttributes() const { return AttributeSets; } - /// @brief Set the attribute list for this Function. + /// Set the attribute list for this Function. void setAttributes(AttributeList Attrs) { AttributeSets = Attrs; } - /// @brief Add function attributes to this function. + /// Add function attributes to this function. void addFnAttr(Attribute::AttrKind Kind) { addAttribute(AttributeList::FunctionIndex, Kind); } - /// @brief Add function attributes to this function. + /// Add function attributes to this function. void addFnAttr(StringRef Kind, StringRef Val = StringRef()) { addAttribute(AttributeList::FunctionIndex, Attribute::get(getContext(), Kind, Val)); } - /// @brief Add function attributes to this function. + /// Add function attributes to this function. void addFnAttr(Attribute Attr) { addAttribute(AttributeList::FunctionIndex, Attr); } - /// @brief Remove function attributes from this function. + /// Remove function attributes from this function. void removeFnAttr(Attribute::AttrKind Kind) { removeAttribute(AttributeList::FunctionIndex, Kind); } - /// @brief Remove function attribute from this function. + /// Remove function attribute from this function. void removeFnAttr(StringRef Kind) { setAttributes(getAttributes().removeAttribute( getContext(), AttributeList::FunctionIndex, Kind)); @@ -263,7 +268,7 @@ public: static ProfileCount getInvalid() { return ProfileCount(-1, PCT_Invalid); } }; - /// \brief Set the entry count for this function. + /// Set the entry count for this function. /// /// Entry count is the number of times this function was executed based on /// pgo data. \p Imports points to a set of GUIDs that needs to @@ -276,7 +281,7 @@ public: void setEntryCount(uint64_t Count, ProfileCountType Type = PCT_Real, const DenseSet *Imports = nullptr); - /// \brief Get the entry count for this function. + /// Get the entry count for this function. /// /// Entry count is the number of times the function was executed based on /// pgo data. @@ -298,27 +303,27 @@ public: /// Get the section prefix for this function. Optional getSectionPrefix() const; - /// @brief Return true if the function has the attribute. + /// Return true if the function has the attribute. bool hasFnAttribute(Attribute::AttrKind Kind) const { return AttributeSets.hasFnAttribute(Kind); } - /// @brief Return true if the function has the attribute. + /// Return true if the function has the attribute. bool hasFnAttribute(StringRef Kind) const { return AttributeSets.hasFnAttribute(Kind); } - /// @brief Return the attribute for the given attribute kind. + /// Return the attribute for the given attribute kind. Attribute getFnAttribute(Attribute::AttrKind Kind) const { return getAttribute(AttributeList::FunctionIndex, Kind); } - /// @brief Return the attribute for the given attribute kind. + /// Return the attribute for the given attribute kind. Attribute getFnAttribute(StringRef Kind) const { return getAttribute(AttributeList::FunctionIndex, Kind); } - /// \brief Return the stack alignment for the function. + /// Return the stack alignment for the function. unsigned getFnStackAlignment() const { if (!hasFnAttribute(Attribute::StackAlignment)) return 0; @@ -334,110 +339,110 @@ public: void setGC(std::string Str); void clearGC(); - /// @brief adds the attribute to the list of attributes. + /// adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute::AttrKind Kind); - /// @brief adds the attribute to the list of attributes. + /// adds the attribute to the list of attributes. void addAttribute(unsigned i, Attribute Attr); - /// @brief adds the attributes to the list of attributes. + /// adds the attributes to the list of attributes. void addAttributes(unsigned i, const AttrBuilder &Attrs); - /// @brief adds the attribute to the list of attributes for the given arg. + /// adds the attribute to the list of attributes for the given arg. void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); - /// @brief adds the attribute to the list of attributes for the given arg. + /// adds the attribute to the list of attributes for the given arg. void addParamAttr(unsigned ArgNo, Attribute Attr); - /// @brief adds the attributes to the list of attributes for the given arg. + /// adds the attributes to the list of attributes for the given arg. void addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs); - /// @brief removes the attribute from the list of attributes. + /// removes the attribute from the list of attributes. void removeAttribute(unsigned i, Attribute::AttrKind Kind); - /// @brief removes the attribute from the list of attributes. + /// removes the attribute from the list of attributes. void removeAttribute(unsigned i, StringRef Kind); - /// @brief removes the attributes from the list of attributes. + /// removes the attributes from the list of attributes. void removeAttributes(unsigned i, const AttrBuilder &Attrs); - /// @brief removes the attribute from the list of attributes. + /// removes the attribute from the list of attributes. void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind); - /// @brief removes the attribute from the list of attributes. + /// removes the attribute from the list of attributes. void removeParamAttr(unsigned ArgNo, StringRef Kind); - /// @brief removes the attribute from the list of attributes. + /// removes the attribute from the list of attributes. void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs); - /// @brief check if an attributes is in the list of attributes. + /// check if an attributes is in the list of attributes. bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const { return getAttributes().hasAttribute(i, Kind); } - /// @brief check if an attributes is in the list of attributes. + /// check if an attributes is in the list of attributes. bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const { return getAttributes().hasParamAttribute(ArgNo, Kind); } - /// @brief gets the attribute from the list of attributes. + /// gets the attribute from the list of attributes. Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const { return AttributeSets.getAttribute(i, Kind); } - /// @brief gets the attribute from the list of attributes. + /// gets the attribute from the list of attributes. Attribute getAttribute(unsigned i, StringRef Kind) const { return AttributeSets.getAttribute(i, Kind); } - /// @brief adds the dereferenceable attribute to the list of attributes. + /// adds the dereferenceable attribute to the list of attributes. void addDereferenceableAttr(unsigned i, uint64_t Bytes); - /// @brief adds the dereferenceable attribute to the list of attributes for + /// adds the dereferenceable attribute to the list of attributes for /// the given arg. void addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes); - /// @brief adds the dereferenceable_or_null attribute to the list of + /// adds the dereferenceable_or_null attribute to the list of /// attributes. void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes); - /// @brief adds the dereferenceable_or_null attribute to the list of + /// adds the dereferenceable_or_null attribute to the list of /// attributes for the given arg. void addDereferenceableOrNullParamAttr(unsigned ArgNo, uint64_t Bytes); - /// @brief Extract the alignment for a call or parameter (0=unknown). + /// Extract the alignment for a call or parameter (0=unknown). unsigned getParamAlignment(unsigned ArgNo) const { return AttributeSets.getParamAlignment(ArgNo); } - /// @brief Extract the number of dereferenceable bytes for a call or + /// Extract the number of dereferenceable bytes for a call or /// parameter (0=unknown). /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableBytes(unsigned i) const { return AttributeSets.getDereferenceableBytes(i); } - /// @brief Extract the number of dereferenceable bytes for a parameter. + /// Extract the number of dereferenceable bytes for a parameter. /// @param ArgNo Index of an argument, with 0 being the first function arg. uint64_t getParamDereferenceableBytes(unsigned ArgNo) const { return AttributeSets.getParamDereferenceableBytes(ArgNo); } - /// @brief Extract the number of dereferenceable_or_null bytes for a call or + /// Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeSets.getDereferenceableOrNullBytes(i); } - /// @brief Extract the number of dereferenceable_or_null bytes for a + /// Extract the number of dereferenceable_or_null bytes for a /// parameter. /// @param ArgNo AttributeList ArgNo, referring to an argument. uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const { return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo); } - /// @brief Determine if the function does not access memory. + /// Determine if the function does not access memory. bool doesNotAccessMemory() const { return hasFnAttribute(Attribute::ReadNone); } @@ -445,7 +450,7 @@ public: addFnAttr(Attribute::ReadNone); } - /// @brief Determine if the function does not access or only reads memory. + /// Determine if the function does not access or only reads memory. bool onlyReadsMemory() const { return doesNotAccessMemory() || hasFnAttribute(Attribute::ReadOnly); } @@ -453,7 +458,7 @@ public: addFnAttr(Attribute::ReadOnly); } - /// @brief Determine if the function does not access or only writes memory. + /// Determine if the function does not access or only writes memory. bool doesNotReadMemory() const { return doesNotAccessMemory() || hasFnAttribute(Attribute::WriteOnly); } @@ -461,14 +466,14 @@ public: addFnAttr(Attribute::WriteOnly); } - /// @brief Determine if the call can access memmory only using pointers based + /// Determine if the call can access memmory only using pointers based /// on its arguments. bool onlyAccessesArgMemory() const { return hasFnAttribute(Attribute::ArgMemOnly); } void setOnlyAccessesArgMemory() { addFnAttr(Attribute::ArgMemOnly); } - /// @brief Determine if the function may only access memory that is + /// Determine if the function may only access memory that is /// inaccessible from the IR. bool onlyAccessesInaccessibleMemory() const { return hasFnAttribute(Attribute::InaccessibleMemOnly); @@ -477,7 +482,7 @@ public: addFnAttr(Attribute::InaccessibleMemOnly); } - /// @brief Determine if the function may only access memory that is + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const { return hasFnAttribute(Attribute::InaccessibleMemOrArgMemOnly); @@ -486,7 +491,7 @@ public: addFnAttr(Attribute::InaccessibleMemOrArgMemOnly); } - /// @brief Determine if the function cannot return. + /// Determine if the function cannot return. bool doesNotReturn() const { return hasFnAttribute(Attribute::NoReturn); } @@ -497,7 +502,7 @@ public: /// Determine if the function should not perform indirect branch tracking. bool doesNoCfCheck() const { return hasFnAttribute(Attribute::NoCfCheck); } - /// @brief Determine if the function cannot unwind. + /// Determine if the function cannot unwind. bool doesNotThrow() const { return hasFnAttribute(Attribute::NoUnwind); } @@ -505,7 +510,7 @@ public: addFnAttr(Attribute::NoUnwind); } - /// @brief Determine if the call cannot be duplicated. + /// Determine if the call cannot be duplicated. bool cannotDuplicate() const { return hasFnAttribute(Attribute::NoDuplicate); } @@ -513,7 +518,7 @@ public: addFnAttr(Attribute::NoDuplicate); } - /// @brief Determine if the call is convergent. + /// Determine if the call is convergent. bool isConvergent() const { return hasFnAttribute(Attribute::Convergent); } @@ -524,7 +529,7 @@ public: removeFnAttr(Attribute::Convergent); } - /// @brief Determine if the call has sideeffects. + /// Determine if the call has sideeffects. bool isSpeculatable() const { return hasFnAttribute(Attribute::Speculatable); } @@ -541,7 +546,7 @@ public: addFnAttr(Attribute::NoRecurse); } - /// @brief True if the ABI mandates (or the user requested) that this + /// True if the ABI mandates (or the user requested) that this /// function be in a unwind table. bool hasUWTable() const { return hasFnAttribute(Attribute::UWTable); @@ -550,19 +555,19 @@ public: addFnAttr(Attribute::UWTable); } - /// @brief True if this function needs an unwind table. + /// True if this function needs an unwind table. bool needsUnwindTableEntry() const { return hasUWTable() || !doesNotThrow(); } - /// @brief Determine if the function returns a structure through first + /// Determine if the function returns a structure through first /// or second pointer argument. bool hasStructRetAttr() const { return AttributeSets.hasParamAttribute(0, Attribute::StructRet) || AttributeSets.hasParamAttribute(1, Attribute::StructRet); } - /// @brief Determine if the parameter or return value is marked with NoAlias + /// Determine if the parameter or return value is marked with NoAlias /// attribute. bool returnDoesNotAlias() const { return AttributeSets.hasAttribute(AttributeList::ReturnIndex, @@ -679,30 +684,30 @@ public: size_t arg_size() const { return NumArgs; } bool arg_empty() const { return arg_size() == 0; } - /// \brief Check whether this function has a personality function. + /// Check whether this function has a personality function. bool hasPersonalityFn() const { return getSubclassDataFromValue() & (1<<3); } - /// \brief Get the personality function associated with this function. + /// Get the personality function associated with this function. Constant *getPersonalityFn() const; void setPersonalityFn(Constant *Fn); - /// \brief Check whether this function has prefix data. + /// Check whether this function has prefix data. bool hasPrefixData() const { return getSubclassDataFromValue() & (1<<1); } - /// \brief Get the prefix data associated with this function. + /// Get the prefix data associated with this function. Constant *getPrefixData() const; void setPrefixData(Constant *PrefixData); - /// \brief Check whether this function has prologue data. + /// Check whether this function has prologue data. bool hasPrologueData() const { return getSubclassDataFromValue() & (1<<2); } - /// \brief Get the prologue data associated with this function. + /// Get the prologue data associated with this function. Constant *getPrologueData() const; void setPrologueData(Constant *PrologueData); @@ -762,12 +767,12 @@ public: /// setjmp or other function that gcc recognizes as "returning twice". bool callsFunctionThatReturnsTwice() const; - /// \brief Set the attached subprogram. + /// Set the attached subprogram. /// /// Calls \a setMetadata() with \a LLVMContext::MD_dbg. void setSubprogram(DISubprogram *SP); - /// \brief Get the attached subprogram. + /// Get the attached subprogram. /// /// Calls \a getMetadata() with \a LLVMContext::MD_dbg and casts the result /// to \a DISubprogram. diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index 278b193567f1f6f220cbe4fe31599aa2d4140eb0..1fd3568100c2673ee0340e1003a55b2914d36c8c 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -105,6 +105,14 @@ public: /// Check if this has any metadata. bool hasMetadata() const { return hasMetadataHashEntry(); } + /// Check if this has any metadata of the given kind. + bool hasMetadata(unsigned KindID) const { + return getMetadata(KindID) != nullptr; + } + bool hasMetadata(StringRef Kind) const { + return getMetadata(Kind) != nullptr; + } + /// Get the current metadata attachments for the given kind, if any. /// /// These functions require that the function have at most a single attachment @@ -143,7 +151,9 @@ public: getAllMetadata(SmallVectorImpl> &MDs) const; /// Erase all metadata attachments with the given kind. - void eraseMetadata(unsigned KindID); + /// + /// \returns true if any metadata was removed. + bool eraseMetadata(unsigned KindID); /// Copy metadata from Src, adjusting offsets by Offset. void copyMetadata(const GlobalObject *Src, unsigned Offset); diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index 35b0b6989cd2598a75237f6a3500d8c33e8f0918..3e42bd60a6d9f504e4f93243ad1fa91cc8766faf 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -44,7 +44,7 @@ namespace Intrinsic { class GlobalValue : public Constant { public: - /// @brief An enumeration for the kinds of linkage for global values. + /// An enumeration for the kinds of linkage for global values. enum LinkageTypes { ExternalLinkage = 0,///< Externally visible function AvailableExternallyLinkage, ///< Available for inspection, not emission. @@ -59,14 +59,14 @@ public: CommonLinkage ///< Tentative definitions. }; - /// @brief An enumeration for the kinds of visibility of global values. + /// An enumeration for the kinds of visibility of global values. enum VisibilityTypes { DefaultVisibility = 0, ///< The GV is visible HiddenVisibility, ///< The GV is hidden ProtectedVisibility ///< The GV is protected }; - /// @brief Storage classes of global values for PE targets. + /// Storage classes of global values for PE targets. enum DLLStorageClassTypes { DefaultStorageClass = 0, DLLImportStorageClass = 1, ///< Function to be imported from DLL @@ -150,7 +150,7 @@ private: } protected: - /// \brief The intrinsic ID for this subclass (which must be a Function). + /// The intrinsic ID for this subclass (which must be a Function). /// /// This member is defined by this class, but not used for anything. /// Subclasses can use it to store their intrinsic ID, if they have one. diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index e46544a4f9ba58a751b083643f4026fd8319a671..056b8625fa50c5dc60f6c2fa8d42158b55895daa 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -54,7 +54,7 @@ class APInt; class MDNode; class Use; -/// \brief This provides the default implementation of the IRBuilder +/// This provides the default implementation of the IRBuilder /// 'InsertHelper' method that is called whenever an instruction is created by /// IRBuilder and needs to be inserted. /// @@ -85,7 +85,7 @@ protected: } }; -/// \brief Common base class shared among various IRBuilders. +/// Common base class shared among various IRBuilders. class IRBuilderBase { DebugLoc CurDbgLocation; @@ -111,7 +111,7 @@ public: // Builder configuration methods //===--------------------------------------------------------------------===// - /// \brief Clear the insertion point: created instructions will not be + /// Clear the insertion point: created instructions will not be /// inserted into a block. void ClearInsertionPoint() { BB = nullptr; @@ -122,14 +122,14 @@ public: BasicBlock::iterator GetInsertPoint() const { return InsertPt; } LLVMContext &getContext() const { return Context; } - /// \brief This specifies that created instructions should be appended to the + /// This specifies that created instructions should be appended to the /// end of the specified block. void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } - /// \brief This specifies that created instructions should be inserted before + /// This specifies that created instructions should be inserted before /// the specified instruction. void SetInsertPoint(Instruction *I) { BB = I->getParent(); @@ -138,7 +138,7 @@ public: SetCurrentDebugLocation(I->getDebugLoc()); } - /// \brief This specifies that created instructions should be inserted at the + /// This specifies that created instructions should be inserted at the /// specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; @@ -147,20 +147,20 @@ public: SetCurrentDebugLocation(IP->getDebugLoc()); } - /// \brief Set location information used by debugging information. + /// Set location information used by debugging information. void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } - /// \brief Get location information used by debugging information. + /// Get location information used by debugging information. const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } - /// \brief If this builder has a current debug location, set it on the + /// If this builder has a current debug location, set it on the /// specified instruction. void SetInstDebugLocation(Instruction *I) const { if (CurDbgLocation) I->setDebugLoc(CurDbgLocation); } - /// \brief Get the return type of the current function that we're emitting + /// Get the return type of the current function that we're emitting /// into. Type *getCurrentFunctionReturnType() const; @@ -170,33 +170,33 @@ public: BasicBlock::iterator Point; public: - /// \brief Creates a new insertion point which doesn't point to anything. + /// Creates a new insertion point which doesn't point to anything. InsertPoint() = default; - /// \brief Creates a new insertion point at the given location. + /// Creates a new insertion point at the given location. InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint) : Block(InsertBlock), Point(InsertPoint) {} - /// \brief Returns true if this insert point is set. + /// Returns true if this insert point is set. bool isSet() const { return (Block != nullptr); } BasicBlock *getBlock() const { return Block; } BasicBlock::iterator getPoint() const { return Point; } }; - /// \brief Returns the current insert point. + /// Returns the current insert point. InsertPoint saveIP() const { return InsertPoint(GetInsertBlock(), GetInsertPoint()); } - /// \brief Returns the current insert point, clearing it in the process. + /// Returns the current insert point, clearing it in the process. InsertPoint saveAndClearIP() { InsertPoint IP(GetInsertBlock(), GetInsertPoint()); ClearInsertionPoint(); return IP; } - /// \brief Sets the current insert point to a previously-saved location. + /// Sets the current insert point to a previously-saved location. void restoreIP(InsertPoint IP) { if (IP.isSet()) SetInsertPoint(IP.getBlock(), IP.getPoint()); @@ -204,26 +204,26 @@ public: ClearInsertionPoint(); } - /// \brief Get the floating point math metadata being used. + /// Get the floating point math metadata being used. MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } - /// \brief Get the flags to be applied to created floating point ops + /// Get the flags to be applied to created floating point ops FastMathFlags getFastMathFlags() const { return FMF; } - /// \brief Clear the fast-math flags. + /// Clear the fast-math flags. void clearFastMathFlags() { FMF.clear(); } - /// \brief Set the floating point math metadata to be used. + /// Set the floating point math metadata to be used. void setDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } - /// \brief Set the fast-math flags to be used with generated fp-math operators + /// Set the fast-math flags to be used with generated fp-math operators void setFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; } //===--------------------------------------------------------------------===// // RAII helpers. //===--------------------------------------------------------------------===// - // \brief RAII object that stores the current insertion point and restores it + // RAII object that stores the current insertion point and restores it // when the object is destroyed. This includes the debug location. class InsertPointGuard { IRBuilderBase &Builder; @@ -245,7 +245,7 @@ public: } }; - // \brief RAII object that stores the current fast math settings and restores + // RAII object that stores the current fast math settings and restores // them when the object is destroyed. class FastMathFlagGuard { IRBuilderBase &Builder; @@ -269,7 +269,7 @@ public: // Miscellaneous creation methods. //===--------------------------------------------------------------------===// - /// \brief Make a new global variable with initializer type i8* + /// Make a new global variable with initializer type i8* /// /// Make a new global variable with an initializer that has array of i8 type /// filled in with the null terminated string value specified. The new global @@ -278,48 +278,48 @@ public: GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "", unsigned AddressSpace = 0); - /// \brief Get a constant value representing either true or false. + /// Get a constant value representing either true or false. ConstantInt *getInt1(bool V) { return ConstantInt::get(getInt1Ty(), V); } - /// \brief Get the constant value for i1 true. + /// Get the constant value for i1 true. ConstantInt *getTrue() { return ConstantInt::getTrue(Context); } - /// \brief Get the constant value for i1 false. + /// Get the constant value for i1 false. ConstantInt *getFalse() { return ConstantInt::getFalse(Context); } - /// \brief Get a constant 8-bit value. + /// Get a constant 8-bit value. ConstantInt *getInt8(uint8_t C) { return ConstantInt::get(getInt8Ty(), C); } - /// \brief Get a constant 16-bit value. + /// Get a constant 16-bit value. ConstantInt *getInt16(uint16_t C) { return ConstantInt::get(getInt16Ty(), C); } - /// \brief Get a constant 32-bit value. + /// Get a constant 32-bit value. ConstantInt *getInt32(uint32_t C) { return ConstantInt::get(getInt32Ty(), C); } - /// \brief Get a constant 64-bit value. + /// Get a constant 64-bit value. ConstantInt *getInt64(uint64_t C) { return ConstantInt::get(getInt64Ty(), C); } - /// \brief Get a constant N-bit value, zero extended or truncated from + /// Get a constant N-bit value, zero extended or truncated from /// a 64-bit value. ConstantInt *getIntN(unsigned N, uint64_t C) { return ConstantInt::get(getIntNTy(N), C); } - /// \brief Get a constant integer value. + /// Get a constant integer value. ConstantInt *getInt(const APInt &AI) { return ConstantInt::get(Context, AI); } @@ -328,65 +328,65 @@ public: // Type creation methods //===--------------------------------------------------------------------===// - /// \brief Fetch the type representing a single bit + /// Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); } - /// \brief Fetch the type representing an 8-bit integer. + /// Fetch the type representing an 8-bit integer. IntegerType *getInt8Ty() { return Type::getInt8Ty(Context); } - /// \brief Fetch the type representing a 16-bit integer. + /// Fetch the type representing a 16-bit integer. IntegerType *getInt16Ty() { return Type::getInt16Ty(Context); } - /// \brief Fetch the type representing a 32-bit integer. + /// Fetch the type representing a 32-bit integer. IntegerType *getInt32Ty() { return Type::getInt32Ty(Context); } - /// \brief Fetch the type representing a 64-bit integer. + /// Fetch the type representing a 64-bit integer. IntegerType *getInt64Ty() { return Type::getInt64Ty(Context); } - /// \brief Fetch the type representing a 128-bit integer. + /// Fetch the type representing a 128-bit integer. IntegerType *getInt128Ty() { return Type::getInt128Ty(Context); } - /// \brief Fetch the type representing an N-bit integer. + /// Fetch the type representing an N-bit integer. IntegerType *getIntNTy(unsigned N) { return Type::getIntNTy(Context, N); } - /// \brief Fetch the type representing a 16-bit floating point value. + /// Fetch the type representing a 16-bit floating point value. Type *getHalfTy() { return Type::getHalfTy(Context); } - /// \brief Fetch the type representing a 32-bit floating point value. + /// Fetch the type representing a 32-bit floating point value. Type *getFloatTy() { return Type::getFloatTy(Context); } - /// \brief Fetch the type representing a 64-bit floating point value. + /// Fetch the type representing a 64-bit floating point value. Type *getDoubleTy() { return Type::getDoubleTy(Context); } - /// \brief Fetch the type representing void. + /// Fetch the type representing void. Type *getVoidTy() { return Type::getVoidTy(Context); } - /// \brief Fetch the type representing a pointer to an 8-bit integer value. + /// Fetch the type representing a pointer to an 8-bit integer value. PointerType *getInt8PtrTy(unsigned AddrSpace = 0) { return Type::getInt8PtrTy(Context, AddrSpace); } - /// \brief Fetch the type representing a pointer to an integer value. + /// Fetch the type representing a pointer to an integer value. IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) { return DL.getIntPtrType(Context, AddrSpace); } @@ -395,7 +395,7 @@ public: // Intrinsic creation methods //===--------------------------------------------------------------------===// - /// \brief Create and insert a memset to the specified pointer and the + /// Create and insert a memset to the specified pointer and the /// specified value. /// /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is @@ -414,7 +414,31 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); - /// \brief Create and insert a memcpy between the specified pointers. + /// Create and insert an element unordered-atomic memset of the region of + /// memory starting at the given pointer to the given value. + /// + /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. Likewise with alias.scope + /// and noalias tags. + CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, + uint64_t Size, unsigned Align, + uint32_t ElementSize, + MDNode *TBAATag = nullptr, + MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr) { + return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size), Align, + ElementSize, TBAATag, ScopeTag, + NoAliasTag); + } + + CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, + Value *Size, unsigned Align, + uint32_t ElementSize, + MDNode *TBAATag = nullptr, + MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr); + + /// Create and insert a memcpy between the specified pointers. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope @@ -437,7 +461,7 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); - /// \brief Create and insert an element unordered-atomic memcpy between the + /// Create and insert an element unordered-atomic memcpy between the /// specified pointers. /// /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, respectively. @@ -461,7 +485,7 @@ public: MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); - /// \brief Create and insert a memmove between the specified + /// Create and insert a memmove between the specified /// pointers. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is @@ -480,51 +504,76 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); - /// \brief Create a vector fadd reduction intrinsic of the source vector. + /// \brief Create and insert an element unordered-atomic memmove between the + /// specified pointers. + /// + /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, + /// respectively. + /// + /// If the pointers aren't i8*, they will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. Likewise with alias.scope + /// and noalias tags. + CallInst *CreateElementUnorderedAtomicMemMove( + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, + uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr) { + return CreateElementUnorderedAtomicMemMove( + Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, + TBAAStructTag, ScopeTag, NoAliasTag); + } + + CallInst *CreateElementUnorderedAtomicMemMove( + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr); + + /// Create a vector fadd reduction intrinsic of the source vector. /// The first parameter is a scalar accumulator value for ordered reductions. CallInst *CreateFAddReduce(Value *Acc, Value *Src); - /// \brief Create a vector fmul reduction intrinsic of the source vector. + /// Create a vector fmul reduction intrinsic of the source vector. /// The first parameter is a scalar accumulator value for ordered reductions. CallInst *CreateFMulReduce(Value *Acc, Value *Src); - /// \brief Create a vector int add reduction intrinsic of the source vector. + /// Create a vector int add reduction intrinsic of the source vector. CallInst *CreateAddReduce(Value *Src); - /// \brief Create a vector int mul reduction intrinsic of the source vector. + /// Create a vector int mul reduction intrinsic of the source vector. CallInst *CreateMulReduce(Value *Src); - /// \brief Create a vector int AND reduction intrinsic of the source vector. + /// Create a vector int AND reduction intrinsic of the source vector. CallInst *CreateAndReduce(Value *Src); - /// \brief Create a vector int OR reduction intrinsic of the source vector. + /// Create a vector int OR reduction intrinsic of the source vector. CallInst *CreateOrReduce(Value *Src); - /// \brief Create a vector int XOR reduction intrinsic of the source vector. + /// Create a vector int XOR reduction intrinsic of the source vector. CallInst *CreateXorReduce(Value *Src); - /// \brief Create a vector integer max reduction intrinsic of the source + /// Create a vector integer max reduction intrinsic of the source /// vector. CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false); - /// \brief Create a vector integer min reduction intrinsic of the source + /// Create a vector integer min reduction intrinsic of the source /// vector. CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false); - /// \brief Create a vector float max reduction intrinsic of the source + /// Create a vector float max reduction intrinsic of the source /// vector. CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false); - /// \brief Create a vector float min reduction intrinsic of the source + /// Create a vector float min reduction intrinsic of the source /// vector. CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false); - /// \brief Create a lifetime.start intrinsic. + /// Create a lifetime.start intrinsic. /// /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = nullptr); - /// \brief Create a lifetime.end intrinsic. + /// Create a lifetime.end intrinsic. /// /// If the pointer isn't i8* it will be converted. CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = nullptr); @@ -534,29 +583,29 @@ public: /// If the pointer isn't i8* it will be converted. CallInst *CreateInvariantStart(Value *Ptr, ConstantInt *Size = nullptr); - /// \brief Create a call to Masked Load intrinsic + /// Create a call to Masked Load intrinsic CallInst *CreateMaskedLoad(Value *Ptr, unsigned Align, Value *Mask, Value *PassThru = nullptr, const Twine &Name = ""); - /// \brief Create a call to Masked Store intrinsic + /// Create a call to Masked Store intrinsic CallInst *CreateMaskedStore(Value *Val, Value *Ptr, unsigned Align, Value *Mask); - /// \brief Create a call to Masked Gather intrinsic + /// Create a call to Masked Gather intrinsic CallInst *CreateMaskedGather(Value *Ptrs, unsigned Align, Value *Mask = nullptr, Value *PassThru = nullptr, const Twine& Name = ""); - /// \brief Create a call to Masked Scatter intrinsic + /// Create a call to Masked Scatter intrinsic CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, unsigned Align, Value *Mask = nullptr); - /// \brief Create an assume intrinsic call that allows the optimizer to + /// Create an assume intrinsic call that allows the optimizer to /// assume that the provided condition will be true. CallInst *CreateAssumption(Value *Cond); - /// \brief Create a call to the experimental.gc.statepoint intrinsic to + /// Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, @@ -565,7 +614,7 @@ public: ArrayRef GCArgs, const Twine &Name = ""); - /// \brief Create a call to the experimental.gc.statepoint intrinsic to + /// Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags, @@ -575,7 +624,7 @@ public: ArrayRef GCArgs, const Twine &Name = ""); - /// \brief Conveninence function for the common case when CallArgs are filled + /// Conveninence function for the common case when CallArgs are filled /// in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be /// .get()'ed to get the Value pointer. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, @@ -584,7 +633,7 @@ public: ArrayRef GCArgs, const Twine &Name = ""); - /// \brief Create an invoke to the experimental.gc.statepoint intrinsic to + /// Create an invoke to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. InvokeInst * CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, @@ -593,7 +642,7 @@ public: ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); - /// \brief Create an invoke to the experimental.gc.statepoint intrinsic to + /// Create an invoke to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. InvokeInst *CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, @@ -612,13 +661,13 @@ public: ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name = ""); - /// \brief Create a call to the experimental.gc.result intrinsic to extract + /// Create a call to the experimental.gc.result intrinsic to extract /// the result from a call wrapped in a statepoint. CallInst *CreateGCResult(Instruction *Statepoint, Type *ResultType, const Twine &Name = ""); - /// \brief Create a call to the experimental.gc.relocate intrinsics to + /// Create a call to the experimental.gc.relocate intrinsics to /// project the relocated value of one pointer from the statepoint. CallInst *CreateGCRelocate(Instruction *Statepoint, int BaseOffset, @@ -632,6 +681,11 @@ public: Value *LHS, Value *RHS, const Twine &Name = ""); + /// Create a call to intrinsic \p ID with no operands. + CallInst *CreateIntrinsic(Intrinsic::ID ID, + Instruction *FMFSource = nullptr, + const Twine &Name = ""); + /// Create a call to intrinsic \p ID with 1 or more operands assuming the /// intrinsic and all operands have the same type. If \p FMFSource is /// provided, copy fast-math-flags from that instruction to the intrinsic. @@ -650,7 +704,7 @@ public: } private: - /// \brief Create a call to a masked intrinsic with given Id. + /// Create a call to a masked intrinsic with given Id. CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef Ops, ArrayRef OverloadedTypes, const Twine &Name = ""); @@ -658,7 +712,7 @@ private: Value *getCastedInt8PtrValue(Value *Ptr); }; -/// \brief This provides a uniform API for creating instructions and inserting +/// This provides a uniform API for creating instructions and inserting /// them into a basic block: either at the end of a BasicBlock, or at a specific /// iterator location in a block. /// @@ -720,10 +774,10 @@ public: SetInsertPoint(TheBB, IP); } - /// \brief Get the constant folder being used. + /// Get the constant folder being used. const T &getFolder() { return Folder; } - /// \brief Insert and return the specified instruction. + /// Insert and return the specified instruction. template InstTy *Insert(InstTy *I, const Twine &Name = "") const { this->InsertHelper(I, Name, BB, InsertPt); @@ -731,7 +785,7 @@ public: return I; } - /// \brief No-op overload to handle constants. + /// No-op overload to handle constants. Constant *Insert(Constant *C, const Twine& = "") const { return C; } @@ -741,7 +795,7 @@ public: //===--------------------------------------------------------------------===// private: - /// \brief Helper to add branch weight and unpredictable metadata onto an + /// Helper to add branch weight and unpredictable metadata onto an /// instruction. /// \returns The annotated instruction. template @@ -754,17 +808,17 @@ private: } public: - /// \brief Create a 'ret void' instruction. + /// Create a 'ret void' instruction. ReturnInst *CreateRetVoid() { return Insert(ReturnInst::Create(Context)); } - /// \brief Create a 'ret ' instruction. + /// Create a 'ret ' instruction. ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(Context, V)); } - /// \brief Create a sequence of N insertvalue instructions, + /// Create a sequence of N insertvalue instructions, /// with one Value from the retVals array each, that build a aggregate /// return value one value at a time, and a ret instruction to return /// the resulting aggregate value. @@ -778,12 +832,12 @@ public: return Insert(ReturnInst::Create(Context, V)); } - /// \brief Create an unconditional 'br label X' instruction. + /// Create an unconditional 'br label X' instruction. BranchInst *CreateBr(BasicBlock *Dest) { return Insert(BranchInst::Create(Dest)); } - /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' + /// Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights = nullptr, @@ -792,7 +846,7 @@ public: BranchWeights, Unpredictable)); } - /// \brief Create a conditional 'br Cond, TrueDest, FalseDest' + /// Create a conditional 'br Cond, TrueDest, FalseDest' /// instruction. Copy branch meta data if available. BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, Instruction *MDSrc) { @@ -805,7 +859,7 @@ public: return Insert(Br); } - /// \brief Create a switch instruction with the specified value, default dest, + /// Create a switch instruction with the specified value, default dest, /// and with a hint for the number of cases that will be added (for efficient /// allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10, @@ -815,14 +869,14 @@ public: BranchWeights, Unpredictable)); } - /// \brief Create an indirect branch instruction with the specified address + /// Create an indirect branch instruction with the specified address /// operand, with an optional hint for the number of destinations that will be /// added (for efficient allocation). IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { return Insert(IndirectBrInst::Create(Addr, NumDests)); } - /// \brief Create an invoke instruction. + /// Create an invoke instruction. InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef Args = None, @@ -1246,7 +1300,7 @@ public: return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name); } - /// \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of + /// Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of /// converting the string to 'bool' for the isVolatile parameter. LoadInst *CreateLoad(Value *Ptr, const char *Name) { return Insert(new LoadInst(Ptr), Name); @@ -1268,7 +1322,7 @@ public: return Insert(new StoreInst(Val, Ptr, isVolatile)); } - /// \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' + /// Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' /// correctly, instead of converting the string to 'bool' for the isVolatile /// parameter. LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) { @@ -1476,14 +1530,19 @@ public: return CreateConstInBoundsGEP2_32(Ty, Ptr, 0, Idx, Name); } - /// \brief Same as CreateGlobalString, but return a pointer with "i8*" type + Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { + return CreateConstInBoundsGEP2_32(nullptr, Ptr, 0, Idx, Name); + } + + /// Same as CreateGlobalString, but return a pointer with "i8*" type /// instead of a pointer to array of i8. - Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "", - unsigned AddressSpace = 0) { - GlobalVariable *gv = CreateGlobalString(Str, Name, AddressSpace); - Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); - Value *Args[] = { zero, zero }; - return CreateInBoundsGEP(gv->getValueType(), gv, Args, Name); + Constant *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "", + unsigned AddressSpace = 0) { + GlobalVariable *GV = CreateGlobalString(Str, Name, AddressSpace); + Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0); + Constant *Indices[] = {Zero, Zero}; + return ConstantExpr::getInBoundsGetElementPtr(GV->getValueType(), GV, + Indices); } //===--------------------------------------------------------------------===// @@ -1502,7 +1561,7 @@ public: return CreateCast(Instruction::SExt, V, DestTy, Name); } - /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Return + /// Create a ZExt or Trunc from the integer value V to DestTy. Return /// the value untouched if the type of V is already DestTy. Value *CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { @@ -1517,7 +1576,7 @@ public: return V; } - /// \brief Create a SExt or Trunc from the integer value V to DestTy. Return + /// Create a SExt or Trunc from the integer value V to DestTy. Return /// the value untouched if the type of V is already DestTy. Value *CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name = "") { @@ -1665,7 +1724,7 @@ public: return Insert(CastInst::CreateFPCast(V, DestTy), Name); } - // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a + // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a // compile time error, instead of converting the string to bool for the // isSigned parameter. Value *CreateIntCast(Value *, Type *, const char *) = delete; @@ -1927,19 +1986,19 @@ public: // Utility creation methods //===--------------------------------------------------------------------===// - /// \brief Return an i1 value testing if \p Arg is null. + /// Return an i1 value testing if \p Arg is null. Value *CreateIsNull(Value *Arg, const Twine &Name = "") { return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), Name); } - /// \brief Return an i1 value testing if \p Arg is not null. + /// Return an i1 value testing if \p Arg is not null. Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") { return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), Name); } - /// \brief Return the i64 difference between two pointer values, dividing out + /// Return the i64 difference between two pointer values, dividing out /// the size of the pointed-to objects. /// /// This is intended to implement C-style pointer subtraction. As such, the @@ -1957,35 +2016,33 @@ public: Name); } - /// \brief Create an invariant.group.barrier intrinsic call, that stops - /// optimizer to propagate equality using invariant.group metadata. - /// If Ptr type is different from pointer to i8, it's casted to pointer to i8 - /// in the same address space before call and casted back to Ptr type after - /// call. - Value *CreateInvariantGroupBarrier(Value *Ptr) { + /// Create a launder.invariant.group intrinsic call. If Ptr type is + /// different from pointer to i8, it's casted to pointer to i8 in the same + /// address space before call and casted back to Ptr type after call. + Value *CreateLaunderInvariantGroup(Value *Ptr) { assert(isa(Ptr->getType()) && - "invariant.group.barrier only applies to pointers."); + "launder.invariant.group only applies to pointers."); auto *PtrType = Ptr->getType(); auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace()); if (PtrType != Int8PtrTy) Ptr = CreateBitCast(Ptr, Int8PtrTy); Module *M = BB->getParent()->getParent(); - Function *FnInvariantGroupBarrier = Intrinsic::getDeclaration( - M, Intrinsic::invariant_group_barrier, {Int8PtrTy}); + Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration( + M, Intrinsic::launder_invariant_group, {Int8PtrTy}); - assert(FnInvariantGroupBarrier->getReturnType() == Int8PtrTy && - FnInvariantGroupBarrier->getFunctionType()->getParamType(0) == + assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy && + FnLaunderInvariantGroup->getFunctionType()->getParamType(0) == Int8PtrTy && - "InvariantGroupBarrier should take and return the same type"); + "LaunderInvariantGroup should take and return the same type"); - CallInst *Fn = CreateCall(FnInvariantGroupBarrier, {Ptr}); + CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr}); if (PtrType != Int8PtrTy) return CreateBitCast(Fn, PtrType); return Fn; } - /// \brief Return a vector value that contains \arg V broadcasted to \p + /// Return a vector value that contains \arg V broadcasted to \p /// NumElts elements. Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") { assert(NumElts > 0 && "Cannot splat to an empty vector!"); @@ -2001,7 +2058,7 @@ public: return CreateShuffleVector(V, Undef, Zeros, Name + ".splat"); } - /// \brief Return a value that has been extracted from a larger integer type. + /// Return a value that has been extracted from a larger integer type. Value *CreateExtractInteger(const DataLayout &DL, Value *From, IntegerType *ExtractedTy, uint64_t Offset, const Twine &Name) { @@ -2026,7 +2083,7 @@ public: } private: - /// \brief Helper function that creates an assume intrinsic call that + /// Helper function that creates an assume intrinsic call that /// represents an alignment assumption on the provided Ptr, Mask, Type /// and Offset. CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL, @@ -2055,7 +2112,7 @@ private: } public: - /// \brief Create an assume intrinsic call that represents an alignment + /// Create an assume intrinsic call that represents an alignment /// assumption on the provided pointer. /// /// An optional offset can be provided, and if it is provided, the offset @@ -2074,7 +2131,7 @@ public: OffsetValue); } - /// \brief Create an assume intrinsic call that represents an alignment + /// Create an assume intrinsic call that represents an alignment /// assumption on the provided pointer. /// /// An optional offset can be provided, and if it is provided, the offset diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h index 0825e0696cac46af924c9a4418e4c14f2e5d8485..e4ac5d4d88a362c8bbbdfe5c43b03c4e89946957 100644 --- a/include/llvm/IR/IRPrintingPasses.h +++ b/include/llvm/IR/IRPrintingPasses.h @@ -23,6 +23,7 @@ #include namespace llvm { +class Pass; class BasicBlockPass; class Function; class FunctionPass; @@ -32,18 +33,18 @@ class PreservedAnalyses; class raw_ostream; template class AnalysisManager; -/// \brief Create and return a pass that writes the module to the specified +/// Create and return a pass that writes the module to the specified /// \c raw_ostream. ModulePass *createPrintModulePass(raw_ostream &OS, const std::string &Banner = "", bool ShouldPreserveUseListOrder = false); -/// \brief Create and return a pass that prints functions to the specified +/// Create and return a pass that prints functions to the specified /// \c raw_ostream as they are processed. FunctionPass *createPrintFunctionPass(raw_ostream &OS, const std::string &Banner = ""); -/// \brief Create and return a pass that writes the BB to the specified +/// Create and return a pass that writes the BB to the specified /// \c raw_ostream. BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS, const std::string &Banner = ""); @@ -54,7 +55,10 @@ BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS, /// non-printable characters in it. void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name); -/// \brief Pass for printing a Module as LLVM's text IR assembly. +/// Return true if a pass is for IR printing. +bool isIRPrintingPass(Pass *P); + +/// Pass for printing a Module as LLVM's text IR assembly. /// /// Note: This pass is for use with the new pass manager. Use the create...Pass /// functions above to create passes for use with the legacy pass manager. @@ -73,7 +77,7 @@ public: static StringRef name() { return "PrintModulePass"; } }; -/// \brief Pass for printing a Function as LLVM's text IR assembly. +/// Pass for printing a Function as LLVM's text IR assembly. /// /// Note: This pass is for use with the new pass manager. Use the create...Pass /// functions above to create passes for use with the legacy pass manager. diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h index 55579819fd34f4b3917c46d0ee2cbc8e2c20eb40..65074025a0832d48550a23d06877f39ac0fcd295 100644 --- a/include/llvm/IR/InstVisitor.h +++ b/include/llvm/IR/InstVisitor.h @@ -32,7 +32,7 @@ namespace llvm { visit##CLASS_TO_VISIT(static_cast(I)) -/// @brief Base class for instruction visitors +/// Base class for instruction visitors /// /// Instruction visitors are used when you want to perform different actions /// for different kinds of instructions without having to use lots of casts @@ -213,6 +213,7 @@ public: // Handle the special instrinsic instruction classes. RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);} RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);} + RetTy visitDbgLabelInst(DbgLabelInst &I) { DELEGATE(DbgInfoIntrinsic);} RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); } RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); } RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); } @@ -272,6 +273,7 @@ private: default: DELEGATE(IntrinsicInst); case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst); case Intrinsic::dbg_value: DELEGATE(DbgValueInst); + case Intrinsic::dbg_label: DELEGATE(DbgLabelInst); case Intrinsic::memcpy: DELEGATE(MemCpyInst); case Intrinsic::memmove: DELEGATE(MemMoveInst); case Intrinsic::memset: DELEGATE(MemSetInst); diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 0243c4cb1746ff3d79a4cc1f7874c8ccb4e0134c..ad0012048ac936a516a4b78a77099aed59e094b2 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -81,7 +81,7 @@ public: return isa(V) && classof(cast(V)); } - // \brief Returns true if this terminator relates to exception handling. + // Returns true if this terminator relates to exception handling. bool isExceptional() const { switch (getOpcode()) { case Instruction::CatchSwitch: @@ -118,7 +118,7 @@ public: return idx < TermInst->getNumSuccessors(); } - /// \brief Proxy object to allow write access in operator[] + /// Proxy object to allow write access in operator[] class SuccessorProxy { Self it; @@ -588,16 +588,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) /// can be performed with code like: /// /// if (isa(Instr)) { ... } -/// @brief Base class of casting instructions. +/// Base class of casting instructions. class CastInst : public UnaryInstruction { protected: - /// @brief Constructor with insert-before-instruction semantics for subclasses + /// Constructor with insert-before-instruction semantics for subclasses CastInst(Type *Ty, unsigned iType, Value *S, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) : UnaryInstruction(Ty, iType, S, InsertBefore) { setName(NameStr); } - /// @brief Constructor with insert-at-end-of-block semantics for subclasses + /// Constructor with insert-at-end-of-block semantics for subclasses CastInst(Type *Ty, unsigned iType, Value *S, const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, iType, S, InsertAtEnd) { @@ -610,7 +610,7 @@ public: /// CastOps category (Instruction::isCast(opcode) returns true). This /// constructor has insert-before-instruction semantics to automatically /// insert the new CastInst before InsertBefore (if it is non-null). - /// @brief Construct any of the CastInst subclasses + /// Construct any of the CastInst subclasses static CastInst *Create( Instruction::CastOps, ///< The opcode of the cast instruction Value *S, ///< The value to be casted (operand 0) @@ -623,7 +623,7 @@ public: /// CastOps category. This constructor has insert-at-end-of-block semantics /// to automatically insert the new CastInst at the end of InsertAtEnd (if /// its non-null). - /// @brief Construct any of the CastInst subclasses + /// Construct any of the CastInst subclasses static CastInst *Create( Instruction::CastOps, ///< The opcode for the cast instruction Value *S, ///< The value to be casted (operand 0) @@ -632,7 +632,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a ZExt or BitCast cast instruction + /// Create a ZExt or BitCast cast instruction static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -640,7 +640,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a ZExt or BitCast cast instruction + /// Create a ZExt or BitCast cast instruction static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -648,7 +648,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a SExt or BitCast cast instruction + /// Create a SExt or BitCast cast instruction static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -656,7 +656,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a SExt or BitCast cast instruction + /// Create a SExt or BitCast cast instruction static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -664,7 +664,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction. + /// Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction. static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -672,7 +672,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction. + /// Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction. static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -680,7 +680,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + /// Create a BitCast or an AddrSpaceCast cast instruction. static CastInst *CreatePointerBitCastOrAddrSpaceCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -688,7 +688,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + /// Create a BitCast or an AddrSpaceCast cast instruction. static CastInst *CreatePointerBitCastOrAddrSpaceCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -696,7 +696,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a BitCast, a PtrToInt, or an IntToPTr cast instruction. + /// Create a BitCast, a PtrToInt, or an IntToPTr cast instruction. /// /// If the value is a pointer type and the destination an integer type, /// creates a PtrToInt cast. If the value is an integer type and the @@ -709,7 +709,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. + /// Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -718,7 +718,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. + /// Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The integer value to be casted (operand 0) Type *Ty, ///< The integer type to which operand is casted @@ -727,7 +727,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts + /// Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( Value *S, ///< The floating point value to be casted Type *Ty, ///< The floating point type to cast to @@ -735,7 +735,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts + /// Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( Value *S, ///< The floating point value to be casted Type *Ty, ///< The floating point type to cast to @@ -743,7 +743,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a Trunc or BitCast cast instruction + /// Create a Trunc or BitCast cast instruction static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -751,7 +751,7 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); - /// @brief Create a Trunc or BitCast cast instruction + /// Create a Trunc or BitCast cast instruction static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -759,19 +759,19 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Check whether it is valid to call getCastOpcode for these types. + /// Check whether it is valid to call getCastOpcode for these types. static bool isCastable( Type *SrcTy, ///< The Type from which the value should be cast. Type *DestTy ///< The Type to which the value should be cast. ); - /// @brief Check whether a bitcast between these types is valid + /// Check whether a bitcast between these types is valid static bool isBitCastable( Type *SrcTy, ///< The Type from which the value should be cast. Type *DestTy ///< The Type to which the value should be cast. ); - /// @brief Check whether a bitcast, inttoptr, or ptrtoint cast between these + /// Check whether a bitcast, inttoptr, or ptrtoint cast between these /// types is valid and a no-op. /// /// This ensures that any pointer<->integer cast has enough bits in the @@ -783,7 +783,7 @@ public: /// Returns the opcode necessary to cast Val into Ty using usual casting /// rules. - /// @brief Infer the opcode for cast operand and type + /// Infer the opcode for cast operand and type static Instruction::CastOps getCastOpcode( const Value *Val, ///< The value to cast bool SrcIsSigned, ///< Whether to treat the source as signed @@ -795,14 +795,14 @@ public: /// only deals with integer source and destination types. To simplify that /// logic, this method is provided. /// @returns true iff the cast has only integral typed operand and dest type. - /// @brief Determine if this is an integer-only cast. + /// Determine if this is an integer-only cast. bool isIntegerCast() const; /// A lossless cast is one that does not alter the basic value. It implies /// a no-op cast but is more stringent, preventing things like int->float, /// long->double, or int->ptr. /// @returns true iff the cast is lossless. - /// @brief Determine if this is a lossless cast. + /// Determine if this is a lossless cast. bool isLosslessCast() const; /// A no-op cast is one that can be effected without changing any bits. @@ -811,7 +811,7 @@ public: /// involving Integer and Pointer types. They are no-op casts if the integer /// is the same size as the pointer. However, pointer size varies with /// platform. - /// @brief Determine if the described cast is a no-op cast. + /// Determine if the described cast is a no-op cast. static bool isNoopCast( Instruction::CastOps Opcode, ///< Opcode of cast Type *SrcTy, ///< SrcTy of cast @@ -819,7 +819,7 @@ public: const DataLayout &DL ///< DataLayout to get the Int Ptr type from. ); - /// @brief Determine if this cast is a no-op cast. + /// Determine if this cast is a no-op cast. /// /// \param DL is the DataLayout to determine pointer size. bool isNoopCast(const DataLayout &DL) const; @@ -829,7 +829,7 @@ public: /// @returns 0 if the CastInst pair can't be eliminated, otherwise /// returns Instruction::CastOps value for a cast that can replace /// the pair, casting SrcTy to DstTy. - /// @brief Determine if a cast pair is eliminable + /// Determine if a cast pair is eliminable static unsigned isEliminableCastPair( Instruction::CastOps firstOpcode, ///< Opcode of first cast Instruction::CastOps secondOpcode, ///< Opcode of second cast @@ -841,23 +841,23 @@ public: Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null ); - /// @brief Return the opcode of this CastInst + /// Return the opcode of this CastInst Instruction::CastOps getOpcode() const { return Instruction::CastOps(Instruction::getOpcode()); } - /// @brief Return the source type, as a convenience + /// Return the source type, as a convenience Type* getSrcTy() const { return getOperand(0)->getType(); } - /// @brief Return the destination type, as a convenience + /// Return the destination type, as a convenience Type* getDestTy() const { return getType(); } /// This method can be used to determine if a cast from S to DstTy using /// Opcode op is valid or not. /// @returns true iff the proposed cast is valid. - /// @brief Determine if a cast is valid without creating one. + /// Determine if a cast is valid without creating one. static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->isCast(); } @@ -871,7 +871,7 @@ public: //===----------------------------------------------------------------------===// /// This class is the base class for the comparison instructions. -/// @brief Abstract base class of comparison instructions. +/// Abstract base class of comparison instructions. class CmpInst : public Instruction { public: /// This enumeration lists the possible predicates for CmpInst subclasses. @@ -937,7 +937,7 @@ public: /// the two operands. Optionally (if InstBefore is specified) insert the /// instruction into a BasicBlock right before the specified instruction. /// The specified Instruction is allowed to be a dereferenced end iterator. - /// @brief Create a CmpInst + /// Create a CmpInst static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name = "", @@ -946,21 +946,21 @@ public: /// Construct a compare instruction, given the opcode, the predicate and the /// two operands. Also automatically insert this instruction to the end of /// the BasicBlock specified. - /// @brief Create a CmpInst + /// Create a CmpInst static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); - /// @brief Get the opcode casted to the right type + /// Get the opcode casted to the right type OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } - /// @brief Return the predicate for this instruction. + /// Return the predicate for this instruction. Predicate getPredicate() const { return Predicate(getSubclassDataFromInstruction()); } - /// @brief Set the predicate for this instruction to the specified value. + /// Set the predicate for this instruction to the specified value. void setPredicate(Predicate P) { setInstructionSubclassData(P); } static bool isFPPredicate(Predicate P) { @@ -979,7 +979,7 @@ public: /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. /// @returns the inverse predicate for the instruction's current predicate. - /// @brief Return the inverse of the instruction's predicate. + /// Return the inverse of the instruction's predicate. Predicate getInversePredicate() const { return getInversePredicate(getPredicate()); } @@ -987,7 +987,7 @@ public: /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. /// @returns the inverse predicate for predicate provided in \p pred. - /// @brief Return the inverse of a given predicate + /// Return the inverse of a given predicate static Predicate getInversePredicate(Predicate pred); /// For example, EQ->EQ, SLE->SGE, ULT->UGT, @@ -995,14 +995,14 @@ public: /// @returns the predicate that would be the result of exchanging the two /// operands of the CmpInst instruction without changing the result /// produced. - /// @brief Return the predicate as if the operands were swapped + /// Return the predicate as if the operands were swapped Predicate getSwappedPredicate() const { return getSwappedPredicate(getPredicate()); } /// This is a static version that you can use without an instruction /// available. - /// @brief Return the predicate as if the operands were swapped. + /// Return the predicate as if the operands were swapped. static Predicate getSwappedPredicate(Predicate pred); /// For predicate of kind "is X or equal to 0" returns the predicate "is X". @@ -1010,18 +1010,18 @@ public: /// does not support other kind of predicates. /// @returns the predicate that does not contains is equal to zero if /// it had and vice versa. - /// @brief Return the flipped strictness of predicate + /// Return the flipped strictness of predicate Predicate getFlippedStrictnessPredicate() const { return getFlippedStrictnessPredicate(getPredicate()); } /// This is a static version that you can use without an instruction /// available. - /// @brief Return the flipped strictness of predicate + /// Return the flipped strictness of predicate static Predicate getFlippedStrictnessPredicate(Predicate pred); /// For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE. - /// @brief Returns the non-strict version of strict comparisons. + /// Returns the non-strict version of strict comparisons. Predicate getNonStrictPredicate() const { return getNonStrictPredicate(getPredicate()); } @@ -1030,74 +1030,74 @@ public: /// available. /// @returns the non-strict version of comparison provided in \p pred. /// If \p pred is not a strict comparison predicate, returns \p pred. - /// @brief Returns the non-strict version of strict comparisons. + /// Returns the non-strict version of strict comparisons. static Predicate getNonStrictPredicate(Predicate pred); - /// @brief Provide more efficient getOperand methods. + /// Provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// This is just a convenience that dispatches to the subclasses. - /// @brief Swap the operands and adjust predicate accordingly to retain + /// Swap the operands and adjust predicate accordingly to retain /// the same comparison. void swapOperands(); /// This is just a convenience that dispatches to the subclasses. - /// @brief Determine if this CmpInst is commutative. + /// Determine if this CmpInst is commutative. bool isCommutative() const; /// This is just a convenience that dispatches to the subclasses. - /// @brief Determine if this is an equals/not equals predicate. + /// Determine if this is an equals/not equals predicate. bool isEquality() const; /// @returns true if the comparison is signed, false otherwise. - /// @brief Determine if this instruction is using a signed comparison. + /// Determine if this instruction is using a signed comparison. bool isSigned() const { return isSigned(getPredicate()); } /// @returns true if the comparison is unsigned, false otherwise. - /// @brief Determine if this instruction is using an unsigned comparison. + /// Determine if this instruction is using an unsigned comparison. bool isUnsigned() const { return isUnsigned(getPredicate()); } /// For example, ULT->SLT, ULE->SLE, UGT->SGT, UGE->SGE, SLT->Failed assert /// @returns the signed version of the unsigned predicate pred. - /// @brief return the signed version of a predicate + /// return the signed version of a predicate static Predicate getSignedPredicate(Predicate pred); /// For example, ULT->SLT, ULE->SLE, UGT->SGT, UGE->SGE, SLT->Failed assert /// @returns the signed version of the predicate for this instruction (which /// has to be an unsigned predicate). - /// @brief return the signed version of a predicate + /// return the signed version of a predicate Predicate getSignedPredicate() { return getSignedPredicate(getPredicate()); } /// This is just a convenience. - /// @brief Determine if this is true when both operands are the same. + /// Determine if this is true when both operands are the same. bool isTrueWhenEqual() const { return isTrueWhenEqual(getPredicate()); } /// This is just a convenience. - /// @brief Determine if this is false when both operands are the same. + /// Determine if this is false when both operands are the same. bool isFalseWhenEqual() const { return isFalseWhenEqual(getPredicate()); } /// @returns true if the predicate is unsigned, false otherwise. - /// @brief Determine if the predicate is an unsigned operation. + /// Determine if the predicate is an unsigned operation. static bool isUnsigned(Predicate predicate); /// @returns true if the predicate is signed, false otherwise. - /// @brief Determine if the predicate is an signed operation. + /// Determine if the predicate is an signed operation. static bool isSigned(Predicate predicate); - /// @brief Determine if the predicate is an ordered operation. + /// Determine if the predicate is an ordered operation. static bool isOrdered(Predicate predicate); - /// @brief Determine if the predicate is an unordered operation. + /// Determine if the predicate is an unordered operation. static bool isUnordered(Predicate predicate); /// Determine if the predicate is true when comparing a value with itself. @@ -1114,7 +1114,7 @@ public: /// operands. static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2); - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp || I->getOpcode() == Instruction::FCmp; @@ -1123,7 +1123,7 @@ public: return isa(V) && classof(cast(V)); } - /// @brief Create a result type for fcmp/icmp + /// Create a result type for fcmp/icmp static Type* makeCmpResultType(Type* opnd_type) { if (VectorType* vt = dyn_cast(opnd_type)) { return VectorType::get(Type::getInt1Ty(opnd_type->getContext()), @@ -1181,7 +1181,7 @@ public: /// Convenience accessors - /// \brief Return the outer EH-pad this funclet is nested within. + /// Return the outer EH-pad this funclet is nested within. /// /// Note: This returns the associated CatchSwitchInst if this FuncletPadInst /// is a CatchPadInst. @@ -1217,7 +1217,7 @@ struct OperandTraits DEFINE_TRANSPARENT_OPERAND_ACCESSORS(FuncletPadInst, Value) -/// \brief A lightweight accessor for an operand bundle meant to be passed +/// A lightweight accessor for an operand bundle meant to be passed /// around by value. struct OperandBundleUse { ArrayRef Inputs; @@ -1226,7 +1226,7 @@ struct OperandBundleUse { explicit OperandBundleUse(StringMapEntry *Tag, ArrayRef Inputs) : Inputs(Inputs), Tag(Tag) {} - /// \brief Return true if the operand at index \p Idx in this operand bundle + /// Return true if the operand at index \p Idx in this operand bundle /// has the attribute A. bool operandHasAttr(unsigned Idx, Attribute::AttrKind A) const { if (isDeoptOperandBundle()) @@ -1237,12 +1237,12 @@ struct OperandBundleUse { return false; } - /// \brief Return the tag of this operand bundle as a string. + /// Return the tag of this operand bundle as a string. StringRef getTagName() const { return Tag->getKey(); } - /// \brief Return the tag of this operand bundle as an integer. + /// Return the tag of this operand bundle as an integer. /// /// Operand bundle tags are interned by LLVMContextImpl::getOrInsertBundleTag, /// and this function returns the unique integer getOrInsertBundleTag @@ -1251,22 +1251,22 @@ struct OperandBundleUse { return Tag->getValue(); } - /// \brief Return true if this is a "deopt" operand bundle. + /// Return true if this is a "deopt" operand bundle. bool isDeoptOperandBundle() const { return getTagID() == LLVMContext::OB_deopt; } - /// \brief Return true if this is a "funclet" operand bundle. + /// Return true if this is a "funclet" operand bundle. bool isFuncletOperandBundle() const { return getTagID() == LLVMContext::OB_funclet; } private: - /// \brief Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag. + /// Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag. StringMapEntry *Tag; }; -/// \brief A container for an operand bundle being viewed as a set of values +/// A container for an operand bundle being viewed as a set of values /// rather than a set of uses. /// /// Unlike OperandBundleUse, OperandBundleDefT owns the memory it carries, and @@ -1301,7 +1301,7 @@ public: using OperandBundleDef = OperandBundleDefT; using ConstOperandBundleDef = OperandBundleDefT; -/// \brief A mixin to add operand bundle functionality to llvm instruction +/// A mixin to add operand bundle functionality to llvm instruction /// classes. /// /// OperandBundleUser uses the descriptor area co-allocated with the host User @@ -1349,21 +1349,21 @@ using ConstOperandBundleDef = OperandBundleDefT; /// Currently operand bundle users with hung-off operands are not supported. template class OperandBundleUser { public: - /// \brief Return the number of operand bundles associated with this User. + /// Return the number of operand bundles associated with this User. unsigned getNumOperandBundles() const { return std::distance(bundle_op_info_begin(), bundle_op_info_end()); } - /// \brief Return true if this User has any operand bundles. + /// Return true if this User has any operand bundles. bool hasOperandBundles() const { return getNumOperandBundles() != 0; } - /// \brief Return the index of the first bundle operand in the Use array. + /// Return the index of the first bundle operand in the Use array. unsigned getBundleOperandsStartIndex() const { assert(hasOperandBundles() && "Don't call otherwise!"); return bundle_op_info_begin()->Begin; } - /// \brief Return the index of the last bundle operand in the Use array. + /// Return the index of the last bundle operand in the Use array. unsigned getBundleOperandsEndIndex() const { assert(hasOperandBundles() && "Don't call otherwise!"); return bundle_op_info_end()[-1].End; @@ -1375,7 +1375,7 @@ public: Idx < getBundleOperandsEndIndex(); } - /// \brief Return the total number operands (not operand bundles) used by + /// Return the total number operands (not operand bundles) used by /// every operand bundle in this OperandBundleUser. unsigned getNumTotalBundleOperands() const { if (!hasOperandBundles()) @@ -1388,13 +1388,13 @@ public: return End - Begin; } - /// \brief Return the operand bundle at a specific index. + /// Return the operand bundle at a specific index. OperandBundleUse getOperandBundleAt(unsigned Index) const { assert(Index < getNumOperandBundles() && "Index out of bounds!"); return operandBundleFromBundleOpInfo(*(bundle_op_info_begin() + Index)); } - /// \brief Return the number of operand bundles with the tag Name attached to + /// Return the number of operand bundles with the tag Name attached to /// this instruction. unsigned countOperandBundlesOfType(StringRef Name) const { unsigned Count = 0; @@ -1405,7 +1405,7 @@ public: return Count; } - /// \brief Return the number of operand bundles with the tag ID attached to + /// Return the number of operand bundles with the tag ID attached to /// this instruction. unsigned countOperandBundlesOfType(uint32_t ID) const { unsigned Count = 0; @@ -1416,7 +1416,7 @@ public: return Count; } - /// \brief Return an operand bundle by name, if present. + /// Return an operand bundle by name, if present. /// /// It is an error to call this for operand bundle types that may have /// multiple instances of them on the same instruction. @@ -1432,7 +1432,7 @@ public: return None; } - /// \brief Return an operand bundle by tag ID, if present. + /// Return an operand bundle by tag ID, if present. /// /// It is an error to call this for operand bundle types that may have /// multiple instances of them on the same instruction. @@ -1448,7 +1448,7 @@ public: return None; } - /// \brief Return the list of operand bundles attached to this instruction as + /// Return the list of operand bundles attached to this instruction as /// a vector of OperandBundleDefs. /// /// This function copies the OperandBundeUse instances associated with this @@ -1460,7 +1460,7 @@ public: Defs.emplace_back(getOperandBundleAt(i)); } - /// \brief Return the operand bundle for the operand at index OpIdx. + /// Return the operand bundle for the operand at index OpIdx. /// /// It is an error to call this with an OpIdx that does not correspond to an /// bundle operand. @@ -1468,7 +1468,7 @@ public: return operandBundleFromBundleOpInfo(getBundleOpInfoForOperand(OpIdx)); } - /// \brief Return true if this operand bundle user has operand bundles that + /// Return true if this operand bundle user has operand bundles that /// may read from the heap. bool hasReadingOperandBundles() const { // Implementation note: this is a conservative implementation of operand @@ -1477,7 +1477,7 @@ public: return hasOperandBundles(); } - /// \brief Return true if this operand bundle user has operand bundles that + /// Return true if this operand bundle user has operand bundles that /// may write to the heap. bool hasClobberingOperandBundles() const { for (auto &BOI : bundle_op_infos()) { @@ -1493,7 +1493,7 @@ public: return false; } - /// \brief Return true if the bundle operand at index \p OpIdx has the + /// Return true if the bundle operand at index \p OpIdx has the /// attribute \p A. bool bundleOperandHasAttr(unsigned OpIdx, Attribute::AttrKind A) const { auto &BOI = getBundleOpInfoForOperand(OpIdx); @@ -1501,7 +1501,7 @@ public: return OBU.operandHasAttr(OpIdx - BOI.Begin, A); } - /// \brief Return true if \p Other has the same sequence of operand bundle + /// Return true if \p Other has the same sequence of operand bundle /// tags with the same number of operands on each one of them as this /// OperandBundleUser. bool hasIdenticalOperandBundleSchema( @@ -1513,7 +1513,7 @@ public: Other.bundle_op_info_begin()); } - /// \brief Return true if this operand bundle user contains operand bundles + /// Return true if this operand bundle user contains operand bundles /// with tags other than those specified in \p IDs. bool hasOperandBundlesOtherThan(ArrayRef IDs) const { for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i) { @@ -1525,7 +1525,7 @@ public: } protected: - /// \brief Is the function attribute S disallowed by some operand bundle on + /// Is the function attribute S disallowed by some operand bundle on /// this operand bundle user? bool isFnAttrDisallowedByOpBundle(StringRef S) const { // Operand bundles only possibly disallow readnone, readonly and argmenonly @@ -1533,7 +1533,7 @@ protected: return false; } - /// \brief Is the function attribute A disallowed by some operand bundle on + /// Is the function attribute A disallowed by some operand bundle on /// this operand bundle user? bool isFnAttrDisallowedByOpBundle(Attribute::AttrKind A) const { switch (A) { @@ -1559,18 +1559,18 @@ protected: llvm_unreachable("switch has a default case!"); } - /// \brief Used to keep track of an operand bundle. See the main comment on + /// Used to keep track of an operand bundle. See the main comment on /// OperandBundleUser above. struct BundleOpInfo { - /// \brief The operand bundle tag, interned by + /// The operand bundle tag, interned by /// LLVMContextImpl::getOrInsertBundleTag. StringMapEntry *Tag; - /// \brief The index in the Use& vector where operands for this operand + /// The index in the Use& vector where operands for this operand /// bundle starts. uint32_t Begin; - /// \brief The index in the Use& vector where operands for this operand + /// The index in the Use& vector where operands for this operand /// bundle ends. uint32_t End; @@ -1579,7 +1579,7 @@ protected: } }; - /// \brief Simple helper function to map a BundleOpInfo to an + /// Simple helper function to map a BundleOpInfo to an /// OperandBundleUse. OperandBundleUse operandBundleFromBundleOpInfo(const BundleOpInfo &BOI) const { @@ -1591,7 +1591,7 @@ protected: using bundle_op_iterator = BundleOpInfo *; using const_bundle_op_iterator = const BundleOpInfo *; - /// \brief Return the start of the list of BundleOpInfo instances associated + /// Return the start of the list of BundleOpInfo instances associated /// with this OperandBundleUser. bundle_op_iterator bundle_op_info_begin() { if (!static_cast(this)->hasDescriptor()) @@ -1601,7 +1601,7 @@ protected: return reinterpret_cast(BytesBegin); } - /// \brief Return the start of the list of BundleOpInfo instances associated + /// Return the start of the list of BundleOpInfo instances associated /// with this OperandBundleUser. const_bundle_op_iterator bundle_op_info_begin() const { auto *NonConstThis = @@ -1609,7 +1609,7 @@ protected: return NonConstThis->bundle_op_info_begin(); } - /// \brief Return the end of the list of BundleOpInfo instances associated + /// Return the end of the list of BundleOpInfo instances associated /// with this OperandBundleUser. bundle_op_iterator bundle_op_info_end() { if (!static_cast(this)->hasDescriptor()) @@ -1619,7 +1619,7 @@ protected: return reinterpret_cast(BytesEnd); } - /// \brief Return the end of the list of BundleOpInfo instances associated + /// Return the end of the list of BundleOpInfo instances associated /// with this OperandBundleUser. const_bundle_op_iterator bundle_op_info_end() const { auto *NonConstThis = @@ -1627,17 +1627,17 @@ protected: return NonConstThis->bundle_op_info_end(); } - /// \brief Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). + /// Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). iterator_range bundle_op_infos() { return make_range(bundle_op_info_begin(), bundle_op_info_end()); } - /// \brief Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). + /// Return the range [\p bundle_op_info_begin, \p bundle_op_info_end). iterator_range bundle_op_infos() const { return make_range(bundle_op_info_begin(), bundle_op_info_end()); } - /// \brief Populate the BundleOpInfo instances and the Use& vector from \p + /// Populate the BundleOpInfo instances and the Use& vector from \p /// Bundles. Return the op_iterator pointing to the Use& one past the last /// last bundle operand use. /// @@ -1668,7 +1668,7 @@ protected: return It; } - /// \brief Return the BundleOpInfo for the operand at index OpIdx. + /// Return the BundleOpInfo for the operand at index OpIdx. /// /// It is an error to call this with an OpIdx that does not correspond to an /// bundle operand. @@ -1680,7 +1680,7 @@ protected: llvm_unreachable("Did not find operand bundle for operand!"); } - /// \brief Return the total number of values used in \p Bundles. + /// Return the total number of values used in \p Bundles. static unsigned CountBundleInputs(ArrayRef Bundles) { unsigned Total = 0; for (auto &B : Bundles) diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 76bc4010d8c8b9d4f66e76b17719157af5ff383f..dddea3e11f7de3ddad3a83f4c750758dba29e81d 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -590,7 +590,7 @@ public: /// be identical. /// @returns true if the specified instruction is the same operation as /// the current one. - /// @brief Determine if one instruction is the same operation as another. + /// Determine if one instruction is the same operation as another. bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const; /// Return true if there are any uses of this instruction in blocks other than diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 6c15d5d62d7fafdfb2498e55581bb962f4be524b..59a19034f329b76d315f4524cf896a4631ecc587 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1719,7 +1719,7 @@ public: return Attrs.getDereferenceableOrNullBytes(i); } - /// @brief Determine if the return value is marked with NoAlias attribute. + /// Determine if the return value is marked with NoAlias attribute. bool returnDoesNotAlias() const { return Attrs.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); } @@ -1763,7 +1763,7 @@ public: addAttribute(AttributeList::FunctionIndex, Attribute::WriteOnly); } - /// @brief Determine if the call can access memmory only using pointers based + /// Determine if the call can access memmory only using pointers based /// on its arguments. bool onlyAccessesArgMemory() const { return hasFnAttr(Attribute::ArgMemOnly); @@ -1772,7 +1772,7 @@ public: addAttribute(AttributeList::FunctionIndex, Attribute::ArgMemOnly); } - /// @brief Determine if the function may only access memory that is + /// Determine if the function may only access memory that is /// inaccessible from the IR. bool onlyAccessesInaccessibleMemory() const { return hasFnAttr(Attribute::InaccessibleMemOnly); @@ -1781,7 +1781,7 @@ public: addAttribute(AttributeList::FunctionIndex, Attribute::InaccessibleMemOnly); } - /// @brief Determine if the function may only access memory that is + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const { return hasFnAttr(Attribute::InaccessibleMemOrArgMemOnly); diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index 80d428c014070a69bf0df6c7c5562fd4538595e5..2592d43819df854a6bed903334e4e60dec9deeed 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -100,6 +100,7 @@ namespace llvm { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: case Intrinsic::dbg_addr: + case Intrinsic::dbg_label: return true; default: return false; } @@ -159,6 +160,32 @@ namespace llvm { /// @} }; + /// This represents the llvm.dbg.label instruction. + class DbgLabelInst : public DbgInfoIntrinsic { + public: + DILabel *getLabel() const { + return cast(getRawVariable()); + } + + Metadata *getRawVariable() const { + return cast(getArgOperand(0))->getMetadata(); + } + + Metadata *getRawExpression() const { + return nullptr; + } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + /// @{ + static bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::dbg_label; + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + /// @} + }; + /// This is the common base class for constrained floating point intrinsics. class ConstrainedFPIntrinsic : public IntrinsicInst { public: @@ -266,6 +293,71 @@ namespace llvm { } }; + /// Common base class for all memory transfer intrinsics. Simply provides + /// common methods. + template class MemTransferBase : public BaseCL { + private: + enum { ARG_SOURCE = 1 }; + + public: + /// Return the arguments to the instruction. + Value *getRawSource() const { + return const_cast(BaseCL::getArgOperand(ARG_SOURCE)); + } + const Use &getRawSourceUse() const { + return BaseCL::getArgOperandUse(ARG_SOURCE); + } + Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } + + /// This is just like getRawSource, but it strips off any cast + /// instructions that feed it, giving the original input. The returned + /// value is guaranteed to be a pointer. + Value *getSource() const { return getRawSource()->stripPointerCasts(); } + + unsigned getSourceAddressSpace() const { + return cast(getRawSource()->getType())->getAddressSpace(); + } + + unsigned getSourceAlignment() const { + return BaseCL::getParamAlignment(ARG_SOURCE); + } + + void setSource(Value *Ptr) { + assert(getRawSource()->getType() == Ptr->getType() && + "setSource called with pointer of wrong type!"); + BaseCL::setArgOperand(ARG_SOURCE, Ptr); + } + + void setSourceAlignment(unsigned Align) { + BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); + if (Align > 0) + BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( + BaseCL::getContext(), Align)); + } + }; + + /// Common base class for all memset intrinsics. Simply provides + /// common methods. + template class MemSetBase : public BaseCL { + private: + enum { ARG_VALUE = 1 }; + + public: + Value *getValue() const { + return const_cast(BaseCL::getArgOperand(ARG_VALUE)); + } + const Use &getValueUse() const { + return BaseCL::getArgOperandUse(ARG_VALUE); + } + Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } + + void setValue(Value *Val) { + assert(getValue()->getType() == Val->getType() && + "setValue called with value of wrong type!"); + BaseCL::setArgOperand(ARG_VALUE, Val); + } + }; + // The common base class for the atomic memset/memmove/memcpy intrinsics // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove class AtomicMemIntrinsic : public MemIntrinsicBase { @@ -308,23 +400,8 @@ namespace llvm { /// This class represents atomic memset intrinsic // i.e. llvm.element.unordered.atomic.memset - class AtomicMemSetInst : public AtomicMemIntrinsic { - private: - enum { ARG_VALUE = 1 }; - + class AtomicMemSetInst : public MemSetBase { public: - Value *getValue() const { - return const_cast(getArgOperand(ARG_VALUE)); - } - const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); } - Use &getValueUse() { return getArgOperandUse(ARG_VALUE); } - - void setValue(Value *Val) { - assert(getValue()->getType() == Val->getType() && - "setValue called with value of wrong type!"); - setArgOperand(ARG_VALUE, Val); - } - static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; } @@ -335,44 +412,8 @@ namespace llvm { // This class wraps the atomic memcpy/memmove intrinsics // i.e. llvm.element.unordered.atomic.memcpy/memmove - class AtomicMemTransferInst : public AtomicMemIntrinsic { - private: - enum { ARG_SOURCE = 1 }; - + class AtomicMemTransferInst : public MemTransferBase { public: - /// Return the arguments to the instruction. - Value *getRawSource() const { - return const_cast(getArgOperand(ARG_SOURCE)); - } - const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); } - Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); } - - /// This is just like getRawSource, but it strips off any cast - /// instructions that feed it, giving the original input. The returned - /// value is guaranteed to be a pointer. - Value *getSource() const { return getRawSource()->stripPointerCasts(); } - - unsigned getSourceAddressSpace() const { - return cast(getRawSource()->getType())->getAddressSpace(); - } - - unsigned getSourceAlignment() const { - return getParamAlignment(ARG_SOURCE); - } - - void setSource(Value *Ptr) { - assert(getRawSource()->getType() == Ptr->getType() && - "setSource called with pointer of wrong type!"); - setArgOperand(ARG_SOURCE, Ptr); - } - - void setSourceAlignment(unsigned Align) { - removeParamAttr(ARG_SOURCE, Attribute::Alignment); - if (Align > 0) - addParamAttr(ARG_SOURCE, - Attribute::getWithAlignment(getContext(), Align)); - } - static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memcpy_element_unordered_atomic: @@ -444,19 +485,8 @@ namespace llvm { }; /// This class wraps the llvm.memset intrinsic. - class MemSetInst : public MemIntrinsic { + class MemSetInst : public MemSetBase { public: - /// Return the arguments to the instruction. - Value *getValue() const { return const_cast(getArgOperand(1)); } - const Use &getValueUse() const { return getArgOperandUse(1); } - Use &getValueUse() { return getArgOperandUse(1); } - - void setValue(Value *Val) { - assert(getValue()->getType() == Val->getType() && - "setValue called with value of wrong type!"); - setArgOperand(1, Val); - } - // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memset; @@ -467,42 +497,8 @@ namespace llvm { }; /// This class wraps the llvm.memcpy/memmove intrinsics. - class MemTransferInst : public MemIntrinsic { - private: - enum { ARG_SOURCE = 1 }; - + class MemTransferInst : public MemTransferBase { public: - /// Return the arguments to the instruction. - Value *getRawSource() const { return const_cast(getArgOperand(ARG_SOURCE)); } - const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); } - Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); } - - /// This is just like getRawSource, but it strips off any cast - /// instructions that feed it, giving the original input. The returned - /// value is guaranteed to be a pointer. - Value *getSource() const { return getRawSource()->stripPointerCasts(); } - - unsigned getSourceAddressSpace() const { - return cast(getRawSource()->getType())->getAddressSpace(); - } - - unsigned getSourceAlignment() const { - return getParamAlignment(ARG_SOURCE); - } - - void setSource(Value *Ptr) { - assert(getRawSource()->getType() == Ptr->getType() && - "setSource called with pointer of wrong type!"); - setArgOperand(ARG_SOURCE, Ptr); - } - - void setSourceAlignment(unsigned Align) { - removeParamAttr(ARG_SOURCE, Attribute::Alignment); - if (Align > 0) - addParamAttr(ARG_SOURCE, - Attribute::getWithAlignment(getContext(), Align)); - } - // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy || @@ -571,23 +567,8 @@ namespace llvm { /// This class represents any memset intrinsic // i.e. llvm.element.unordered.atomic.memset // and llvm.memset - class AnyMemSetInst : public AnyMemIntrinsic { - private: - enum { ARG_VALUE = 1 }; - + class AnyMemSetInst : public MemSetBase { public: - Value *getValue() const { - return const_cast(getArgOperand(ARG_VALUE)); - } - const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); } - Use &getValueUse() { return getArgOperandUse(ARG_VALUE); } - - void setValue(Value *Val) { - assert(getValue()->getType() == Val->getType() && - "setValue called with value of wrong type!"); - setArgOperand(ARG_VALUE, Val); - } - static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memset: @@ -605,44 +586,8 @@ namespace llvm { // This class wraps any memcpy/memmove intrinsics // i.e. llvm.element.unordered.atomic.memcpy/memmove // and llvm.memcpy/memmove - class AnyMemTransferInst : public AnyMemIntrinsic { - private: - enum { ARG_SOURCE = 1 }; - + class AnyMemTransferInst : public MemTransferBase { public: - /// Return the arguments to the instruction. - Value *getRawSource() const { - return const_cast(getArgOperand(ARG_SOURCE)); - } - const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); } - Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); } - - /// This is just like getRawSource, but it strips off any cast - /// instructions that feed it, giving the original input. The returned - /// value is guaranteed to be a pointer. - Value *getSource() const { return getRawSource()->stripPointerCasts(); } - - unsigned getSourceAddressSpace() const { - return cast(getRawSource()->getType())->getAddressSpace(); - } - - unsigned getSourceAlignment() const { - return getParamAlignment(ARG_SOURCE); - } - - void setSource(Value *Ptr) { - assert(getRawSource()->getType() == Ptr->getType() && - "setSource called with pointer of wrong type!"); - setArgOperand(ARG_SOURCE, Ptr); - } - - void setSourceAlignment(unsigned Align) { - removeParamAttr(ARG_SOURCE, Attribute::Alignment); - if (Align > 0) - addParamAttr(ARG_SOURCE, - Attribute::getWithAlignment(getContext(), Align)); - } - static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memcpy: diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index fc79da7ae0e66b5acfd45b2dd085a523a87ce22d..d47c91fd6b9f02a61104fe34b10502079c4a3cf9 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/include/llvm/IR/Intrinsics.h @@ -39,7 +39,7 @@ namespace Intrinsic { // Get the intrinsic enums generated from Intrinsics.td #define GET_INTRINSIC_ENUM_VALUES -#include "llvm/IR/Intrinsics.gen" +#include "llvm/IR/Intrinsics.inc" #undef GET_INTRINSIC_ENUM_VALUES , num_intrinsics }; diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index fbb1c5c3fe605e5f223402719394fed4784d5a6f..22c26298566dc24820b2e5ba183689d894b0fce9 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -117,6 +117,7 @@ def IntrHasSideEffects : IntrinsicProperty; class LLVMType { ValueType VT = vt; + int isAny = 0; } class LLVMQualPointerType @@ -131,6 +132,8 @@ class LLVMPointerType class LLVMAnyPointerType : LLVMType{ LLVMType ElTy = elty; + + let isAny = 1; } // Match the type of another intrinsic parameter. Number is an index into the @@ -163,10 +166,12 @@ class LLVMVectorOfAnyPointersToElt : LLVMMatchType; class LLVMHalfElementsVectorType : LLVMMatchType; def llvm_void_ty : LLVMType; -def llvm_any_ty : LLVMType; -def llvm_anyint_ty : LLVMType; -def llvm_anyfloat_ty : LLVMType; -def llvm_anyvector_ty : LLVMType; +let isAny = 1 in { + def llvm_any_ty : LLVMType; + def llvm_anyint_ty : LLVMType; + def llvm_anyfloat_ty : LLVMType; + def llvm_anyvector_ty : LLVMType; +} def llvm_i1_ty : LLVMType; def llvm_i8_ty : LLVMType; def llvm_i16_ty : LLVMType; @@ -249,7 +254,6 @@ def llvm_v8f64_ty : LLVMType; // 8 x double def llvm_vararg_ty : LLVMType; // this means vararg here - //===----------------------------------------------------------------------===// // Intrinsic Definitions. //===----------------------------------------------------------------------===// @@ -595,6 +599,8 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { [llvm_metadata_ty, llvm_metadata_ty, llvm_metadata_ty]>; + def int_dbg_label : Intrinsic<[], + [llvm_metadata_ty]>; } //===------------------ Exception Handling Intrinsics----------------------===// @@ -706,16 +712,21 @@ def int_invariant_end : Intrinsic<[], llvm_anyptr_ty], [IntrArgMemOnly, NoCapture<2>]>; -// invariant.group.barrier can't be marked with 'readnone' (IntrNoMem), +// launder.invariant.group can't be marked with 'readnone' (IntrNoMem), // because it would cause CSE of two barriers with the same argument. -// Readonly and argmemonly says that barrier only reads its argument and -// it can be CSE only if memory didn't change between 2 barriers call, -// which is valid. +// Inaccessiblememonly says that the barrier doesn't read the argument, +// but it changes state not accessible to this module. This way +// we can DSE through the barrier because it doesn't read the value +// after store. Although the barrier doesn't modify any memory it +// can't be marked as readonly, because it would be possible to +// CSE 2 barriers with store in between. // The argument also can't be marked with 'returned' attribute, because // it would remove barrier. -def int_invariant_group_barrier : Intrinsic<[llvm_anyptr_ty], +// Note that it is still experimental, which means that its semantics +// might change in the future. +def int_launder_invariant_group : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>], - [IntrReadMem, IntrArgMemOnly]>; + [IntrInaccessibleMemOnly, IntrSpeculatable]>; //===------------------------ Stackmap Intrinsics -------------------------===// // @@ -768,6 +779,7 @@ def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>; def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; +def int_coro_noop : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; def int_coro_size : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>; def int_coro_save : Intrinsic<[llvm_token_ty], [llvm_ptr_ty], []>; @@ -887,6 +899,10 @@ def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty], // Takes a pointer to a string and the length of the string. def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [NoCapture<0>, ReadOnly<0>, IntrWriteMem]>; +// Typed event logging for x-ray. +// Takes a numeric type tag, a pointer to a string and the length of the string. +def int_xray_typedevent : Intrinsic<[], [llvm_i16_ty, llvm_ptr_ty, llvm_i32_ty], + [NoCapture<1>, ReadOnly<1>, IntrWriteMem]>; //===----------------------------------------------------------------------===// //===------ Memory intrinsics with element-wise atomicity guarantees ------===// diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td index 50341338c39930b9b2e6db07ba698cee4a4974b8..994671419cdd909038dc0db8a787b80b74d24915 100644 --- a/include/llvm/IR/IntrinsicsAArch64.td +++ b/include/llvm/IR/IntrinsicsAArch64.td @@ -149,6 +149,11 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". class AdvSIMD_1Arg_Intrinsic : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrNoMem]>; + + class AdvSIMD_Dot_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>], + [IntrNoMem]>; } // Arithmetic ops @@ -415,6 +420,10 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in { // Scalar FP Inexact Narrowing def int_aarch64_sisd_fcvtxn : Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>; + + // v8.2-A Dot Product + def int_aarch64_neon_udot : AdvSIMD_Dot_Intrinsic; + def int_aarch64_neon_sdot : AdvSIMD_Dot_Intrinsic; } let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.". diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 408ab023656782dabb4a0fa172fee4059f13e94b..b5f2285c0db5d6f28956c8e83522ddd1fd5a6259 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -17,6 +17,13 @@ class AMDGPUReadPreloadRegisterIntrinsic class AMDGPUReadPreloadRegisterIntrinsicNamed : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>, GCCBuiltin; +// Used to tag image and resource intrinsics with information used to generate +// mem operands. +class AMDGPURsrcIntrinsic { + int RsrcArg = rsrcarg; + bit IsImage = isimage; +} + let TargetPrefix = "r600" in { multiclass AMDGPUReadPreloadRegisterIntrinsic_xyz { @@ -69,6 +76,59 @@ def int_r600_cube : Intrinsic< [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable] >; +def int_r600_store_stream_output : Intrinsic< + [], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [] +>; + +class TextureIntrinsicFloatInput : Intrinsic<[llvm_v4f32_ty], [ + llvm_v4f32_ty, // Coord + llvm_i32_ty, // offset_x + llvm_i32_ty, // offset_y, + llvm_i32_ty, // offset_z, + llvm_i32_ty, // resource_id + llvm_i32_ty, // samplerid + llvm_i32_ty, // coord_type_x + llvm_i32_ty, // coord_type_y + llvm_i32_ty, // coord_type_z + llvm_i32_ty], // coord_type_w + [IntrNoMem] +>; + +class TextureIntrinsicInt32Input : Intrinsic<[llvm_v4i32_ty], [ + llvm_v4i32_ty, // Coord + llvm_i32_ty, // offset_x + llvm_i32_ty, // offset_y, + llvm_i32_ty, // offset_z, + llvm_i32_ty, // resource_id + llvm_i32_ty, // samplerid + llvm_i32_ty, // coord_type_x + llvm_i32_ty, // coord_type_y + llvm_i32_ty, // coord_type_z + llvm_i32_ty], // coord_type_w + [IntrNoMem] +>; + +def int_r600_store_swizzle : + Intrinsic<[], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], [] +>; + +def int_r600_tex : TextureIntrinsicFloatInput; +def int_r600_texc : TextureIntrinsicFloatInput; +def int_r600_txl : TextureIntrinsicFloatInput; +def int_r600_txlc : TextureIntrinsicFloatInput; +def int_r600_txb : TextureIntrinsicFloatInput; +def int_r600_txbc : TextureIntrinsicFloatInput; +def int_r600_txf : TextureIntrinsicInt32Input; +def int_r600_txq : TextureIntrinsicInt32Input; +def int_r600_ddx : TextureIntrinsicFloatInput; +def int_r600_ddy : TextureIntrinsicFloatInput; + +def int_r600_dot4 : Intrinsic<[llvm_float_ty], + [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable] +>; + +def int_r600_kill : Intrinsic<[], [llvm_float_ty], []>; + } // End TargetPrefix = "r600" let TargetPrefix = "amdgcn" in { @@ -326,9 +386,11 @@ class AMDGPULDSF32Intrin : [IntrArgMemOnly, NoCapture<0>] >; -def int_amdgcn_ds_fadd : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fadd">; -def int_amdgcn_ds_fmin : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fmin">; -def int_amdgcn_ds_fmax : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fmax">; +def int_amdgcn_ds_fadd : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_faddf">; +def int_amdgcn_ds_fmin : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fminf">; +def int_amdgcn_ds_fmax : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fmaxf">; + +defset list AMDGPUImageIntrinsics = { class AMDGPUImageLoad : Intrinsic < [llvm_anyfloat_ty], // vdata(VGPR) @@ -340,7 +402,8 @@ class AMDGPUImageLoad : Intrinsic < llvm_i1_ty, // lwe(imm) llvm_i1_ty], // da(imm) !if(NoMem, [IntrNoMem], [IntrReadMem]), "", - !if(NoMem, [], [SDNPMemOperand])>; + !if(NoMem, [], [SDNPMemOperand])>, + AMDGPURsrcIntrinsic<1, 1>; def int_amdgcn_image_load : AMDGPUImageLoad; def int_amdgcn_image_load_mip : AMDGPUImageLoad; @@ -356,7 +419,8 @@ class AMDGPUImageStore : Intrinsic < llvm_i1_ty, // slc(imm) llvm_i1_ty, // lwe(imm) llvm_i1_ty], // da(imm) - [IntrWriteMem], "", [SDNPMemOperand]>; + [IntrWriteMem], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<2, 1>; def int_amdgcn_image_store : AMDGPUImageStore; def int_amdgcn_image_store_mip : AMDGPUImageStore; @@ -373,7 +437,8 @@ class AMDGPUImageSample : Intrinsic < llvm_i1_ty, // lwe(imm) llvm_i1_ty], // da(imm) !if(NoMem, [IntrNoMem], [IntrReadMem]), "", - !if(NoMem, [], [SDNPMemOperand])>; + !if(NoMem, [], [SDNPMemOperand])>, + AMDGPURsrcIntrinsic<1, 1>; // Basic sample def int_amdgcn_image_sample : AMDGPUImageSample; @@ -465,7 +530,8 @@ class AMDGPUImageAtomic : Intrinsic < llvm_i1_ty, // r128(imm) llvm_i1_ty, // da(imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>; + [], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<2, 1>; def int_amdgcn_image_atomic_swap : AMDGPUImageAtomic; def int_amdgcn_image_atomic_add : AMDGPUImageAtomic; @@ -488,7 +554,390 @@ def int_amdgcn_image_atomic_cmpswap : Intrinsic < llvm_i1_ty, // r128(imm) llvm_i1_ty, // da(imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>; + [], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<3, 1>; + +} // defset AMDGPUImageIntrinsics + +} // TargetPrefix = "amdgcn" + +// New-style image intrinsics + +////////////////////////////////////////////////////////////////////////// +// Dimension-aware image intrinsics framework +////////////////////////////////////////////////////////////////////////// + +// Helper class to represent (type, name) combinations of arguments. The +// argument names are explanatory and used as DAG operand names for codegen +// pattern matching. +class AMDGPUArg { + LLVMType Type = ty; + string Name = name; +} + +// Return [AMDGPUArg, AMDGPUArg, names[1]>, ...] +class makeArgList names, LLVMType basety> { + list ret = + !listconcat([AMDGPUArg], + !foreach(name, !tail(names), AMDGPUArg, name>)); +} + +// Return arglist, with LLVMMatchType's references shifted by 'shift'. +class arglistmatchshift arglist, int shift> { + list ret = + !foreach(arg, arglist, + !if(!isa(arg.Type), + AMDGPUArg(arg.Type).Number, shift)>, + arg.Name>, + arg)); +} + +// Return the concatenation of the given arglists. LLVMMatchType's are adjusted +// accordingly, and shifted by an additional 'shift'. +class arglistconcat> arglists, int shift = 0> { + list ret = + !foldl([], arglists, lhs, rhs, + !listconcat( + lhs, + arglistmatchshift.ret)); +} + +// Represent texture/image types / dimensionality. +class AMDGPUDimProps coord_names, list slice_names> { + string Name = name; // e.g. "2darraymsaa" + bit DA = 0; // DA bit in MIMG encoding + + list CoordSliceArgs = + makeArgList.ret; + list CoordSliceIntArgs = + makeArgList.ret; + list GradientArgs = + makeArgList.ret; +} + +def AMDGPUDim1D : AMDGPUDimProps<"1d", ["s"], []>; +def AMDGPUDim2D : AMDGPUDimProps<"2d", ["s", "t"], []>; +def AMDGPUDim3D : AMDGPUDimProps<"3d", ["s", "t", "r"], []>; +let DA = 1 in { + def AMDGPUDimCube : AMDGPUDimProps<"cube", ["s", "t"], ["face"]>; + def AMDGPUDim1DArray : AMDGPUDimProps<"1darray", ["s"], ["slice"]>; + def AMDGPUDim2DArray : AMDGPUDimProps<"2darray", ["s", "t"], ["slice"]>; +} +def AMDGPUDim2DMsaa : AMDGPUDimProps<"2dmsaa", ["s", "t"], ["fragid"]>; +let DA = 1 in { + def AMDGPUDim2DArrayMsaa : AMDGPUDimProps<"2darraymsaa", ["s", "t"], ["slice", "fragid"]>; +} + +def AMDGPUDims { + list NoMsaa = [AMDGPUDim1D, AMDGPUDim2D, AMDGPUDim3D, + AMDGPUDimCube, AMDGPUDim1DArray, + AMDGPUDim2DArray]; + list Msaa = [AMDGPUDim2DMsaa, AMDGPUDim2DArrayMsaa]; + list All = !listconcat(NoMsaa, Msaa); +} + +// Represent sample variants, i.e. _C, _O, _B, ... and combinations thereof. +class AMDGPUSampleVariant extra_addr> { + string UpperCaseMod = ucmod; + string LowerCaseMod = lcmod; + + // {offset} {bias} {z-compare} + list ExtraAddrArgs = extra_addr; + bit Gradients = 0; + + // Name of the {lod} or {clamp} argument that is appended to the coordinates, + // if any. + string LodOrClamp = ""; +} + +// AMDGPUSampleVariants: all variants supported by IMAGE_SAMPLE +// AMDGPUSampleVariantsNoGradients: variants supported by IMAGE_GATHER4 +defset list AMDGPUSampleVariants = { + multiclass AMDGPUSampleHelper_Offset extra_addr> { + def NAME#lcmod : AMDGPUSampleVariant; + def NAME#lcmod#_o : AMDGPUSampleVariant< + ucmod#"_O", lcmod#"_o", !listconcat([AMDGPUArg], extra_addr)>; + } + + multiclass AMDGPUSampleHelper_Compare extra_addr> { + defm NAME : AMDGPUSampleHelper_Offset; + defm NAME : AMDGPUSampleHelper_Offset< + "_C"#ucmod, "_c"#lcmod, !listconcat(extra_addr, [AMDGPUArg])>; + } + + multiclass AMDGPUSampleHelper_Clamp extra_addr> { + defm NAME : AMDGPUSampleHelper_Compare; + let LodOrClamp = "clamp" in + defm NAME : AMDGPUSampleHelper_Compare; + } + + defset list AMDGPUSampleVariantsNoGradients = { + defm AMDGPUSample : AMDGPUSampleHelper_Clamp<"", "", []>; + defm AMDGPUSample : AMDGPUSampleHelper_Clamp< + "_B", "_b", [AMDGPUArg]>; + let LodOrClamp = "lod" in + defm AMDGPUSample : AMDGPUSampleHelper_Compare<"_L", "_l", []>; + defm AMDGPUSample : AMDGPUSampleHelper_Compare<"_LZ", "_lz", []>; + } + + let Gradients = 1 in { + defm AMDGPUSample : AMDGPUSampleHelper_Clamp<"_D", "_d", []>; + defm AMDGPUSample : AMDGPUSampleHelper_Clamp<"_CD", "_cd", []>; + } +} + +// Helper class to capture the profile of a dimension-aware image intrinsic. +// This information is used to generate the intrinsic's type and to inform +// codegen pattern matching. +class AMDGPUDimProfile { + AMDGPUDimProps Dim = dim; + string OpMod = opmod; // the corresponding instruction is named IMAGE_OpMod + + // These are entended to be overwritten by subclasses + bit IsSample = 0; + bit IsAtomic = 0; + list RetTypes = []; + list DataArgs = []; + list ExtraAddrArgs = []; + bit Gradients = 0; + string LodClampMip = ""; + + int NumRetAndDataAnyTypes = + !foldl(0, !listconcat(RetTypes, !foreach(arg, DataArgs, arg.Type)), a, b, + !add(a, b.isAny)); + + list AddrArgs = + arglistconcat<[ExtraAddrArgs, + !if(Gradients, dim.GradientArgs, []), + !listconcat(!if(IsSample, dim.CoordSliceArgs, dim.CoordSliceIntArgs), + !if(!eq(LodClampMip, ""), + [], + [AMDGPUArg, LodClampMip>]))], + NumRetAndDataAnyTypes>.ret; + list AddrTypes = !foreach(arg, AddrArgs, arg.Type); + list AddrDefaultArgs = + !foreach(arg, AddrArgs, + AMDGPUArg(arg.Type)), + !if(IsSample, llvm_float_ty, llvm_i32_ty), arg.Type), + arg.Name>); + list AddrA16Args = + !foreach(arg, AddrArgs, + AMDGPUArg(arg.Type)), + !if(IsSample, llvm_half_ty, llvm_i16_ty), arg.Type), + arg.Name>); +} + +class AMDGPUDimProfileCopy : AMDGPUDimProfile { + let IsSample = base.IsSample; + let IsAtomic = base.IsAtomic; + let RetTypes = base.RetTypes; + let DataArgs = base.DataArgs; + let ExtraAddrArgs = base.ExtraAddrArgs; + let Gradients = base.Gradients; + let LodClampMip = base.LodClampMip; +} + +class AMDGPUDimSampleProfile : AMDGPUDimProfile { + let IsSample = 1; + let RetTypes = [llvm_anyfloat_ty]; + let ExtraAddrArgs = sample.ExtraAddrArgs; + let Gradients = sample.Gradients; + let LodClampMip = sample.LodOrClamp; +} + +class AMDGPUDimNoSampleProfile retty, + list dataargs, + bit Mip = 0> : AMDGPUDimProfile { + let RetTypes = retty; + let DataArgs = dataargs; + let LodClampMip = !if(Mip, "mip", ""); +} + +class AMDGPUDimAtomicProfile dataargs> : AMDGPUDimProfile { + let RetTypes = [llvm_anyint_ty]; + let DataArgs = dataargs; + let IsAtomic = 1; +} + +class AMDGPUDimGetResInfoProfile : AMDGPUDimProfile<"GET_RESINFO", dim> { + let RetTypes = [llvm_anyfloat_ty]; + let DataArgs = []; + let AddrArgs = [AMDGPUArg]; + let LodClampMip = "mip"; +} + +// All dimension-aware intrinsics are derived from this class. +class AMDGPUImageDimIntrinsic props, + list sdnodeprops> : Intrinsic< + P_.RetTypes, // vdata(VGPR) -- for load/atomic-with-return + !listconcat( + !foreach(arg, P_.DataArgs, arg.Type), // vdata(VGPR) -- for store/atomic + !if(P_.IsAtomic, [], [llvm_i32_ty]), // dmask(imm) + P_.AddrTypes, // vaddr(VGPR) + [llvm_v8i32_ty], // rsrc(SGPR) + !if(P_.IsSample, [llvm_v4i32_ty, // samp(SGPR) + llvm_i1_ty], []), // unorm(imm) + [llvm_i32_ty, // texfailctrl(imm; bit 0 = tfe, bit 1 = lwe) + llvm_i32_ty]), // cachepolicy(imm; bit 0 = glc, bit 1 = slc) + props, "", sdnodeprops>, + AMDGPURsrcIntrinsic { + AMDGPUDimProfile P = P_; + + let TargetPrefix = "amdgcn"; +} + +defset list AMDGPUImageDimIntrinsics = { + + ////////////////////////////////////////////////////////////////////////// + // Load and store intrinsics + ////////////////////////////////////////////////////////////////////////// + multiclass AMDGPUImageDimIntrinsicsNoMsaa retty, + list dataargs, + list props, + list sdnodeprops, + bit Mip = 0> { + foreach dim = AMDGPUDims.NoMsaa in { + def !strconcat(NAME, "_", dim.Name) + : AMDGPUImageDimIntrinsic< + AMDGPUDimNoSampleProfile, + props, sdnodeprops>; + } + } + + multiclass AMDGPUImageDimIntrinsicsAll retty, + list dataargs, + list props, + list sdnodeprops, + bit Mip = 0> { + foreach dim = AMDGPUDims.All in { + def !strconcat(NAME, "_", dim.Name) + : AMDGPUImageDimIntrinsic< + AMDGPUDimNoSampleProfile, + props, sdnodeprops>; + } + } + + defm int_amdgcn_image_load : AMDGPUImageDimIntrinsicsAll< + "LOAD", [llvm_anyfloat_ty], [], [IntrReadMem], [SDNPMemOperand]>; + defm int_amdgcn_image_load_mip : AMDGPUImageDimIntrinsicsNoMsaa< + "LOAD_MIP", [llvm_anyfloat_ty], [], [IntrReadMem], [SDNPMemOperand], 1>; + + defm int_amdgcn_image_store : AMDGPUImageDimIntrinsicsAll< + "STORE", [], [AMDGPUArg], + [IntrWriteMem], [SDNPMemOperand]>; + defm int_amdgcn_image_store_mip : AMDGPUImageDimIntrinsicsNoMsaa< + "STORE_MIP", [], [AMDGPUArg], + [IntrWriteMem], [SDNPMemOperand], 1>; + + ////////////////////////////////////////////////////////////////////////// + // sample and getlod intrinsics + ////////////////////////////////////////////////////////////////////////// + multiclass AMDGPUImageDimSampleDims { + foreach dim = AMDGPUDims.NoMsaa in { + def !strconcat(NAME, "_", dim.Name) : AMDGPUImageDimIntrinsic< + AMDGPUDimSampleProfile, + !if(NoMem, [IntrNoMem], [IntrReadMem]), + !if(NoMem, [], [SDNPMemOperand])>; + } + } + + foreach sample = AMDGPUSampleVariants in { + defm int_amdgcn_image_sample # sample.LowerCaseMod : + AMDGPUImageDimSampleDims<"SAMPLE" # sample.UpperCaseMod, sample>; + } + + defm int_amdgcn_image_getlod : AMDGPUImageDimSampleDims<"GET_LOD", AMDGPUSample, 1>; +} + +////////////////////////////////////////////////////////////////////////// +// getresinfo intrinsics (separate due to D16) +////////////////////////////////////////////////////////////////////////// +defset list AMDGPUImageDimGetResInfoIntrinsics = { + foreach dim = AMDGPUDims.All in { + def !strconcat("int_amdgcn_image_getresinfo_", dim.Name) + : AMDGPUImageDimIntrinsic, [IntrNoMem], []>; + } +} + +////////////////////////////////////////////////////////////////////////// +// gather4 intrinsics +////////////////////////////////////////////////////////////////////////// +defset list AMDGPUImageDimGatherIntrinsics = { + foreach sample = AMDGPUSampleVariantsNoGradients in { + foreach dim = [AMDGPUDim2D, AMDGPUDimCube, AMDGPUDim2DArray] in { + def int_amdgcn_image_gather4 # sample.LowerCaseMod # _ # dim.Name: + AMDGPUImageDimIntrinsic< + AMDGPUDimSampleProfile<"GATHER4" # sample.UpperCaseMod, dim, sample>, + [IntrReadMem], [SDNPMemOperand]>; + } + } +} + +////////////////////////////////////////////////////////////////////////// +// atomic intrinsics +////////////////////////////////////////////////////////////////////////// +defset list AMDGPUImageDimAtomicIntrinsics = { + multiclass AMDGPUImageDimAtomicX dataargs> { + foreach dim = AMDGPUDims.All in { + def !strconcat(NAME, "_", dim.Name) + : AMDGPUImageDimIntrinsic< + AMDGPUDimAtomicProfile, + [], [SDNPMemOperand]>; + } + } + + multiclass AMDGPUImageDimAtomic { + defm "" : AMDGPUImageDimAtomicX, "vdata">]>; + } + + defm int_amdgcn_image_atomic_swap : AMDGPUImageDimAtomic<"ATOMIC_SWAP">; + defm int_amdgcn_image_atomic_add : AMDGPUImageDimAtomic<"ATOMIC_ADD">; + defm int_amdgcn_image_atomic_sub : AMDGPUImageDimAtomic<"ATOMIC_SUB">; + defm int_amdgcn_image_atomic_smin : AMDGPUImageDimAtomic<"ATOMIC_SMIN">; + defm int_amdgcn_image_atomic_umin : AMDGPUImageDimAtomic<"ATOMIC_UMIN">; + defm int_amdgcn_image_atomic_smax : AMDGPUImageDimAtomic<"ATOMIC_SMAX">; + defm int_amdgcn_image_atomic_umax : AMDGPUImageDimAtomic<"ATOMIC_UMAX">; + defm int_amdgcn_image_atomic_and : AMDGPUImageDimAtomic<"ATOMIC_AND">; + defm int_amdgcn_image_atomic_or : AMDGPUImageDimAtomic<"ATOMIC_OR">; + defm int_amdgcn_image_atomic_xor : AMDGPUImageDimAtomic<"ATOMIC_XOR">; + + // TODO: INC/DEC are weird: they seem to have a vdata argument in hardware, + // even though it clearly shouldn't be needed + defm int_amdgcn_image_atomic_inc : AMDGPUImageDimAtomic<"ATOMIC_INC">; + defm int_amdgcn_image_atomic_dec : AMDGPUImageDimAtomic<"ATOMIC_DEC">; + + defm int_amdgcn_image_atomic_cmpswap : + AMDGPUImageDimAtomicX<"ATOMIC_CMPSWAP", [AMDGPUArg, "src">, + AMDGPUArg, "cmp">]>; +} + +////////////////////////////////////////////////////////////////////////// +// Buffer intrinsics +////////////////////////////////////////////////////////////////////////// + +let TargetPrefix = "amdgcn" in { + +defset list AMDGPUBufferIntrinsics = { class AMDGPUBufferLoad : Intrinsic < [llvm_anyfloat_ty], @@ -497,7 +946,8 @@ class AMDGPUBufferLoad : Intrinsic < llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrReadMem], "", [SDNPMemOperand]>; + [IntrReadMem], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<0>; def int_amdgcn_buffer_load_format : AMDGPUBufferLoad; def int_amdgcn_buffer_load : AMDGPUBufferLoad; @@ -509,7 +959,8 @@ class AMDGPUBufferStore : Intrinsic < llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrWriteMem], "", [SDNPMemOperand]>; + [IntrWriteMem], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<1>; def int_amdgcn_buffer_store_format : AMDGPUBufferStore; def int_amdgcn_buffer_store : AMDGPUBufferStore; @@ -524,7 +975,8 @@ def int_amdgcn_tbuffer_load : Intrinsic < llvm_i32_ty, // nfmt(imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrReadMem], "", [SDNPMemOperand]>; + [IntrReadMem], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<0>; def int_amdgcn_tbuffer_store : Intrinsic < [], @@ -538,7 +990,8 @@ def int_amdgcn_tbuffer_store : Intrinsic < llvm_i32_ty, // nfmt(imm) llvm_i1_ty, // glc(imm) llvm_i1_ty], // slc(imm) - [IntrWriteMem], "", [SDNPMemOperand]>; + [IntrWriteMem], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<1>; class AMDGPUBufferAtomic : Intrinsic < [llvm_i32_ty], @@ -547,7 +1000,8 @@ class AMDGPUBufferAtomic : Intrinsic < llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>; + [], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<1, 0>; def int_amdgcn_buffer_atomic_swap : AMDGPUBufferAtomic; def int_amdgcn_buffer_atomic_add : AMDGPUBufferAtomic; def int_amdgcn_buffer_atomic_sub : AMDGPUBufferAtomic; @@ -566,7 +1020,10 @@ def int_amdgcn_buffer_atomic_cmpswap : Intrinsic< llvm_i32_ty, // vindex(VGPR) llvm_i32_ty, // offset(SGPR/VGPR/imm) llvm_i1_ty], // slc(imm) - [], "", [SDNPMemOperand]>; + [], "", [SDNPMemOperand]>, + AMDGPURsrcIntrinsic<2, 0>; + +} // defset AMDGPUBufferIntrinsics // Uses that do not set the done bit should set IntrWriteMem on the // call site. @@ -879,6 +1336,109 @@ def int_amdgcn_ds_bpermute : GCCBuiltin<"__builtin_amdgcn_ds_bpermute">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>; +//===----------------------------------------------------------------------===// +// Deep learning intrinsics. +//===----------------------------------------------------------------------===// + +// f32 %r = llvm.amdgcn.fdot2(v2f16 %a, v2f16 %b, f32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %c +def int_amdgcn_fdot2 : + GCCBuiltin<"__builtin_amdgcn_fdot2">, + Intrinsic< + [llvm_float_ty], // %r + [ + llvm_v2f16_ty, // %a + llvm_v2f16_ty, // %b + llvm_float_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// i32 %r = llvm.amdgcn.sdot2(v2i16 %a, v2i16 %b, i32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %c +def int_amdgcn_sdot2 : + GCCBuiltin<"__builtin_amdgcn_sdot2">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_v2i16_ty, // %a + llvm_v2i16_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// u32 %r = llvm.amdgcn.udot2(v2u16 %a, v2u16 %b, u32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %c +def int_amdgcn_udot2 : + GCCBuiltin<"__builtin_amdgcn_udot2">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_v2i16_ty, // %a + llvm_v2i16_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// i32 %r = llvm.amdgcn.sdot4(v4i8 (as i32) %a, v4i8 (as i32) %b, i32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %a[2] * %b[2] + %a[3] * %b[3] + %c +def int_amdgcn_sdot4 : + GCCBuiltin<"__builtin_amdgcn_sdot4">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_i32_ty, // %a + llvm_i32_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// u32 %r = llvm.amdgcn.udot4(v4u8 (as u32) %a, v4u8 (as u32) %b, u32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %a[2] * %b[2] + %a[3] * %b[3] + %c +def int_amdgcn_udot4 : + GCCBuiltin<"__builtin_amdgcn_udot4">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_i32_ty, // %a + llvm_i32_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// i32 %r = llvm.amdgcn.sdot8(v8i4 (as i32) %a, v8i4 (as i32) %b, i32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %a[2] * %b[2] + %a[3] * %b[3] + +// %a[4] * %b[4] + %a[5] * %b[5] + %a[6] * %b[6] + %a[7] * %b[7] + %c +def int_amdgcn_sdot8 : + GCCBuiltin<"__builtin_amdgcn_sdot8">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_i32_ty, // %a + llvm_i32_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; + +// u32 %r = llvm.amdgcn.udot8(v8u4 (as u32) %a, v8u4 (as u32) %b, u32 %c) +// %r = %a[0] * %b[0] + %a[1] * %b[1] + %a[2] * %b[2] + %a[3] * %b[3] + +// %a[4] * %b[4] + %a[5] * %b[5] + %a[6] * %b[6] + %a[7] * %b[7] + %c +def int_amdgcn_udot8 : + GCCBuiltin<"__builtin_amdgcn_udot8">, + Intrinsic< + [llvm_i32_ty], // %r + [ + llvm_i32_ty, // %a + llvm_i32_ty, // %b + llvm_i32_ty // %c + ], + [IntrNoMem, IntrSpeculatable] + >; //===----------------------------------------------------------------------===// // Special Intrinsics for backend internal use only. No frontend diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index fe3861301689a6850eb83e3a80b4f2b62671e5d0..29fdb6ab07f5ca89ad753861b0f1b84057da02f1 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -369,6 +369,10 @@ class Neon_3Arg_Long_Intrinsic : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMTruncatedType<0>, LLVMTruncatedType<0>], [IntrNoMem]>; + +class Neon_1FloatArg_Intrinsic + : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + class Neon_CvtFxToFP_Intrinsic : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>; class Neon_CvtFPToFx_Intrinsic @@ -591,8 +595,8 @@ def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic; def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic; def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic; -// Vector Rounding -def int_arm_neon_vrintn : Neon_1Arg_Intrinsic; +// Vector and Scalar Rounding. +def int_arm_neon_vrintn : Neon_1FloatArg_Intrinsic; def int_arm_neon_vrintx : Neon_1Arg_Intrinsic; def int_arm_neon_vrinta : Neon_1Arg_Intrinsic; def int_arm_neon_vrintz : Neon_1Arg_Intrinsic; @@ -616,6 +620,18 @@ def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, [llvm_anyptr_ty, llvm_i32_ty], [IntrReadMem, IntrArgMemOnly]>; +def int_arm_neon_vld1x2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], + [LLVMAnyPointerType>], + [IntrReadMem, IntrArgMemOnly]>; +def int_arm_neon_vld1x3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>], + [LLVMAnyPointerType>], + [IntrReadMem, IntrArgMemOnly]>; +def int_arm_neon_vld1x4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, + LLVMMatchType<0>, LLVMMatchType<0>], + [LLVMAnyPointerType>], + [IntrReadMem, IntrArgMemOnly]>; + // Vector load N-element structure to one lane. // Source operands are: the address, the N input vectors (since only one // lane is assigned), the lane number, and the alignment. @@ -713,4 +729,14 @@ def int_arm_neon_sha256h: SHA_3Arg_v4i32_Intrinsic; def int_arm_neon_sha256h2: SHA_3Arg_v4i32_Intrinsic; def int_arm_neon_sha256su1: SHA_3Arg_v4i32_Intrinsic; +// Armv8.2-A dot product instructions +class Neon_Dot_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty, + LLVMMatchType<1>], + [IntrNoMem]>; +def int_arm_neon_udot : Neon_Dot_Intrinsic; +def int_arm_neon_sdot : Neon_Dot_Intrinsic; + + } // end TargetPrefix diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td index 609aebdd5d2d91c358008f40967eda671525df50..7f694f68969e651618c8f0f0eca21cfc6ebb98f5 100644 --- a/include/llvm/IR/IntrinsicsNVVM.td +++ b/include/llvm/IR/IntrinsicsNVVM.td @@ -3920,7 +3920,9 @@ multiclass NVVM_WMMA_LD_G { } multiclass NVVM_WMMA_LD { + defm _m32n8k16_load: NVVM_WMMA_LD_G<"m32n8k16">; defm _m16n16k16_load: NVVM_WMMA_LD_G<"m16n16k16">; + defm _m8n32k16_load: NVVM_WMMA_LD_G<"m8n32k16">; } defm int_nvvm_wmma: NVVM_WMMA_LD; @@ -3947,7 +3949,7 @@ class NVVM_WMMA_STD_GLSTS; -multiclass NVVM_WMMA_STD_GLT { def _stride: NVVM_WMMA_STD_GLSTS; def NAME: NVVM_WMMA_STD_GLSTS; @@ -3963,7 +3965,9 @@ multiclass NVVM_WMMA_STD_G { } multiclass NVVM_WMMA_STD { + defm _m32n8k16_store: NVVM_WMMA_STD_G<"m32n8k16">; defm _m16n16k16_store: NVVM_WMMA_STD_G<"m16n16k16">; + defm _m8n32k16_store: NVVM_WMMA_STD_G<"m8n32k16">; } defm int_nvvm_wmma: NVVM_WMMA_STD; @@ -4033,7 +4037,9 @@ multiclass NVVM_WMMA_MMA_G { } multiclass NVVM_WMMA_MMA { + defm _m32n8k16_mma : NVVM_WMMA_MMA_G<"m32n8k16">; defm _m16n16k16_mma : NVVM_WMMA_MMA_G<"m16n16k16">; + defm _m8n32k16_mma : NVVM_WMMA_MMA_G<"m8n32k16">; } defm int_nvvm_wmma : NVVM_WMMA_MMA; diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index 6321bb81b8cbc4e6c14c238dd7882a3c62a14aa6..a302d5726aa3228f3ef212bd5fd41b02f6af297a 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -36,8 +36,12 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". // Intrinsics used to generate ctr-based loops. These should only be // generated by the PowerPC backend! + // The branch intrinsic is marked as NoDuplicate because loop rotation will + // attempt to duplicate it forming loops where a block reachable from one + // instance of it can contain another. def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>; - def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>; + def int_ppc_is_decremented_ctr_nonzero : + Intrinsic<[llvm_i1_ty], [], [IntrNoDuplicate]>; // Intrinsics for [double]word extended forms of divide instructions def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">, diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index e9e5e533b56a35b4463057562f4c0ca62b9085fd..7afc755a1e37bb630831b98f6a4a76e3af419de4 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -8,17 +8,23 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file defines all of the WebAssembly-specific intrinsics. +/// This file defines all of the WebAssembly-specific intrinsics. /// //===----------------------------------------------------------------------===// let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.". // Query the current memory size, and increase the current memory size. -// Note that mem.size is not IntrNoMem because it must be sequenced with -// respect to mem.grow calls. -// These are the new proposed names, which aren't yet official. Use at your own -// risk. +// Note that memory.size is not IntrNoMem because it must be sequenced with +// respect to memory.grow calls. +def int_wasm_memory_size : Intrinsic<[llvm_anyint_ty], + [llvm_i32_ty], + [IntrReadMem]>; +def int_wasm_memory_grow : Intrinsic<[llvm_anyint_ty], + [llvm_i32_ty, LLVMMatchType<0>], + []>; + +// These are the old names. def int_wasm_mem_size : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty], [IntrReadMem]>; @@ -26,8 +32,7 @@ def int_wasm_mem_grow : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty, LLVMMatchType<0>], []>; -// These are the existing names, which are currently official, but expected -// to be deprecated in the future. They also lack the immediate field. +// These are the old old names. They also lack the immediate field. def int_wasm_current_memory : Intrinsic<[llvm_anyint_ty], [], [IntrReadMem]>; def int_wasm_grow_memory : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], []>; @@ -42,7 +47,21 @@ def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>; // Since wasm does not use landingpad instructions, these instructions return // exception pointer and selector values until we lower them in WasmEHPrepare. -def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [], [IntrHasSideEffects]>; -def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [], +def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty], + [IntrHasSideEffects]>; +def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrHasSideEffects]>; + +// wasm.catch returns the pointer to the exception object caught by wasm 'catch' +// instruction. +def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], + [IntrHasSideEffects]>; + +// WebAssembly EH must maintain the landingpads in the order assigned to them +// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is +// used in order to give them the indices in WasmEHPrepare. +def int_wasm_landingpad_index: Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>; + +// Returns LSDA address of the current function. +def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; } diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index b0a9dc1cc7de8cb695c22bab5455cfec62e95d59..f07d61bd9f555fef8c096cdb6eb09546702f6a47 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -269,12 +269,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>; def int_x86_sse_cvttss2si64 : GCCBuiltin<"__builtin_ia32_cvttss2si64">, Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_sse_cvtsi2ss : // TODO: Remove this intrinsic. - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_sse_cvtsi642ss : // TODO: Remove this intrinsic. - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i64_ty], [IntrNoMem]>; def int_x86_sse_cvtps2pi : GCCBuiltin<"__builtin_ia32_cvtps2pi">, Intrinsic<[llvm_x86mmx_ty], [llvm_v4f32_ty], [IntrNoMem]>; @@ -408,9 +402,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw128">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem, Commutative]>; - def int_x86_sse2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq128">, - Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, - llvm_v4i32_ty], [IntrNoMem, Commutative]>; def int_x86_sse2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd128">, Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem, Commutative]>; @@ -474,8 +465,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Conversion ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse2_cvtdq2ps : GCCBuiltin<"__builtin_ia32_cvtdq2ps">, - Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>; def int_x86_sse2_cvtpd2dq : GCCBuiltin<"__builtin_ia32_cvtpd2dq">, Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>; def int_x86_sse2_cvttpd2dq : GCCBuiltin<"__builtin_ia32_cvttpd2dq">, @@ -494,18 +483,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>; def int_x86_sse2_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_cvttsd2si64">, Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_sse2_cvtsi2sd : // TODO: Remove this intrinsic. - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_sse2_cvtsi642sd : // TODO: Remove this intrinsic. - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i64_ty], [IntrNoMem]>; def int_x86_sse2_cvtsd2ss : GCCBuiltin<"__builtin_ia32_cvtsd2ss">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_sse2_cvtss2sd : // TODO: Remove this intrinsic. - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_v4f32_ty], [IntrNoMem]>; def int_x86_sse_cvtpd2pi : GCCBuiltin<"__builtin_ia32_cvtpd2pi">, Intrinsic<[llvm_x86mmx_ty], [llvm_v2f64_ty], [IntrNoMem]>; def int_x86_sse_cvttpd2pi: GCCBuiltin<"__builtin_ia32_cvttpd2pi">, @@ -803,13 +783,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [IntrNoMem]>; } -// Vector multiply -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse41_pmuldq : GCCBuiltin<"__builtin_ia32_pmuldq128">, - Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], - [IntrNoMem, Commutative]>; -} - // Vector insert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_insertps : GCCBuiltin<"__builtin_ia32_insertps128">, @@ -1039,325 +1012,99 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_vpermilvarps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermi2var_d_128 : - GCCBuiltin<"__builtin_ia32_vpermi2vard128_mask">, - Intrinsic<[llvm_v4i32_ty], - [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_d_256 : - GCCBuiltin<"__builtin_ia32_vpermi2vard256_mask">, - Intrinsic<[llvm_v8i32_ty], - [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_d_512 : - GCCBuiltin<"__builtin_ia32_vpermi2vard512_mask">, - Intrinsic<[llvm_v16i32_ty], - [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_hi_128 : - GCCBuiltin<"__builtin_ia32_vpermi2varhi128_mask">, - Intrinsic<[llvm_v8i16_ty], - [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_d_128 : + GCCBuiltin<"__builtin_ia32_vpermi2vard128">, + Intrinsic<[llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermi2var_hi_256 : - GCCBuiltin<"__builtin_ia32_vpermi2varhi256_mask">, - Intrinsic<[llvm_v16i16_ty], - [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_hi_512 : - GCCBuiltin<"__builtin_ia32_vpermi2varhi512_mask">, - Intrinsic<[llvm_v32i16_ty], - [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_pd_128 : - GCCBuiltin<"__builtin_ia32_vpermi2varpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_pd_256 : - GCCBuiltin<"__builtin_ia32_vpermi2varpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_pd_512 : - GCCBuiltin<"__builtin_ia32_vpermi2varpd512_mask">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_ps_128 : - GCCBuiltin<"__builtin_ia32_vpermi2varps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_ps_256 : - GCCBuiltin<"__builtin_ia32_vpermi2varps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_ps_512 : - GCCBuiltin<"__builtin_ia32_vpermi2varps512_mask">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16f32_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_q_128 : - GCCBuiltin<"__builtin_ia32_vpermi2varq128_mask">, - Intrinsic<[llvm_v2i64_ty], - [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_q_256 : - GCCBuiltin<"__builtin_ia32_vpermi2varq256_mask">, - Intrinsic<[llvm_v4i64_ty], - [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermi2var_q_512 : - GCCBuiltin<"__builtin_ia32_vpermi2varq512_mask">, - Intrinsic<[llvm_v8i64_ty], - [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_d_512: - GCCBuiltin<"__builtin_ia32_vpermt2vard512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, - llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_q_512: - GCCBuiltin<"__builtin_ia32_vpermt2varq512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, - llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_ps_512: - GCCBuiltin<"__builtin_ia32_vpermt2varps512_mask">, - Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, - llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_pd_512: - GCCBuiltin<"__builtin_ia32_vpermt2varpd512_mask">, - Intrinsic<[llvm_v8f64_ty], [llvm_v8i64_ty, - llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_d_128 : - GCCBuiltin<"__builtin_ia32_vpermt2vard128_mask">, - Intrinsic<[llvm_v4i32_ty], - [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_d_128 : - GCCBuiltin<"__builtin_ia32_vpermt2vard128_maskz">, - Intrinsic<[llvm_v4i32_ty], - [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_d_256 : - GCCBuiltin<"__builtin_ia32_vpermt2vard256_mask">, - Intrinsic<[llvm_v8i32_ty], - [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_d_256 : - GCCBuiltin<"__builtin_ia32_vpermt2vard256_maskz">, - Intrinsic<[llvm_v8i32_ty], - [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_d_512 : - GCCBuiltin<"__builtin_ia32_vpermt2vard512_maskz">, - Intrinsic<[llvm_v16i32_ty], - [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_hi_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi128_mask">, - Intrinsic<[llvm_v8i16_ty], - [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_hi_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi128_maskz">, - Intrinsic<[llvm_v8i16_ty], - [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_hi_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi256_mask">, - Intrinsic<[llvm_v16i16_ty], - [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_hi_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi256_maskz">, - Intrinsic<[llvm_v16i16_ty], - [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_hi_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi512_mask">, - Intrinsic<[llvm_v32i16_ty], - [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_hi_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varhi512_maskz">, - Intrinsic<[llvm_v32i16_ty], - [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_pd_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varpd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2i64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_pd_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varpd128_maskz">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2i64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_pd_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varpd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4i64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_pd_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varpd256_maskz">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4i64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_pd_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varpd512_maskz">, - Intrinsic<[llvm_v8f64_ty], - [llvm_v8i64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_ps_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_ps_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varps128_maskz">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_ps_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8i32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_ps_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varps256_maskz">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8i32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_ps_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varps512_maskz">, - Intrinsic<[llvm_v16f32_ty], - [llvm_v16i32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_q_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varq128_mask">, - Intrinsic<[llvm_v2i64_ty], - [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_maskz_vpermt2var_q_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varq128_maskz">, - Intrinsic<[llvm_v2i64_ty], - [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_vpermt2var_q_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varq256_mask">, - Intrinsic<[llvm_v4i64_ty], - [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_d_256 : + GCCBuiltin<"__builtin_ia32_vpermi2vard256">, + Intrinsic<[llvm_v8i32_ty], + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpermt2var_q_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varq256_maskz">, - Intrinsic<[llvm_v4i64_ty], - [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_d_512 : + GCCBuiltin<"__builtin_ia32_vpermi2vard512">, + Intrinsic<[llvm_v16i32_ty], + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_vpermt2var_q_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varq512_maskz">, - Intrinsic<[llvm_v8i64_ty], - [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_hi_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi128">, + Intrinsic<[llvm_v8i16_ty], + [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermi2var_qi_128 : - GCCBuiltin<"__builtin_ia32_vpermi2varqi128_mask">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, - llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_hi_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi256">, + Intrinsic<[llvm_v16i16_ty], + [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v16i16_ty], + [IntrNoMem]>; - def int_x86_avx512_mask_vpermt2var_qi_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi128_mask">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, - llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_hi_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varhi512">, + Intrinsic<[llvm_v32i16_ty], + [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_vpermt2var_qi_128 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi128_maskz">, - Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, - llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_pd_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd128">, + Intrinsic<[llvm_v2f64_ty], + [llvm_v2f64_ty, llvm_v2i64_ty, llvm_v2f64_ty], [IntrNoMem]>; + + def int_x86_avx512_vpermi2var_pd_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd256">, + Intrinsic<[llvm_v4f64_ty], + [llvm_v4f64_ty, llvm_v4i64_ty, llvm_v4f64_ty], [IntrNoMem]>; + + def int_x86_avx512_vpermi2var_pd_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varpd512">, + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8i64_ty, llvm_v8f64_ty], [IntrNoMem]>; + + def int_x86_avx512_vpermi2var_ps_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varps128">, + Intrinsic<[llvm_v4f32_ty], + [llvm_v4f32_ty, llvm_v4i32_ty, llvm_v4f32_ty], [IntrNoMem]>; + + def int_x86_avx512_vpermi2var_ps_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varps256">, + Intrinsic<[llvm_v8f32_ty], + [llvm_v8f32_ty, llvm_v8i32_ty, llvm_v8f32_ty], [IntrNoMem]>; + + def int_x86_avx512_vpermi2var_ps_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varps512">, + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16i32_ty, llvm_v16f32_ty], + [IntrNoMem]>; - def int_x86_avx512_mask_vpermi2var_qi_256 : - GCCBuiltin<"__builtin_ia32_vpermi2varqi256_mask">, - Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, - llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_q_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varq128">, + Intrinsic<[llvm_v2i64_ty], + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt2var_qi_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi256_mask">, - Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, - llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_q_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varq256">, + Intrinsic<[llvm_v4i64_ty], + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpermt2var_qi_256 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi256_maskz">, - Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, - llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_q_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varq512">, + Intrinsic<[llvm_v8i64_ty], + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermi2var_qi_512 : - GCCBuiltin<"__builtin_ia32_vpermi2varqi512_mask">, - Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, - llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_qi_128 : + GCCBuiltin<"__builtin_ia32_vpermi2varqi128">, + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpermt2var_qi_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi512_mask">, - Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, - llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_qi_256 : + GCCBuiltin<"__builtin_ia32_vpermi2varqi256">, + Intrinsic<[llvm_v32i8_ty], + [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v32i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpermt2var_qi_512 : - GCCBuiltin<"__builtin_ia32_vpermt2varqi512_maskz">, - Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, - llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], - [IntrNoMem]>; + def int_x86_avx512_vpermi2var_qi_512 : + GCCBuiltin<"__builtin_ia32_vpermi2varqi512">, + Intrinsic<[llvm_v64i8_ty], + [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty], [IntrNoMem]>; def int_x86_avx512_vpermilvar_pd_512 : GCCBuiltin<"__builtin_ia32_vpermilvarpd512">, @@ -1456,8 +1203,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector convert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx_cvtdq2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtdq2ps256">, - Intrinsic<[llvm_v8f32_ty], [llvm_v8i32_ty], [IntrNoMem]>; def int_x86_avx_cvt_pd2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtpd2ps256">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f64_ty], [IntrNoMem]>; def int_x86_avx_cvt_ps2dq_256 : GCCBuiltin<"__builtin_ia32_cvtps2dq256">, @@ -1606,11 +1351,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_maskstoreps256">, Intrinsic<[], [llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty], [IntrArgMemOnly]>; - - def int_x86_avx512_mask_store_ss : - GCCBuiltin<"__builtin_ia32_storess_mask">, - Intrinsic<[], [llvm_ptr_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrArgMemOnly]>; } // BITALG bits shuffle @@ -1667,12 +1407,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw256">, Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem, Commutative]>; - def int_x86_avx2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, - llvm_v8i32_ty], [IntrNoMem, Commutative]>; - def int_x86_avx2_pmul_dq : GCCBuiltin<"__builtin_ia32_pmuldq256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, - llvm_v8i32_ty], [IntrNoMem, Commutative]>; def int_x86_avx2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem, Commutative]>; @@ -2188,11 +1922,11 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // FMA3 and FMA4 let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_fma_vfmadd_ss : GCCBuiltin<"__builtin_ia32_vfmaddss3">, + def int_x86_fma_vfmadd_ss : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_fma_vfmadd_sd : GCCBuiltin<"__builtin_ia32_vfmaddsd3">, + def int_x86_fma_vfmadd_sd : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; @@ -2204,342 +1938,236 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_fma_vfmadd_ps : GCCBuiltin<"__builtin_ia32_vfmaddps">, + def int_x86_fma_vfmadd_ps : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_fma_vfmadd_pd : GCCBuiltin<"__builtin_ia32_vfmaddpd">, + def int_x86_fma_vfmadd_pd : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_fma_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256">, + def int_x86_fma_vfmadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; - def int_x86_fma_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256">, + def int_x86_fma_vfmadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_fma_vfmsub_ss : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsub_sd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsub_ps : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsub_pd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsub_ps_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsub_pd_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_ss : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_sd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_ps : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_pd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_ps_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmadd_pd_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmsub_ss : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmsub_sd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfnmsub_ps : // TODO: remove this intrinsic + def int_x86_fma_vfmaddsub_ps : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; - def int_x86_fma_vfnmsub_pd : // TODO: remove this intrinsic + def int_x86_fma_vfmaddsub_pd : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_fma_vfnmsub_ps_256 : // TODO: remove this intrinsic + def int_x86_fma_vfmaddsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; - def int_x86_fma_vfnmsub_pd_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmaddsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps256">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmaddsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd256">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsubadd_ps : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsubadd_pd : // TODO: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsubadd_ps_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v8f32_ty], - [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty], - [IntrNoMem]>; - def int_x86_fma_vfmsubadd_pd_256 : // TODO: remove this intrinsic + def int_x86_fma_vfmaddsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddpd128_mask">, + def int_x86_avx512_mask_vfmadd_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmadd_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddpd128_mask3">, + def int_x86_avx512_mask3_vfmadd_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddpd128_maskz">, + def int_x86_avx512_maskz_vfmadd_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddpd256_mask">, + def int_x86_avx512_mask_vfmadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmadd_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddpd256_mask3">, + def int_x86_avx512_mask3_vfmadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddpd256_maskz">, + def int_x86_avx512_maskz_vfmadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddpd512_mask">, + def int_x86_avx512_vfmadd_pd_512 : Intrinsic<[llvm_v8f64_ty], - [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_pd_512 : // FIXME: remove this intrinsic. + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_mask3_vfmadd_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddpd512_mask3">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddpd512_maskz">, + def int_x86_avx512_maskz_vfmadd_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddps128_mask">, + def int_x86_avx512_mask_vfmadd_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmadd_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddps128_mask3">, + def int_x86_avx512_mask3_vfmadd_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddps128_maskz">, + def int_x86_avx512_maskz_vfmadd_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddps256_mask">, + def int_x86_avx512_mask_vfmadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmadd_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddps256_mask3">, + def int_x86_avx512_mask3_vfmadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddps256_maskz">, + def int_x86_avx512_maskz_vfmadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmadd_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddps512_mask">, + def int_x86_avx512_vfmadd_ps_512 : + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmadd_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmadd_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddps512_mask3">, + def int_x86_avx512_mask3_vfmadd_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmadd_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddps512_maskz">, + def int_x86_avx512_maskz_vfmadd_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_mask">, + def int_x86_avx512_mask_vfmaddsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_mask3">, + def int_x86_avx512_mask3_vfmaddsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd128_maskz">, + def int_x86_avx512_maskz_vfmaddsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_mask">, + def int_x86_avx512_mask_vfmaddsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_mask3">, + def int_x86_avx512_mask3_vfmaddsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd256_maskz">, + def int_x86_avx512_maskz_vfmaddsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_mask">, + def int_x86_avx512_vfmaddsub_pd_512 : + Intrinsic<[llvm_v8f64_ty], + [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_mask3">, + def int_x86_avx512_mask3_vfmaddsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubpd512_maskz">, + def int_x86_avx512_maskz_vfmaddsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps128_mask">, + def int_x86_avx512_mask_vfmaddsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps128_mask3">, + def int_x86_avx512_mask3_vfmaddsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps128_maskz">, + def int_x86_avx512_maskz_vfmaddsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps256_mask">, + def int_x86_avx512_mask_vfmaddsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps256_mask3">, + def int_x86_avx512_mask3_vfmaddsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps256_maskz">, + def int_x86_avx512_maskz_vfmaddsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfmaddsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps512_mask">, + def int_x86_avx512_vfmaddsub_ps_512 : + Intrinsic<[llvm_v16f32_ty], + [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty], + [IntrNoMem]>; + + def int_x86_avx512_mask_vfmaddsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmaddsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps512_mask3">, + def int_x86_avx512_mask3_vfmaddsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vfmaddsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmaddsubps512_maskz">, + def int_x86_avx512_maskz_vfmaddsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; @@ -2593,110 +2221,92 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmsubpd128_mask3">, + def int_x86_avx512_mask3_vfmsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmsubpd256_mask3">, + def int_x86_avx512_mask3_vfmsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmsubpd512_mask3">, + def int_x86_avx512_mask3_vfmsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmsubps128_mask3">, + def int_x86_avx512_mask3_vfmsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmsubps256_mask3">, + def int_x86_avx512_mask3_vfmsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmsubps512_mask3">, + def int_x86_avx512_mask3_vfmsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_pd_128 : - GCCBuiltin<"__builtin_ia32_vfmsubaddpd128_mask3">, + def int_x86_avx512_mask3_vfmsubadd_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_pd_256 : - GCCBuiltin<"__builtin_ia32_vfmsubaddpd256_mask3">, + def int_x86_avx512_mask3_vfmsubadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_pd_512 : - GCCBuiltin<"__builtin_ia32_vfmsubaddpd512_mask3">, + def int_x86_avx512_mask3_vfmsubadd_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_ps_128 : - GCCBuiltin<"__builtin_ia32_vfmsubaddps128_mask3">, + def int_x86_avx512_mask3_vfmsubadd_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_ps_256 : - GCCBuiltin<"__builtin_ia32_vfmsubaddps256_mask3">, + def int_x86_avx512_mask3_vfmsubadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfmsubadd_ps_512 : - GCCBuiltin<"__builtin_ia32_vfmsubaddps512_mask3">, + def int_x86_avx512_mask3_vfmsubadd_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_pd_128 : - GCCBuiltin<"__builtin_ia32_vfnmaddpd128_mask">, + def int_x86_avx512_mask_vfnmadd_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_pd_256 : - GCCBuiltin<"__builtin_ia32_vfnmaddpd256_mask">, + def int_x86_avx512_mask_vfnmadd_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_pd_512 : - GCCBuiltin<"__builtin_ia32_vfnmaddpd512_mask">, + def int_x86_avx512_mask_vfnmadd_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_ps_128 : - GCCBuiltin<"__builtin_ia32_vfnmaddps128_mask">, + def int_x86_avx512_mask_vfnmadd_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_ps_256 : - GCCBuiltin<"__builtin_ia32_vfnmaddps256_mask">, + def int_x86_avx512_mask_vfnmadd_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmadd_ps_512 : - GCCBuiltin<"__builtin_ia32_vfnmaddps512_mask">, + def int_x86_avx512_mask_vfnmadd_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; @@ -2713,229 +2323,145 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd128_mask">, + def int_x86_avx512_mask_vfnmsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_pd_128 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd128_mask3">, + def int_x86_avx512_mask3_vfnmsub_pd_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd256_mask">, + def int_x86_avx512_mask_vfnmsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_pd_256 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd256_mask3">, + def int_x86_avx512_mask3_vfnmsub_pd_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd512_mask">, + def int_x86_avx512_mask_vfnmsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_pd_512 : - GCCBuiltin<"__builtin_ia32_vfnmsubpd512_mask3">, + def int_x86_avx512_mask3_vfnmsub_pd_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfnmsubps128_mask">, + def int_x86_avx512_mask_vfnmsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_ps_128 : - GCCBuiltin<"__builtin_ia32_vfnmsubps128_mask3">, + def int_x86_avx512_mask3_vfnmsub_ps_128 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfnmsubps256_mask">, + def int_x86_avx512_mask_vfnmsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_ps_256 : - GCCBuiltin<"__builtin_ia32_vfnmsubps256_mask3">, + def int_x86_avx512_mask3_vfnmsub_ps_256 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vfnmsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfnmsubps512_mask">, + def int_x86_avx512_mask_vfnmsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask3_vfnmsub_ps_512 : - GCCBuiltin<"__builtin_ia32_vfnmsubps512_mask3">, + def int_x86_avx512_mask3_vfnmsub_ps_512 : // FIXME: remove this intrinsic. Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52h_uq_128 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq128_mask">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52h_uq_128 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq128_maskz">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52l_uq_128 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq128_mask">, + def int_x86_avx512_vpmadd52h_uq_128 : + GCCBuiltin<"__builtin_ia32_vpmadd52huq128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52l_uq_128 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq128_maskz">, + llvm_v2i64_ty], [IntrNoMem]>; + def int_x86_avx512_vpmadd52l_uq_128 : + GCCBuiltin<"__builtin_ia32_vpmadd52luq128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, - llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52h_uq_256 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq256_mask">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52h_uq_256 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq256_maskz">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52l_uq_256 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq256_mask">, + llvm_v2i64_ty], [IntrNoMem]>; + def int_x86_avx512_vpmadd52h_uq_256 : + GCCBuiltin<"__builtin_ia32_vpmadd52huq256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52l_uq_256 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq256_maskz">, + llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_vpmadd52l_uq_256 : + GCCBuiltin<"__builtin_ia32_vpmadd52luq256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, - llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52h_uq_512 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq512_mask">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52h_uq_512 : - GCCBuiltin<"__builtin_ia32_vpmadd52huq512_maskz">, - Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpmadd52l_uq_512 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq512_mask">, + llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_vpmadd52h_uq_512 : + GCCBuiltin<"__builtin_ia32_vpmadd52huq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpmadd52l_uq_512 : - GCCBuiltin<"__builtin_ia32_vpmadd52luq512_maskz">, + llvm_v8i64_ty], [IntrNoMem]>; + def int_x86_avx512_vpmadd52l_uq_512 : + GCCBuiltin<"__builtin_ia32_vpmadd52luq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, - llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + llvm_v8i64_ty], [IntrNoMem]>; } // VNNI let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx512_mask_vpdpbusd_128 : - GCCBuiltin<"__builtin_ia32_vpdpbusd128_mask">, + def int_x86_avx512_vpdpbusd_128 : + GCCBuiltin<"__builtin_ia32_vpdpbusd128">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusd_128 : - GCCBuiltin<"__builtin_ia32_vpdpbusd128_maskz">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpbusd_256 : - GCCBuiltin<"__builtin_ia32_vpdpbusd256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusd_256 : - GCCBuiltin<"__builtin_ia32_vpdpbusd256_maskz">, + llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpbusd_256 : + GCCBuiltin<"__builtin_ia32_vpdpbusd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpbusd_512 : - GCCBuiltin<"__builtin_ia32_vpdpbusd512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusd_512 : - GCCBuiltin<"__builtin_ia32_vpdpbusd512_maskz">, + llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpbusd_512 : + GCCBuiltin<"__builtin_ia32_vpdpbusd512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + llvm_v16i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpbusds_128 : - GCCBuiltin<"__builtin_ia32_vpdpbusds128_mask">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusds_128 : - GCCBuiltin<"__builtin_ia32_vpdpbusds128_maskz">, + def int_x86_avx512_vpdpbusds_128 : + GCCBuiltin<"__builtin_ia32_vpdpbusds128">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpbusds_256 : - GCCBuiltin<"__builtin_ia32_vpdpbusds256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusds_256 : - GCCBuiltin<"__builtin_ia32_vpdpbusds256_maskz">, + llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpbusds_256 : + GCCBuiltin<"__builtin_ia32_vpdpbusds256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpbusds_512 : - GCCBuiltin<"__builtin_ia32_vpdpbusds512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpbusds_512 : - GCCBuiltin<"__builtin_ia32_vpdpbusds512_maskz">, + llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpbusds_512 : + GCCBuiltin<"__builtin_ia32_vpdpbusds512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + llvm_v16i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssd_128 : - GCCBuiltin<"__builtin_ia32_vpdpwssd128_mask">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssd_128 : - GCCBuiltin<"__builtin_ia32_vpdpwssd128_maskz">, + def int_x86_avx512_vpdpwssd_128 : + GCCBuiltin<"__builtin_ia32_vpdpwssd128">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssd_256 : - GCCBuiltin<"__builtin_ia32_vpdpwssd256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssd_256 : - GCCBuiltin<"__builtin_ia32_vpdpwssd256_maskz">, + llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpwssd_256 : + GCCBuiltin<"__builtin_ia32_vpdpwssd256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssd_512 : - GCCBuiltin<"__builtin_ia32_vpdpwssd512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssd_512 : - GCCBuiltin<"__builtin_ia32_vpdpwssd512_maskz">, + llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpwssd_512 : + GCCBuiltin<"__builtin_ia32_vpdpwssd512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + llvm_v16i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssds_128 : - GCCBuiltin<"__builtin_ia32_vpdpwssds128_mask">, + def int_x86_avx512_vpdpwssds_128 : + GCCBuiltin<"__builtin_ia32_vpdpwssds128">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssds_128 : - GCCBuiltin<"__builtin_ia32_vpdpwssds128_maskz">, - Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, - llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssds_256 : - GCCBuiltin<"__builtin_ia32_vpdpwssds256_mask">, - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssds_256 : - GCCBuiltin<"__builtin_ia32_vpdpwssds256_maskz">, + llvm_v4i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpwssds_256 : + GCCBuiltin<"__builtin_ia32_vpdpwssds256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, - llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_vpdpwssds_512 : - GCCBuiltin<"__builtin_ia32_vpdpwssds512_mask">, - Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_vpdpwssds_512 : - GCCBuiltin<"__builtin_ia32_vpdpwssds512_maskz">, + llvm_v8i32_ty], [IntrNoMem]>; + def int_x86_avx512_vpdpwssds_512 : + GCCBuiltin<"__builtin_ia32_vpdpwssds512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty, - llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + llvm_v16i32_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// @@ -3383,48 +2909,42 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } // Permute let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx512_mask_permvar_df_256 : GCCBuiltin<"__builtin_ia32_permvardf256_mask">, + def int_x86_avx512_permvar_df_256 : GCCBuiltin<"__builtin_ia32_permvardf256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_df_512 : GCCBuiltin<"__builtin_ia32_permvardf512_mask">, + llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_df_512 : GCCBuiltin<"__builtin_ia32_permvardf512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, - llvm_v8i64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_di_256 : GCCBuiltin<"__builtin_ia32_permvardi256_mask">, + llvm_v8i64_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_di_256 : GCCBuiltin<"__builtin_ia32_permvardi256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, - llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_di_512 : GCCBuiltin<"__builtin_ia32_permvardi512_mask">, + llvm_v4i64_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_di_512 : GCCBuiltin<"__builtin_ia32_permvardi512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, - llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_hi_128 : GCCBuiltin<"__builtin_ia32_permvarhi128_mask">, + llvm_v8i64_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_hi_128 : GCCBuiltin<"__builtin_ia32_permvarhi128">, Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, - llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_hi_256 : GCCBuiltin<"__builtin_ia32_permvarhi256_mask">, + llvm_v8i16_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_hi_256 : GCCBuiltin<"__builtin_ia32_permvarhi256">, Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, - llvm_v16i16_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_hi_512 : GCCBuiltin<"__builtin_ia32_permvarhi512_mask">, + llvm_v16i16_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_hi_512 : GCCBuiltin<"__builtin_ia32_permvarhi512">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, - llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_qi_128 : GCCBuiltin<"__builtin_ia32_permvarqi128_mask">, + llvm_v32i16_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_qi_128 : GCCBuiltin<"__builtin_ia32_permvarqi128">, Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, - llvm_v16i8_ty, llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_qi_256 : GCCBuiltin<"__builtin_ia32_permvarqi256_mask">, + llvm_v16i8_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_qi_256 : GCCBuiltin<"__builtin_ia32_permvarqi256">, Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, - llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_qi_512 : GCCBuiltin<"__builtin_ia32_permvarqi512_mask">, + llvm_v32i8_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_qi_512 : GCCBuiltin<"__builtin_ia32_permvarqi512">, Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, - llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_sf_256 : // TODO: Remove this intrinsic - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_sf_512 : GCCBuiltin<"__builtin_ia32_permvarsf512_mask">, + llvm_v64i8_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_sf_512 : GCCBuiltin<"__builtin_ia32_permvarsf512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, - llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_si_256 : // TODO: Remove this intrinsic - Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, - llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_permvar_si_512 : GCCBuiltin<"__builtin_ia32_permvarsi512_mask">, + llvm_v16i32_ty], [IntrNoMem]>; + def int_x86_avx512_permvar_si_512 : GCCBuiltin<"__builtin_ia32_permvarsi512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, - llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>; + llvm_v16i32_ty], [IntrNoMem]>; } // Pack ops. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". @@ -3741,9 +3261,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvttsd2usi64">, Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_cvtusi2sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd32">, - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i32_ty], [IntrNoMem]>; def int_x86_avx512_cvtusi642sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd64">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>; @@ -3792,16 +3309,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Vector convert let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_avx512_mask_cvtdq2ps_128 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvtdq2ps_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v8f32_ty], - [llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtdq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">, Intrinsic<[llvm_v16f32_ty], @@ -3814,22 +3321,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2dq_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4i32_ty], - [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2dq_512 : GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">, Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2ps_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4f32_ty], - [llvm_v4f64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtpd2ps_512 : GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">, Intrinsic<[llvm_v8f32_ty], @@ -3926,16 +3423,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtps2pd_128 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v2f64_ty], - [llvm_v4f32_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvtps2pd_256 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v4f64_ty], - [llvm_v4f32_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtps2pd_512 : GCCBuiltin<"__builtin_ia32_cvtps2pd512_mask">, Intrinsic<[llvm_v8f64_ty], @@ -3996,18 +3483,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtqq2pd_128 : - GCCBuiltin<"__builtin_ia32_cvtqq2pd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvtqq2pd_256 : - GCCBuiltin<"__builtin_ia32_cvtqq2pd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtqq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtqq2pd512_mask">, Intrinsic<[llvm_v8f64_ty], @@ -4038,11 +3513,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v2f64_ty, llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvttpd2dq_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4i32_ty], - [llvm_v4f64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvttpd2dq_512 : GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">, Intrinsic<[llvm_v8i32_ty], @@ -4103,16 +3573,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvttps2dq_128 : // TODO: remove this intrinsic - Intrinsic<[llvm_v4i32_ty], - [llvm_v4f32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvttps2dq_256 : // TODO: remove this intrinsic - Intrinsic<[llvm_v8i32_ty], - [llvm_v8f32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvttps2dq_512 : GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">, Intrinsic<[llvm_v16i32_ty], @@ -4173,36 +3633,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". [llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtudq2ps_128 : - GCCBuiltin<"__builtin_ia32_cvtudq2ps128_mask">, - Intrinsic<[llvm_v4f32_ty], - [llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvtudq2ps_256 : - GCCBuiltin<"__builtin_ia32_cvtudq2ps256_mask">, - Intrinsic<[llvm_v8f32_ty], - [llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtudq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtudq2ps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cvtuqq2pd_128 : - GCCBuiltin<"__builtin_ia32_cvtuqq2pd128_mask">, - Intrinsic<[llvm_v2f64_ty], - [llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrNoMem]>; - - def int_x86_avx512_mask_cvtuqq2pd_256 : - GCCBuiltin<"__builtin_ia32_cvtuqq2pd256_mask">, - Intrinsic<[llvm_v4f64_ty], - [llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_cvtuqq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtuqq2pd512_mask">, Intrinsic<[llvm_v8f64_ty], @@ -4285,13 +3721,6 @@ def int_x86_avx512_mask_range_ps_512 : GCCBuiltin<"__builtin_ia32_rangeps512_mas // Vector load with broadcast let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - // TODO: Remove the broadcast intrinsics with no gcc builtin and autoupgrade - def int_x86_avx512_vbroadcast_ss_512 : - Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>; - - def int_x86_avx512_vbroadcast_sd_512 : - Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>; - def int_x86_avx512_broadcastmw_512 : GCCBuiltin<"__builtin_ia32_broadcastmw512">, Intrinsic<[llvm_v16i32_ty], [llvm_i16_ty], [IntrNoMem]>; @@ -4783,42 +4212,18 @@ let TargetPrefix = "x86" in { def int_x86_avx512_mask_psubus_w_512 : GCCBuiltin<"__builtin_ia32_psubusw512_mask">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512">, - Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty], [IntrNoMem]>; - def int_x86_avx512_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512">, - Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty], [IntrNoMem]>; def int_x86_avx512_pmulhu_w_512 : GCCBuiltin<"__builtin_ia32_pmulhuw512">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty], [IntrNoMem, Commutative]>; def int_x86_avx512_pmulh_w_512 : GCCBuiltin<"__builtin_ia32_pmulhw512">, Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty], [IntrNoMem, Commutative]>; - def int_x86_avx512_mask_pmaddw_d_128 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v4i32_ty], - [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_pmaddw_d_256 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v8i32_ty], - [llvm_v16i16_ty, llvm_v16i16_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_pmaddw_d_512 : - GCCBuiltin<"__builtin_ia32_pmaddwd512_mask">, - Intrinsic<[llvm_v16i32_ty], - [llvm_v32i16_ty, llvm_v32i16_ty, llvm_v16i32_ty, llvm_i16_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_pmaddubs_w_128 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v8i16_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v8i16_ty, llvm_i8_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_pmaddubs_w_256 : // FIXME: remove this intrinsic - Intrinsic<[llvm_v16i16_ty], - [llvm_v32i8_ty, llvm_v32i8_ty, llvm_v16i16_ty, llvm_i16_ty], - [IntrNoMem]>; - def int_x86_avx512_mask_pmaddubs_w_512 : - GCCBuiltin<"__builtin_ia32_pmaddubsw512_mask">, - Intrinsic<[llvm_v32i16_ty], - [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v32i16_ty, llvm_i32_ty], - [IntrNoMem]>; + def int_x86_avx512_pmaddw_d_512 : GCCBuiltin<"__builtin_ia32_pmaddwd512">, + Intrinsic<[llvm_v16i32_ty], [llvm_v32i16_ty, + llvm_v32i16_ty], [IntrNoMem, Commutative]>; + def int_x86_avx512_pmaddubs_w_512 : GCCBuiltin<"__builtin_ia32_pmaddubsw512">, + Intrinsic<[llvm_v32i16_ty], [llvm_v64i8_ty, + llvm_v64i8_ty], [IntrNoMem]>; def int_x86_avx512_mask_dbpsadbw_128 : GCCBuiltin<"__builtin_ia32_dbpsadbw128_mask">, @@ -5945,8 +5350,7 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_qd_256 : - GCCBuiltin<"__builtin_ia32_pmovqd256_mask">, + def int_x86_avx512_mask_pmov_qd_256 : // FIXME: Replace with trunc+select. Intrinsic<[llvm_v4i32_ty], [llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>; @@ -5975,8 +5379,7 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_qd_512 : - GCCBuiltin<"__builtin_ia32_pmovqd512_mask">, + def int_x86_avx512_mask_pmov_qd_512 : // FIXME: Replace with trunc+select. Intrinsic<[llvm_v8i32_ty], [llvm_v8i64_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; @@ -6215,8 +5618,7 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v8i16_ty, llvm_i8_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_wb_256 : - GCCBuiltin<"__builtin_ia32_pmovwb256_mask">, + def int_x86_avx512_mask_pmov_wb_256 : // FIXME: Replace with trunc+select. Intrinsic<[llvm_v16i8_ty], [llvm_v16i16_ty, llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>; @@ -6245,8 +5647,7 @@ let TargetPrefix = "x86" in { Intrinsic<[], [llvm_ptr_ty, llvm_v16i16_ty, llvm_i16_ty], [IntrArgMemOnly]>; - def int_x86_avx512_mask_pmov_wb_512 : - GCCBuiltin<"__builtin_ia32_pmovwb512_mask">, + def int_x86_avx512_mask_pmov_wb_512 : // FIXME: Replace with trunc+select. Intrinsic<[llvm_v32i8_ty], [llvm_v32i16_ty, llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>; @@ -6279,77 +5680,41 @@ let TargetPrefix = "x86" in { // Bitwise ternary logic let TargetPrefix = "x86" in { - def int_x86_avx512_mask_pternlog_d_128 : - GCCBuiltin<"__builtin_ia32_pternlogd128_mask">, + def int_x86_avx512_pternlog_d_128 : + GCCBuiltin<"__builtin_ia32_pternlogd128">, Intrinsic<[llvm_v4i32_ty], - [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_maskz_pternlog_d_128 : - GCCBuiltin<"__builtin_ia32_pternlogd128_maskz">, - Intrinsic<[llvm_v4i32_ty], - [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_pternlog_d_256 : - GCCBuiltin<"__builtin_ia32_pternlogd256_mask">, - Intrinsic<[llvm_v8i32_ty], - [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; + [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_pternlog_d_256 : - GCCBuiltin<"__builtin_ia32_pternlogd256_maskz">, + def int_x86_avx512_pternlog_d_256 : + GCCBuiltin<"__builtin_ia32_pternlogd256">, Intrinsic<[llvm_v8i32_ty], - [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_pternlog_d_512 : - GCCBuiltin<"__builtin_ia32_pternlogd512_mask">, - Intrinsic<[llvm_v16i32_ty], - [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; + [llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_pternlog_d_512 : - GCCBuiltin<"__builtin_ia32_pternlogd512_maskz">, + def int_x86_avx512_pternlog_d_512 : + GCCBuiltin<"__builtin_ia32_pternlogd512">, Intrinsic<[llvm_v16i32_ty], - [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_pternlog_q_128 : - GCCBuiltin<"__builtin_ia32_pternlogq128_mask">, - Intrinsic<[llvm_v2i64_ty], - [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; + [llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty, + llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_maskz_pternlog_q_128 : - GCCBuiltin<"__builtin_ia32_pternlogq128_maskz">, + def int_x86_avx512_pternlog_q_128 : + GCCBuiltin<"__builtin_ia32_pternlogq128">, Intrinsic<[llvm_v2i64_ty], - [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_pternlog_q_256 : - GCCBuiltin<"__builtin_ia32_pternlogq256_mask">, - Intrinsic<[llvm_v4i64_ty], - [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; + [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_pternlog_q_256 : - GCCBuiltin<"__builtin_ia32_pternlogq256_maskz">, + def int_x86_avx512_pternlog_q_256 : + GCCBuiltin<"__builtin_ia32_pternlogq256">, Intrinsic<[llvm_v4i64_ty], - [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_pternlog_q_512 : - GCCBuiltin<"__builtin_ia32_pternlogq512_mask">, - Intrinsic<[llvm_v8i64_ty], - [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; + [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], + [IntrNoMem]>; - def int_x86_avx512_maskz_pternlog_q_512 : - GCCBuiltin<"__builtin_ia32_pternlogq512_maskz">, + def int_x86_avx512_pternlog_q_512 : + GCCBuiltin<"__builtin_ia32_pternlogq512">, Intrinsic<[llvm_v8i64_ty], - [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; + [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], + [IntrNoMem]>; } // Misc. @@ -6421,3 +5786,65 @@ let TargetPrefix = "x86" in { def int_x86_clzero : GCCBuiltin<"__builtin_ia32_clzero">, Intrinsic<[], [llvm_ptr_ty], []>; } + +//===----------------------------------------------------------------------===// +// Cache write back intrinsics + +let TargetPrefix = "x86" in { + // Write back and invalidate + def int_x86_wbinvd : GCCBuiltin<"__builtin_ia32_wbinvd">, + Intrinsic<[], [], []>; + + // Write back no-invalidate + def int_x86_wbnoinvd : GCCBuiltin<"__builtin_ia32_wbnoinvd">, + Intrinsic<[], [], []>; +} + +//===----------------------------------------------------------------------===// +// Cache-line demote + +let TargetPrefix = "x86" in { + def int_x86_cldemote : GCCBuiltin<"__builtin_ia32_cldemote">, + Intrinsic<[], [llvm_ptr_ty], []>; +} + +//===----------------------------------------------------------------------===// +// Wait and pause enhancements +let TargetPrefix = "x86" in { + def int_x86_umonitor : GCCBuiltin<"__builtin_ia32_umonitor">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_x86_umwait : GCCBuiltin<"__builtin_ia32_umwait">, + Intrinsic<[llvm_i8_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_x86_tpause : GCCBuiltin<"__builtin_ia32_tpause">, + Intrinsic<[llvm_i8_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; +} + +//===----------------------------------------------------------------------===// +// Direct Move Instructions + +let TargetPrefix = "x86" in { + def int_x86_directstore32 : GCCBuiltin<"__builtin_ia32_directstore_u32">, + Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], []>; + def int_x86_directstore64 : GCCBuiltin<"__builtin_ia32_directstore_u64">, + Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty], []>; + def int_x86_movdir64b : GCCBuiltin<"__builtin_ia32_movdir64b">, + Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], []>; +} + +//===----------------------------------------------------------------------===// +// PTWrite - Write data to processor trace pocket + +let TargetPrefix = "x86" in { + def int_x86_ptwrite32 : GCCBuiltin<"__builtin_ia32_ptwrite32">, + Intrinsic<[], [llvm_i32_ty], []>; + def int_x86_ptwrite64 : GCCBuiltin<"__builtin_ia32_ptwrite64">, + Intrinsic<[], [llvm_i64_ty], []>; +} + +//===----------------------------------------------------------------------===// +// INVPCID - Invalidate Process-Context Identifier + +let TargetPrefix = "x86" in { + def int_x86_invpcid : GCCBuiltin<"__builtin_ia32_invpcid">, + Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], []>; +} diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index 5778b417ae2a709ab71dbc36a97d802ada1dcf64..ebd445553167bd6496a76acfe31db49ed262fdc5 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -229,23 +229,23 @@ public: /// to caller. std::unique_ptr getDiagnosticHandler(); - /// \brief Return if a code hotness metric should be included in optimization + /// Return if a code hotness metric should be included in optimization /// diagnostics. bool getDiagnosticsHotnessRequested() const; - /// \brief Set if a code hotness metric should be included in optimization + /// Set if a code hotness metric should be included in optimization /// diagnostics. void setDiagnosticsHotnessRequested(bool Requested); - /// \brief Return the minimum hotness value a diagnostic would need in order + /// Return the minimum hotness value a diagnostic would need in order /// to be included in optimization diagnostics. If there is no minimum, this /// returns None. uint64_t getDiagnosticsHotnessThreshold() const; - /// \brief Set the minimum hotness value a diagnostic needs in order to be + /// Set the minimum hotness value a diagnostic needs in order to be /// included in optimization diagnostics. void setDiagnosticsHotnessThreshold(uint64_t Threshold); - /// \brief Return the YAML file used by the backend to save optimization + /// Return the YAML file used by the backend to save optimization /// diagnostics. If null, diagnostics are not saved in a file but only /// emitted via the diagnostic handler. yaml::Output *getDiagnosticsOutputFile(); @@ -256,11 +256,11 @@ public: /// set, the handler is invoked for each diagnostic message. void setDiagnosticsOutputFile(std::unique_ptr F); - /// \brief Get the prefix that should be printed in front of a diagnostic of + /// Get the prefix that should be printed in front of a diagnostic of /// the given \p Severity static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity); - /// \brief Report a message to the currently installed diagnostic handler. + /// Report a message to the currently installed diagnostic handler. /// /// This function returns, in particular in the case of error reporting /// (DI.Severity == \a DS_Error), so the caller should leave the compilation @@ -272,7 +272,7 @@ public: /// "warning: " for \a DS_Warning, and "note: " for \a DS_Note. void diagnose(const DiagnosticInfo &DI); - /// \brief Registers a yield callback with the given context. + /// Registers a yield callback with the given context. /// /// The yield callback function may be called by LLVM to transfer control back /// to the client that invoked the LLVM compilation. This can be used to yield @@ -291,7 +291,7 @@ public: /// control to LLVM. Other LLVM contexts are unaffected by this restriction. void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle); - /// \brief Calls the yield callback (if applicable). + /// Calls the yield callback (if applicable). /// /// This transfers control of the current thread back to the client, which may /// suspend the current thread. Only call this method when LLVM doesn't hold @@ -307,7 +307,7 @@ public: void emitError(const Instruction *I, const Twine &ErrorStr); void emitError(const Twine &ErrorStr); - /// \brief Query for a debug option's value. + /// Query for a debug option's value. /// /// This function returns typed data populated from command line parsing. template @@ -315,9 +315,16 @@ public: return OptionRegistry::instance().template get(); } - /// \brief Access the object which manages optimization bisection for failure - /// analysis. - OptPassGate &getOptPassGate(); + /// Access the object which can disable optional passes and individual + /// optimizations at compile time. + OptPassGate &getOptPassGate() const; + + /// Set the object which can disable optional passes and individual + /// optimizations at compile time. + /// + /// The lifetime of the object must be guaranteed to extend as long as the + /// LLVMContext is used by compilation. + void setOptPassGate(OptPassGate&); private: // Module needs access to the add/removeModule methods. diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h index 3dc4a776dba08dec356484641b0abc9929e25c20..90036c6ce248f31b5215610b9040e1034251bbf9 100644 --- a/include/llvm/IR/LegacyPassManagers.h +++ b/include/llvm/IR/LegacyPassManagers.h @@ -403,6 +403,15 @@ public: InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis(); } + /// Set the initial size of the module if the user has specified that they + /// want remarks for size. + /// Returns 0 if the remark was not requested. + unsigned initSizeRemarkInfo(Module &M); + + /// Emit a remark signifying that the number of IR instructions in the module + /// changed. + void emitInstrCountChangedRemark(Pass *P, Module &M, unsigned CountBefore); + protected: // Top level manager. PMTopLevelManager *TPM; diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h index d5218eadc4ab2de68ffab25f597e0781fb5379c2..174616c7ab1dcd521ada89374e62bde3971633eb 100644 --- a/include/llvm/IR/MDBuilder.h +++ b/include/llvm/IR/MDBuilder.h @@ -38,17 +38,17 @@ class MDBuilder { public: MDBuilder(LLVMContext &context) : Context(context) {} - /// \brief Return the given string as metadata. + /// Return the given string as metadata. MDString *createString(StringRef Str); - /// \brief Return the given constant as metadata. + /// Return the given constant as metadata. ConstantAsMetadata *createConstant(Constant *C); //===------------------------------------------------------------------===// // FPMath metadata. //===------------------------------------------------------------------===// - /// \brief Return metadata with the given settings. The special value 0.0 + /// Return metadata with the given settings. The special value 0.0 /// for the Accuracy parameter indicates the default (maximal precision) /// setting. MDNode *createFPMath(float Accuracy); @@ -57,10 +57,10 @@ public: // Prof metadata. //===------------------------------------------------------------------===// - /// \brief Return metadata containing two branch weights. + /// Return metadata containing two branch weights. MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight); - /// \brief Return metadata containing a number of branch weights. + /// Return metadata containing a number of branch weights. MDNode *createBranchWeights(ArrayRef Weights); /// Return metadata specifying that a branch or switch is unpredictable. @@ -80,17 +80,17 @@ public: // Range metadata. //===------------------------------------------------------------------===// - /// \brief Return metadata describing the range [Lo, Hi). + /// Return metadata describing the range [Lo, Hi). MDNode *createRange(const APInt &Lo, const APInt &Hi); - /// \brief Return metadata describing the range [Lo, Hi). + /// Return metadata describing the range [Lo, Hi). MDNode *createRange(Constant *Lo, Constant *Hi); //===------------------------------------------------------------------===// // Callees metadata. //===------------------------------------------------------------------===// - /// \brief Return metadata indicating the possible callees of indirect + /// Return metadata indicating the possible callees of indirect /// calls. MDNode *createCallees(ArrayRef Callees); @@ -99,28 +99,28 @@ public: //===------------------------------------------------------------------===// protected: - /// \brief Return metadata appropriate for a AA root node (scope or TBAA). + /// Return metadata appropriate for a AA root node (scope or TBAA). /// Each returned node is distinct from all other metadata and will never /// be identified (uniqued) with anything else. MDNode *createAnonymousAARoot(StringRef Name = StringRef(), MDNode *Extra = nullptr); public: - /// \brief Return metadata appropriate for a TBAA root node. Each returned + /// Return metadata appropriate for a TBAA root node. Each returned /// node is distinct from all other metadata and will never be identified /// (uniqued) with anything else. MDNode *createAnonymousTBAARoot() { return createAnonymousAARoot(); } - /// \brief Return metadata appropriate for an alias scope domain node. + /// Return metadata appropriate for an alias scope domain node. /// Each returned node is distinct from all other metadata and will never /// be identified (uniqued) with anything else. MDNode *createAnonymousAliasScopeDomain(StringRef Name = StringRef()) { return createAnonymousAARoot(Name); } - /// \brief Return metadata appropriate for an alias scope root node. + /// Return metadata appropriate for an alias scope root node. /// Each returned node is distinct from all other metadata and will never /// be identified (uniqued) with anything else. MDNode *createAnonymousAliasScope(MDNode *Domain, @@ -128,22 +128,22 @@ public: return createAnonymousAARoot(Name, Domain); } - /// \brief Return metadata appropriate for a TBAA root node with the given + /// Return metadata appropriate for a TBAA root node with the given /// name. This may be identified (uniqued) with other roots with the same /// name. MDNode *createTBAARoot(StringRef Name); - /// \brief Return metadata appropriate for an alias scope domain node with + /// Return metadata appropriate for an alias scope domain node with /// the given name. This may be identified (uniqued) with other roots with /// the same name. MDNode *createAliasScopeDomain(StringRef Name); - /// \brief Return metadata appropriate for an alias scope node with + /// Return metadata appropriate for an alias scope node with /// the given name. This may be identified (uniqued) with other scopes with /// the same name and domain. MDNode *createAliasScope(StringRef Name, MDNode *Domain); - /// \brief Return metadata for a non-root TBAA node with the given name, + /// Return metadata for a non-root TBAA node with the given name, /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. MDNode *createTBAANode(StringRef Name, MDNode *Parent, bool isConstant = false); @@ -156,33 +156,33 @@ public: Offset(Offset), Size(Size), Type(Type) {} }; - /// \brief Return metadata for a tbaa.struct node with the given + /// Return metadata for a tbaa.struct node with the given /// struct field descriptions. MDNode *createTBAAStructNode(ArrayRef Fields); - /// \brief Return metadata for a TBAA struct node in the type DAG + /// Return metadata for a TBAA struct node in the type DAG /// with the given name, a list of pairs (offset, field type in the type DAG). MDNode * createTBAAStructTypeNode(StringRef Name, ArrayRef> Fields); - /// \brief Return metadata for a TBAA scalar type node with the + /// Return metadata for a TBAA scalar type node with the /// given name, an offset and a parent in the TBAA type DAG. MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, uint64_t Offset = 0); - /// \brief Return metadata for a TBAA tag node with the given + /// Return metadata for a TBAA tag node with the given /// base type, access type and offset relative to the base type. MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, uint64_t Offset, bool IsConstant = false); - /// \brief Return metadata for a TBAA type node in the TBAA type DAG with the + /// Return metadata for a TBAA type node in the TBAA type DAG with the /// given parent type, size in bytes, type identifier and a list of fields. MDNode *createTBAATypeNode(MDNode *Parent, uint64_t Size, Metadata *Id, ArrayRef Fields = ArrayRef()); - /// \brief Return metadata for a TBAA access tag with the given base type, + /// Return metadata for a TBAA access tag with the given base type, /// final access type, offset of the access relative to the base type, size of /// the access and flag indicating whether the accessed object can be /// considered immutable for the purposes of the TBAA analysis. @@ -190,11 +190,11 @@ public: uint64_t Offset, uint64_t Size, bool IsImmutable = false); - /// \brief Return mutable version of the given mutable or immutable TBAA + /// Return mutable version of the given mutable or immutable TBAA /// access tag. MDNode *createMutableTBAAAccessTag(MDNode *Tag); - /// \brief Return metadata containing an irreducible loop header weight. + /// Return metadata containing an irreducible loop header weight. MDNode *createIrrLoopHeaderWeight(uint64_t Weight); }; diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index 03cdcab7dc47571c2f08a20d8bf83d8d1d62172d..70a03f28b488f819b9611d43c87934af74e8ace8 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -108,6 +108,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DITemplateValueParameter) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILabel) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index bc0b87a6c3480a7e1fe9f5038b99c6447fd107c1..9ac97f4224ac6ab37101f9620f4463106930c270 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -52,20 +52,20 @@ enum LLVMConstants : uint32_t { DEBUG_METADATA_VERSION = 3 // Current debug info version number. }; -/// \brief Root of the metadata hierarchy. +/// Root of the metadata hierarchy. /// /// This is a root class for typeless data in the IR. class Metadata { friend class ReplaceableMetadataImpl; - /// \brief RTTI. + /// RTTI. const unsigned char SubclassID; protected: - /// \brief Active type of storage. + /// Active type of storage. enum StorageType { Uniqued, Distinct, Temporary }; - /// \brief Storage flag for non-uniqued, otherwise unowned, metadata. + /// Storage flag for non-uniqued, otherwise unowned, metadata. unsigned char Storage; // TODO: expose remaining bits to subclasses. @@ -86,7 +86,7 @@ protected: ~Metadata() = default; - /// \brief Default handling of a changed operand, which asserts. + /// Default handling of a changed operand, which asserts. /// /// If subclasses pass themselves in as owners to a tracking node reference, /// they must provide an implementation of this method. @@ -97,7 +97,7 @@ protected: public: unsigned getMetadataID() const { return SubclassID; } - /// \brief User-friendly dump. + /// User-friendly dump. /// /// If \c M is provided, metadata nodes will be numbered canonically; /// otherwise, pointer addresses are substituted. @@ -110,7 +110,7 @@ public: void dump(const Module *M) const; /// @} - /// \brief Print. + /// Print. /// /// Prints definition of \c this. /// @@ -123,7 +123,7 @@ public: bool IsForDebug = false) const; /// @} - /// \brief Print as operand. + /// Print as operand. /// /// Prints reference of \c this. /// @@ -162,7 +162,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) { return OS; } -/// \brief Metadata wrapper in the Value hierarchy. +/// Metadata wrapper in the Value hierarchy. /// /// A member of the \a Value hierarchy to represent a reference to metadata. /// This allows, e.g., instrinsics to have metadata as operands. @@ -177,7 +177,7 @@ class MetadataAsValue : public Value { MetadataAsValue(Type *Ty, Metadata *MD); - /// \brief Drop use of metadata (during teardown). + /// Drop use of metadata (during teardown). void dropUse() { MD = nullptr; } public: @@ -198,7 +198,7 @@ private: void untrack(); }; -/// \brief API for tracking metadata references through RAUW and deletion. +/// API for tracking metadata references through RAUW and deletion. /// /// Shared API for updating \a Metadata pointers in subclasses that support /// RAUW. @@ -207,7 +207,7 @@ private: /// user-friendly tracking reference. class MetadataTracking { public: - /// \brief Track the reference to metadata. + /// Track the reference to metadata. /// /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets @@ -220,7 +220,7 @@ public: return track(&MD, *MD, static_cast(nullptr)); } - /// \brief Track the reference to metadata for \a Metadata. + /// Track the reference to metadata for \a Metadata. /// /// As \a track(Metadata*&), but with support for calling back to \c Owner to /// tell it that its operand changed. This could trigger \c Owner being @@ -229,7 +229,7 @@ public: return track(Ref, MD, &Owner); } - /// \brief Track the reference to metadata for \a MetadataAsValue. + /// Track the reference to metadata for \a MetadataAsValue. /// /// As \a track(Metadata*&), but with support for calling back to \c Owner to /// tell it that its operand changed. This could trigger \c Owner being @@ -238,13 +238,13 @@ public: return track(Ref, MD, &Owner); } - /// \brief Stop tracking a reference to metadata. + /// Stop tracking a reference to metadata. /// /// Stops \c *MD from tracking \c MD. static void untrack(Metadata *&MD) { untrack(&MD, *MD); } static void untrack(void *Ref, Metadata &MD); - /// \brief Move tracking from one reference to another. + /// Move tracking from one reference to another. /// /// Semantically equivalent to \c untrack(MD) followed by \c track(New), /// except that ownership callbacks are maintained. @@ -257,19 +257,19 @@ public: } static bool retrack(void *Ref, Metadata &MD, void *New); - /// \brief Check whether metadata is replaceable. + /// Check whether metadata is replaceable. static bool isReplaceable(const Metadata &MD); using OwnerTy = PointerUnion; private: - /// \brief Track a reference to metadata for an owner. + /// Track a reference to metadata for an owner. /// /// Generalized version of tracking. static bool track(void *Ref, Metadata &MD, OwnerTy Owner); }; -/// \brief Shared implementation of use-lists for replaceable metadata. +/// Shared implementation of use-lists for replaceable metadata. /// /// Most metadata cannot be RAUW'ed. This is a shared implementation of /// use-lists and associated API for the two that support it (\a ValueAsMetadata @@ -294,12 +294,12 @@ public: LLVMContext &getContext() const { return Context; } - /// \brief Replace all uses of this with MD. + /// Replace all uses of this with MD. /// /// Replace all uses of this with \c MD, which is allowed to be null. void replaceAllUsesWith(Metadata *MD); - /// \brief Resolve all uses of this. + /// Resolve all uses of this. /// /// Resolve all uses of this, turning off RAUW permanently. If \c /// ResolveUsers, call \a MDNode::resolve() on any users whose last operand @@ -326,7 +326,7 @@ private: static bool isReplaceable(const Metadata &MD); }; -/// \brief Value wrapper in the Metadata hierarchy. +/// Value wrapper in the Metadata hierarchy. /// /// This is a custom value handle that allows other metadata to refer to /// classes in the Value hierarchy. @@ -340,7 +340,7 @@ class ValueAsMetadata : public Metadata, ReplaceableMetadataImpl { Value *V; - /// \brief Drop users without RAUW (during teardown). + /// Drop users without RAUW (during teardown). void dropUsers() { ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false); } @@ -382,7 +382,7 @@ public: static void handleRAUW(Value *From, Value *To); protected: - /// \brief Handle collisions after \a Value::replaceAllUsesWith(). + /// Handle collisions after \a Value::replaceAllUsesWith(). /// /// RAUW isn't supported directly for \a ValueAsMetadata, but if the wrapped /// \a Value gets RAUW'ed and the target already exists, this is used to @@ -444,7 +444,7 @@ public: } }; -/// \brief Transitional API for extracting constants from Metadata. +/// Transitional API for extracting constants from Metadata. /// /// This namespace contains transitional functions for metadata that points to /// \a Constants. @@ -520,7 +520,7 @@ template struct IsValidReference { } // end namespace detail -/// \brief Check whether Metadata has a Value. +/// Check whether Metadata has a Value. /// /// As an analogue to \a isa(), check whether \c MD has an \a Value inside of /// type \c X. @@ -539,7 +539,7 @@ inline return hasa(&MD); } -/// \brief Extract a Value from Metadata. +/// Extract a Value from Metadata. /// /// As an analogue to \a cast(), extract the \a Value subclass \c X from \c MD. template @@ -554,7 +554,7 @@ inline return extract(&MD); } -/// \brief Extract a Value from Metadata, allowing null. +/// Extract a Value from Metadata, allowing null. /// /// As an analogue to \a cast_or_null(), extract the \a Value subclass \c X /// from \c MD, allowing \c MD to be null. @@ -566,7 +566,7 @@ extract_or_null(Y &&MD) { return nullptr; } -/// \brief Extract a Value from Metadata, if any. +/// Extract a Value from Metadata, if any. /// /// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X /// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a @@ -579,7 +579,7 @@ dyn_extract(Y &&MD) { return nullptr; } -/// \brief Extract a Value from Metadata, if any, allowing null. +/// Extract a Value from Metadata, if any, allowing null. /// /// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X /// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a @@ -595,7 +595,7 @@ dyn_extract_or_null(Y &&MD) { } // end namespace mdconst //===----------------------------------------------------------------------===// -/// \brief A single uniqued string. +/// A single uniqued string. /// /// These are used to efficiently contain a byte sequence for metadata. /// MDString is always unnamed. @@ -622,22 +622,22 @@ public: using iterator = StringRef::iterator; - /// \brief Pointer to the first byte of the string. + /// Pointer to the first byte of the string. iterator begin() const { return getString().begin(); } - /// \brief Pointer to one byte past the end of the string. + /// Pointer to one byte past the end of the string. iterator end() const { return getString().end(); } const unsigned char *bytes_begin() const { return getString().bytes_begin(); } const unsigned char *bytes_end() const { return getString().bytes_end(); } - /// \brief Methods for support type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDStringKind; } }; -/// \brief A collection of metadata nodes that might be associated with a +/// A collection of metadata nodes that might be associated with a /// memory access used by the alias-analysis infrastructure. struct AAMDNodes { explicit AAMDNodes(MDNode *T = nullptr, MDNode *S = nullptr, @@ -652,16 +652,16 @@ struct AAMDNodes { explicit operator bool() const { return TBAA || Scope || NoAlias; } - /// \brief The tag for type-based alias analysis. + /// The tag for type-based alias analysis. MDNode *TBAA; - /// \brief The tag for alias scope specification (used with noalias). + /// The tag for alias scope specification (used with noalias). MDNode *Scope; - /// \brief The tag specifying the noalias scope. + /// The tag specifying the noalias scope. MDNode *NoAlias; - /// \brief Given two sets of AAMDNodes that apply to the same pointer, + /// Given two sets of AAMDNodes that apply to the same pointer, /// give the best AAMDNodes that are compatible with both (i.e. a set of /// nodes whose allowable aliasing conclusions are a subset of those /// allowable by both of the inputs). However, for efficiency @@ -699,7 +699,7 @@ struct DenseMapInfo { } }; -/// \brief Tracking metadata reference owned by Metadata. +/// Tracking metadata reference owned by Metadata. /// /// Similar to \a TrackingMDRef, but it's expected to be owned by an instance /// of \a Metadata, which has the option of registering itself for callbacks to @@ -761,7 +761,7 @@ template <> struct simplify_type { static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); } }; -/// \brief Pointer to the context, with optional RAUW support. +/// Pointer to the context, with optional RAUW support. /// /// Either a raw (non-null) pointer to the \a LLVMContext, or an owned pointer /// to \a ReplaceableMetadataImpl (which has a reference to \a LLVMContext). @@ -785,7 +785,7 @@ public: operator LLVMContext &() { return getContext(); } - /// \brief Whether this contains RAUW support. + /// Whether this contains RAUW support. bool hasReplaceableUses() const { return Ptr.is(); } @@ -809,7 +809,7 @@ public: return getReplaceableUses(); } - /// \brief Assign RAUW support to this. + /// Assign RAUW support to this. /// /// Make this replaceable, taking ownership of \c ReplaceableUses (which must /// not be null). @@ -822,7 +822,7 @@ public: Ptr = ReplaceableUses.release(); } - /// \brief Drop RAUW support. + /// Drop RAUW support. /// /// Cede ownership of RAUW support, returning it. std::unique_ptr takeReplaceableUses() { @@ -843,7 +843,7 @@ struct TempMDNodeDeleter { #define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_LEAF(CLASS) #include "llvm/IR/Metadata.def" -/// \brief Metadata node. +/// Metadata node. /// /// Metadata nodes can be uniqued, like constants, or distinct. Temporary /// metadata nodes (with full support for RAUW) can be used to delay uniquing @@ -876,12 +876,12 @@ protected: void *operator new(size_t Size, unsigned NumOps); void operator delete(void *Mem); - /// \brief Required by std, but never called. + /// Required by std, but never called. void operator delete(void *, unsigned) { llvm_unreachable("Constructor throws?"); } - /// \brief Required by std, but never called. + /// Required by std, but never called. void operator delete(void *, unsigned, bool) { llvm_unreachable("Constructor throws?"); } @@ -910,10 +910,10 @@ public: static inline TempMDTuple getTemporary(LLVMContext &Context, ArrayRef MDs); - /// \brief Create a (temporary) clone of this. + /// Create a (temporary) clone of this. TempMDNode clone() const; - /// \brief Deallocate a node created by getTemporary. + /// Deallocate a node created by getTemporary. /// /// Calls \c replaceAllUsesWith(nullptr) before deleting, so any remaining /// references will be reset. @@ -921,10 +921,10 @@ public: LLVMContext &getContext() const { return Context.getContext(); } - /// \brief Replace a specific operand. + /// Replace a specific operand. void replaceOperandWith(unsigned I, Metadata *New); - /// \brief Check if node is fully resolved. + /// Check if node is fully resolved. /// /// If \a isTemporary(), this always returns \c false; if \a isDistinct(), /// this always returns \c true. @@ -941,7 +941,7 @@ public: bool isDistinct() const { return Storage == Distinct; } bool isTemporary() const { return Storage == Temporary; } - /// \brief RAUW a temporary. + /// RAUW a temporary. /// /// \pre \a isTemporary() must be \c true. void replaceAllUsesWith(Metadata *MD) { @@ -950,7 +950,7 @@ public: Context.getReplaceableUses()->replaceAllUsesWith(MD); } - /// \brief Resolve cycles. + /// Resolve cycles. /// /// Once all forward declarations have been resolved, force cycles to be /// resolved. @@ -961,7 +961,7 @@ public: /// Resolve a unique, unresolved node. void resolve(); - /// \brief Replace a temporary node with a permanent one. + /// Replace a temporary node with a permanent one. /// /// Try to create a uniqued version of \c N -- in place, if possible -- and /// return it. If \c N cannot be uniqued, return a distinct node instead. @@ -971,7 +971,7 @@ public: return cast(N.release()->replaceWithPermanentImpl()); } - /// \brief Replace a temporary node with a uniqued one. + /// Replace a temporary node with a uniqued one. /// /// Create a uniqued version of \c N -- in place, if possible -- and return /// it. Takes ownership of the temporary node. @@ -983,7 +983,7 @@ public: return cast(N.release()->replaceWithUniquedImpl()); } - /// \brief Replace a temporary node with a distinct one. + /// Replace a temporary node with a distinct one. /// /// Create a distinct version of \c N -- in place, if possible -- and return /// it. Takes ownership of the temporary node. @@ -999,7 +999,7 @@ private: MDNode *replaceWithDistinctImpl(); protected: - /// \brief Set an operand. + /// Set an operand. /// /// Sets the operand directly, without worrying about uniquing. void setOperand(unsigned I, Metadata *New); @@ -1019,14 +1019,14 @@ private: void decrementUnresolvedOperandCount(); void countUnresolvedOperands(); - /// \brief Mutate this to be "uniqued". + /// Mutate this to be "uniqued". /// /// Mutate this so that \a isUniqued(). /// \pre \a isTemporary(). /// \pre already added to uniquing set. void makeUniqued(); - /// \brief Mutate this to be "distinct". + /// Mutate this to be "distinct". /// /// Mutate this so that \a isDistinct(). /// \pre \a isTemporary(). @@ -1069,10 +1069,10 @@ public: return op_begin()[I]; } - /// \brief Return number of MDNode operands. + /// Return number of MDNode operands. unsigned getNumOperands() const { return NumOperands; } - /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -1084,10 +1084,10 @@ public: } } - /// \brief Check whether MDNode is a vtable access. + /// Check whether MDNode is a vtable access. bool isTBAAVtableAccess() const; - /// \brief Methods for metadata merging. + /// Methods for metadata merging. static MDNode *concatenate(MDNode *A, MDNode *B); static MDNode *intersect(MDNode *A, MDNode *B); static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B); @@ -1097,7 +1097,7 @@ public: static MDNode *getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B); }; -/// \brief Tuple of metadata. +/// Tuple of metadata. /// /// This is the simple \a MDNode arbitrary tuple. Nodes are uniqued by /// default based on their operands. @@ -1125,7 +1125,7 @@ class MDTuple : public MDNode { } public: - /// \brief Get the hash, if any. + /// Get the hash, if any. unsigned getHash() const { return SubclassData32; } static MDTuple *get(LLVMContext &Context, ArrayRef MDs) { @@ -1136,14 +1136,14 @@ public: return getImpl(Context, MDs, Uniqued, /* ShouldCreate */ false); } - /// \brief Return a distinct node. + /// Return a distinct node. /// /// Return a distinct node -- i.e., a node that is not uniqued. static MDTuple *getDistinct(LLVMContext &Context, ArrayRef MDs) { return getImpl(Context, MDs, Distinct); } - /// \brief Return a temporary node. + /// Return a temporary node. /// /// For use in constructing cyclic MDNode structures. A temporary MDNode is /// not uniqued, may be RAUW'd, and must be manually deleted with @@ -1153,7 +1153,7 @@ public: return TempMDTuple(getImpl(Context, MDs, Temporary)); } - /// \brief Return a (temporary) clone of this. + /// Return a (temporary) clone of this. TempMDTuple clone() const { return cloneImpl(); } static bool classof(const Metadata *MD) { @@ -1182,7 +1182,7 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const { MDNode::deleteTemporary(Node); } -/// \brief Typed iterator through MDNode operands. +/// Typed iterator through MDNode operands. /// /// An iterator that transforms an \a MDNode::iterator into an iterator over a /// particular Metadata subclass. @@ -1213,7 +1213,7 @@ public: bool operator!=(const TypedMDOperandIterator &X) const { return I != X.I; } }; -/// \brief Typed, array-like tuple of metadata. +/// Typed, array-like tuple of metadata. /// /// This is a wrapper for \a MDTuple that makes it act like an array holding a /// particular type of metadata. @@ -1314,7 +1314,7 @@ public: }; //===----------------------------------------------------------------------===// -/// \brief A tuple of MDNodes. +/// A tuple of MDNodes. /// /// Despite its name, a NamedMDNode isn't itself an MDNode. NamedMDNodes belong /// to modules, have names, and contain lists of MDNodes. @@ -1377,7 +1377,7 @@ public: NamedMDNode(const NamedMDNode &) = delete; ~NamedMDNode(); - /// \brief Drop all references and remove the node from parent module. + /// Drop all references and remove the node from parent module. void eraseFromParent(); /// Remove all uses and clear node vector. @@ -1385,7 +1385,7 @@ public: /// Drop all references to this node's operands. void clearOperands(); - /// \brief Get the module that holds this named metadata collection. + /// Get the module that holds this named metadata collection. inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 58e4bc4494f8db8b71032cc2dc497d102983a4e8..500e3a50dee5af1a472722f4117a4fe2f7c7b4d2 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -59,7 +59,7 @@ class StructType; /// A module maintains a GlobalValRefMap object that is used to hold all /// constant references to global variables in the module. When a global /// variable is destroyed, it should have no entries in the GlobalValueRefMap. -/// @brief The main container class for the LLVM Intermediate Representation. +/// The main container class for the LLVM Intermediate Representation. class Module { /// @name Types And Enumerations /// @{ @@ -207,13 +207,18 @@ public: /// @returns the module identifier as a string const std::string &getModuleIdentifier() const { return ModuleID; } + /// Returns the number of non-debug IR instructions in the module. + /// This is equivalent to the sum of the IR instruction counts of each + /// function contained in the module. + unsigned getInstructionCount(); + /// Get the module's original source file name. When compiling from /// bitcode, this is taken from a bitcode record where it was recorded. /// For other compiles it is the same as the ModuleID, which would /// contain the source file name. const std::string &getSourceFileName() const { return SourceFileName; } - /// \brief Get a short "name" for the module. + /// Get a short "name" for the module. /// /// This is useful for debugging or logging. It is essentially a convenience /// wrapper around getModuleIdentifier(). @@ -795,14 +800,14 @@ public: /// @name Utility functions for querying Debug information. /// @{ - /// \brief Returns the Number of Register ParametersDwarf Version by checking + /// Returns the Number of Register ParametersDwarf Version by checking /// module flags. unsigned getNumberRegisterParameters() const; - /// \brief Returns the Dwarf Version by checking module flags. + /// Returns the Dwarf Version by checking module flags. unsigned getDwarfVersion() const; - /// \brief Returns the CodeView Version by checking module flags. + /// Returns the CodeView Version by checking module flags. /// Returns zero if not present in module. unsigned getCodeViewFlag() const; @@ -810,10 +815,10 @@ public: /// @name Utility functions for querying and setting PIC level /// @{ - /// \brief Returns the PIC level (small or large model) + /// Returns the PIC level (small or large model) PICLevel::Level getPICLevel() const; - /// \brief Set the PIC level (small or large model) + /// Set the PIC level (small or large model) void setPICLevel(PICLevel::Level PL); /// @} @@ -821,20 +826,20 @@ public: /// @name Utility functions for querying and setting PIE level /// @{ - /// \brief Returns the PIE level (small or large model) + /// Returns the PIE level (small or large model) PIELevel::Level getPIELevel() const; - /// \brief Set the PIE level (small or large model) + /// Set the PIE level (small or large model) void setPIELevel(PIELevel::Level PL); /// @} /// @name Utility functions for querying and setting PGO summary /// @{ - /// \brief Attach profile summary metadata to this module. + /// Attach profile summary metadata to this module. void setProfileSummary(Metadata *M); - /// \brief Returns profile summary metadata + /// Returns profile summary metadata Metadata *getProfileSummary(); /// @} @@ -849,7 +854,7 @@ public: void setOwnedMemoryBuffer(std::unique_ptr MB); }; -/// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect +/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect /// the initializer elements of that global in Set and return the global itself. GlobalVariable *collectUsedGlobalVariables(const Module &M, SmallPtrSetImpl &Set, diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 45f8cd7cd512955159a945b13bfcd8081839d24c..8c858fc0b690495c04b4cd2babed8aaa9616a20c 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -47,7 +47,7 @@ template struct MappingTraits; } // end namespace yaml -/// \brief Class to accumulate and hold information about a callee. +/// Class to accumulate and hold information about a callee. struct CalleeInfo { enum class HotnessType : uint8_t { Unknown = 0, @@ -218,16 +218,16 @@ template <> struct DenseMapInfo { static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.getRef(); } }; -/// \brief Function and variable summary information to aid decisions and +/// Function and variable summary information to aid decisions and /// implementation of importing. class GlobalValueSummary { public: - /// \brief Sububclass discriminator (for dyn_cast<> et al.) + /// Sububclass discriminator (for dyn_cast<> et al.) enum SummaryKind : unsigned { AliasKind, FunctionKind, GlobalVarKind }; /// Group flags (Linkage, NotEligibleToImport, etc.) as a bitfield. struct GVFlags { - /// \brief The linkage type of the associated global value. + /// The linkage type of the associated global value. /// /// One use is to flag values that have local linkage types and need to /// have module identifier appended before placing into the combined @@ -269,7 +269,7 @@ private: /// GUID includes the module level id in the hash. GlobalValue::GUID OriginalName = 0; - /// \brief Path of module IR containing value's definition, used to locate + /// Path of module IR containing value's definition, used to locate /// module during importing. /// /// This is only used during parsing of the combined index, or when @@ -296,7 +296,7 @@ public: /// Returns the hash of the original name, it is identical to the GUID for /// externally visible symbols, but not for local ones. - GlobalValue::GUID getOriginalName() { return OriginalName; } + GlobalValue::GUID getOriginalName() const { return OriginalName; } /// Initialize the original name hash in this summary. void setOriginalName(GlobalValue::GUID Name) { OriginalName = Name; } @@ -312,7 +312,7 @@ public: StringRef modulePath() const { return ModulePath; } /// Get the flags for this GlobalValue (see \p struct GVFlags). - GVFlags flags() { return Flags; } + GVFlags flags() const { return Flags; } /// Return linkage type recorded for this global value. GlobalValue::LinkageTypes linkage() const { @@ -350,7 +350,7 @@ public: friend class ModuleSummaryIndex; }; -/// \brief Alias summary information. +/// Alias summary information. class AliasSummary : public GlobalValueSummary { GlobalValueSummary *AliaseeSummary; // AliaseeGUID is only set and accessed when we are building a combined index @@ -397,13 +397,20 @@ inline GlobalValueSummary *GlobalValueSummary::getBaseObject() { return this; } -/// \brief Function summary information to aid decisions and implementation of +/// Function summary information to aid decisions and implementation of /// importing. class FunctionSummary : public GlobalValueSummary { public: /// call edge pair. using EdgeTy = std::pair; + /// Types for -force-summary-edges-cold debugging option. + enum ForceSummaryHotnessType : unsigned { + FSHT_None, + FSHT_AllNonCritical, + FSHT_All + }; + /// An "identifier" for a virtual function. This contains the type identifier /// represented as a GUID and the offset from the address point to the virtual /// function pointer, where "address point" is as defined in the Itanium ABI: @@ -421,6 +428,26 @@ public: std::vector Args; }; + /// All type identifier related information. Because these fields are + /// relatively uncommon we only allocate space for them if necessary. + struct TypeIdInfo { + /// List of type identifiers used by this function in llvm.type.test + /// intrinsics referenced by something other than an llvm.assume intrinsic, + /// represented as GUIDs. + std::vector TypeTests; + + /// List of virtual calls made by this function using (respectively) + /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do + /// not have all constant integer arguments. + std::vector TypeTestAssumeVCalls, TypeCheckedLoadVCalls; + + /// List of virtual calls made by this function using (respectively) + /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with + /// all constant integer arguments. + std::vector TypeTestAssumeConstVCalls, + TypeCheckedLoadConstVCalls; + }; + /// Function attribute flags. Used to track if a function accesses memory, /// recurses or aliases. struct FFlags { @@ -461,25 +488,6 @@ private: /// List of call edge pairs from this function. std::vector CallGraphEdgeList; - /// All type identifier related information. Because these fields are - /// relatively uncommon we only allocate space for them if necessary. - struct TypeIdInfo { - /// List of type identifiers used by this function in llvm.type.test - /// intrinsics other than by an llvm.assume intrinsic, represented as GUIDs. - std::vector TypeTests; - - /// List of virtual calls made by this function using (respectively) - /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics that do - /// not have all constant integer arguments. - std::vector TypeTestAssumeVCalls, TypeCheckedLoadVCalls; - - /// List of virtual calls made by this function using (respectively) - /// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics with - /// all constant integer arguments. - std::vector TypeTestAssumeConstVCalls, - TypeCheckedLoadConstVCalls; - }; - std::unique_ptr TIdInfo; public: @@ -509,7 +517,7 @@ public: } /// Get function attribute flags. - FFlags &fflags() { return FunFlags; } + FFlags fflags() const { return FunFlags; } /// Get the instruction count recorded for this function. unsigned instCount() const { return InstCount; } @@ -569,6 +577,8 @@ public: TIdInfo->TypeTests.push_back(Guid); } + const TypeIdInfo *getTypeIdInfo() const { return TIdInfo.get(); }; + friend struct GraphTraits; }; @@ -606,7 +616,7 @@ template <> struct DenseMapInfo { } }; -/// \brief Global variable summary information to aid decisions and +/// Global variable summary information to aid decisions and /// implementation of importing. /// /// Currently this doesn't add anything to the base \p GlobalValueSummary, @@ -857,6 +867,12 @@ public: } bool isGUIDLive(GlobalValue::GUID GUID) const; + /// Return a ValueInfo for the index value_type (convenient when iterating + /// index). + ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const { + return ValueInfo(IsAnalysis, &R); + } + /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo(). ValueInfo getValueInfo(GlobalValue::GUID GUID) const { auto I = GlobalValueMap.find(GUID); @@ -1041,6 +1057,12 @@ public: void collectDefinedGVSummariesPerModule( StringMap &ModuleToDefinedGVSummaries) const; + /// Print to an output stream. + void print(raw_ostream &OS, bool IsForDebug = false) const; + + /// Dump to stderr (for debugging). + void dump() const; + /// Export summary to dot file for GraphViz. void exportToDot(raw_ostream& OS) const; diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 01746e4b6a2919e6fa7831f52a85c4ac1f73a399..939cec7f4aa4a292693cdd42fc3efebf96b45b32 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -207,17 +207,28 @@ public: bool isFast() const { return all(); } /// Flag setters - void setAllowReassoc() { Flags |= AllowReassoc; } - void setNoNaNs() { Flags |= NoNaNs; } - void setNoInfs() { Flags |= NoInfs; } - void setNoSignedZeros() { Flags |= NoSignedZeros; } - void setAllowReciprocal() { Flags |= AllowReciprocal; } - // TODO: Change the other set* functions to take a parameter? - void setAllowContract(bool B) { + void setAllowReassoc(bool B = true) { + Flags = (Flags & ~AllowReassoc) | B * AllowReassoc; + } + void setNoNaNs(bool B = true) { + Flags = (Flags & ~NoNaNs) | B * NoNaNs; + } + void setNoInfs(bool B = true) { + Flags = (Flags & ~NoInfs) | B * NoInfs; + } + void setNoSignedZeros(bool B = true) { + Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros; + } + void setAllowReciprocal(bool B = true) { + Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal; + } + void setAllowContract(bool B = true) { Flags = (Flags & ~AllowContract) | B * AllowContract; } - void setApproxFunc() { Flags |= ApproxFunc; } - void setFast() { set(); } + void setApproxFunc(bool B = true) { + Flags = (Flags & ~ApproxFunc) | B * ApproxFunc; + } + void setFast(bool B = true) { B ? set() : clear(); } void operator&=(const FastMathFlags &OtherFlags) { Flags &= OtherFlags.Flags; @@ -507,7 +518,7 @@ public: }); } - /// \brief Accumulate the constant address offset of this GEP if possible. + /// Accumulate the constant address offset of this GEP if possible. /// /// This routine accepts an APInt into which it will accumulate the constant /// offset of this GEP if the GEP is in fact constant. If the GEP is not diff --git a/include/llvm/IR/OptBisect.h b/include/llvm/IR/OptBisect.h index cfc724c1678259ed13455fab71dce885dca8e1a2..aa24c94c01302bcde3aeaaa717b1cc691cfd69ce 100644 --- a/include/llvm/IR/OptBisect.h +++ b/include/llvm/IR/OptBisect.h @@ -47,7 +47,7 @@ public: /// optimization-related problems. class OptBisect : public OptPassGate { public: - /// \brief Default constructor, initializes the OptBisect state based on the + /// Default constructor, initializes the OptBisect state based on the /// -opt-bisect-limit command line argument. /// /// By default, bisection is disabled. diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 4f838a719512f9f6d6b984b6c99207a8a56baabe..a5d4aaf71c0e800d680d0b2acf9d70f9b1f5e67c 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -152,17 +152,17 @@ private: /// ``` class PreservedAnalyses { public: - /// \brief Convenience factory function for the empty preserved set. + /// Convenience factory function for the empty preserved set. static PreservedAnalyses none() { return PreservedAnalyses(); } - /// \brief Construct a special preserved set that preserves all passes. + /// Construct a special preserved set that preserves all passes. static PreservedAnalyses all() { PreservedAnalyses PA; PA.PreservedIDs.insert(&AllAnalysesKey); return PA; } - /// \brief Construct a preserved analyses object with a single preserved set. + /// Construct a preserved analyses object with a single preserved set. template static PreservedAnalyses allInSet() { PreservedAnalyses PA; @@ -173,7 +173,7 @@ public: /// Mark an analysis as preserved. template void preserve() { preserve(AnalysisT::ID()); } - /// \brief Given an analysis's ID, mark the analysis as preserved, adding it + /// Given an analysis's ID, mark the analysis as preserved, adding it /// to the set. void preserve(AnalysisKey *ID) { // Clear this ID from the explicit not-preserved set if present. @@ -218,7 +218,7 @@ public: NotPreservedAnalysisIDs.insert(ID); } - /// \brief Intersect this set with another in place. + /// Intersect this set with another in place. /// /// This is a mutating operation on this preserved set, removing all /// preserved passes which are not also preserved in the argument. @@ -240,7 +240,7 @@ public: PreservedIDs.erase(ID); } - /// \brief Intersect this set with a temporary other set in place. + /// Intersect this set with a temporary other set in place. /// /// This is a mutating operation on this preserved set, removing all /// preserved passes which are not also preserved in the argument. @@ -402,7 +402,7 @@ struct AnalysisInfoMixin : PassInfoMixin { } }; -/// \brief Manages a sequence of passes over a particular unit of IR. +/// Manages a sequence of passes over a particular unit of IR. /// /// A pass manager contains a sequence of passes to run over a particular unit /// of IR (e.g. Functions, Modules). It is itself a valid pass over that unit of @@ -420,7 +420,7 @@ template > { public: - /// \brief Construct a pass manager. + /// Construct a pass manager. /// /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs(). explicit PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {} @@ -439,7 +439,7 @@ public: return *this; } - /// \brief Run all of the passes in this manager over the given unit of IR. + /// Run all of the passes in this manager over the given unit of IR. /// ExtraArgs are passed to each pass. PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) { @@ -496,21 +496,21 @@ private: std::vector> Passes; - /// \brief Flag indicating whether we should do debug logging. + /// Flag indicating whether we should do debug logging. bool DebugLogging; }; extern template class PassManager; -/// \brief Convenience typedef for a pass manager over modules. +/// Convenience typedef for a pass manager over modules. using ModulePassManager = PassManager; extern template class PassManager; -/// \brief Convenience typedef for a pass manager over functions. +/// Convenience typedef for a pass manager over functions. using FunctionPassManager = PassManager; -/// \brief A container for analyses that lazily runs them and caches their +/// A container for analyses that lazily runs them and caches their /// results. /// /// This class can manage analyses for any IR unit where the address of the IR @@ -527,7 +527,7 @@ private: detail::AnalysisPassConcept; - /// \brief List of analysis pass IDs and associated concept pointers. + /// List of analysis pass IDs and associated concept pointers. /// /// Requires iterators to be valid across appending new entries and arbitrary /// erases. Provides the analysis ID to enable finding iterators to a given @@ -536,10 +536,10 @@ private: using AnalysisResultListT = std::list>>; - /// \brief Map type from IRUnitT pointer to our custom list type. + /// Map type from IRUnitT pointer to our custom list type. using AnalysisResultListMapT = DenseMap; - /// \brief Map type from a pair of analysis ID and IRUnitT pointer to an + /// Map type from a pair of analysis ID and IRUnitT pointer to an /// iterator into a particular result list (which is where the actual analysis /// result is stored). using AnalysisResultMapT = @@ -634,14 +634,14 @@ public: const AnalysisResultMapT &Results; }; - /// \brief Construct an empty analysis manager. + /// Construct an empty analysis manager. /// /// If \p DebugLogging is true, we'll log our progress to llvm::dbgs(). AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {} AnalysisManager(AnalysisManager &&) = default; AnalysisManager &operator=(AnalysisManager &&) = default; - /// \brief Returns true if the analysis manager has an empty results cache. + /// Returns true if the analysis manager has an empty results cache. bool empty() const { assert(AnalysisResults.empty() == AnalysisResultLists.empty() && "The storage and index of analysis results disagree on how many " @@ -649,7 +649,7 @@ public: return AnalysisResults.empty(); } - /// \brief Clear any cached analysis results for a single unit of IR. + /// Clear any cached analysis results for a single unit of IR. /// /// This doesn't invalidate, but instead simply deletes, the relevant results. /// It is useful when the IR is being removed and we want to clear out all the @@ -669,7 +669,7 @@ public: AnalysisResultLists.erase(ResultsListI); } - /// \brief Clear all analysis results cached by this AnalysisManager. + /// Clear all analysis results cached by this AnalysisManager. /// /// Like \c clear(IRUnitT&), this doesn't invalidate the results; it simply /// deletes them. This lets you clean up the AnalysisManager when the set of @@ -680,7 +680,7 @@ public: AnalysisResultLists.clear(); } - /// \brief Get the result of an analysis pass for a given IR unit. + /// Get the result of an analysis pass for a given IR unit. /// /// Runs the analysis if a cached result is not available. template @@ -697,7 +697,7 @@ public: return static_cast(ResultConcept).Result; } - /// \brief Get the cached result of an analysis pass for a given IR unit. + /// Get the cached result of an analysis pass for a given IR unit. /// /// This method never runs the analysis. /// @@ -718,7 +718,7 @@ public: return &static_cast(ResultConcept)->Result; } - /// \brief Register an analysis pass with the manager. + /// Register an analysis pass with the manager. /// /// The parameter is a callable whose result is an analysis pass. This allows /// passing in a lambda to construct the analysis. @@ -752,7 +752,7 @@ public: return true; } - /// \brief Invalidate a specific analysis pass for an IR module. + /// Invalidate a specific analysis pass for an IR module. /// /// Note that the analysis result can disregard invalidation, if it determines /// it is in fact still valid. @@ -762,7 +762,7 @@ public: invalidateImpl(PassT::ID(), IR); } - /// \brief Invalidate cached analyses for an IR unit. + /// Invalidate cached analyses for an IR unit. /// /// Walk through all of the analyses pertaining to this unit of IR and /// invalidate them, unless they are preserved by the PreservedAnalyses set. @@ -829,7 +829,7 @@ public: } private: - /// \brief Look up a registered analysis pass. + /// Look up a registered analysis pass. PassConceptT &lookUpPass(AnalysisKey *ID) { typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(ID); assert(PI != AnalysisPasses.end() && @@ -837,7 +837,7 @@ private: return *PI->second; } - /// \brief Look up a registered analysis pass. + /// Look up a registered analysis pass. const PassConceptT &lookUpPass(AnalysisKey *ID) const { typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(ID); assert(PI != AnalysisPasses.end() && @@ -845,7 +845,7 @@ private: return *PI->second; } - /// \brief Get an analysis result, running the pass if necessary. + /// Get an analysis result, running the pass if necessary. ResultConceptT &getResultImpl(AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) { typename AnalysisResultMapT::iterator RI; @@ -874,14 +874,14 @@ private: return *RI->second->second; } - /// \brief Get a cached analysis result or return null. + /// Get a cached analysis result or return null. ResultConceptT *getCachedResultImpl(AnalysisKey *ID, IRUnitT &IR) const { typename AnalysisResultMapT::const_iterator RI = AnalysisResults.find({ID, &IR}); return RI == AnalysisResults.end() ? nullptr : &*RI->second->second; } - /// \brief Invalidate a function pass result. + /// Invalidate a function pass result. void invalidateImpl(AnalysisKey *ID, IRUnitT &IR) { typename AnalysisResultMapT::iterator RI = AnalysisResults.find({ID, &IR}); @@ -895,38 +895,38 @@ private: AnalysisResults.erase(RI); } - /// \brief Map type from module analysis pass ID to pass concept pointer. + /// Map type from module analysis pass ID to pass concept pointer. using AnalysisPassMapT = DenseMap>; - /// \brief Collection of module analysis passes, indexed by ID. + /// Collection of module analysis passes, indexed by ID. AnalysisPassMapT AnalysisPasses; - /// \brief Map from function to a list of function analysis results. + /// Map from function to a list of function analysis results. /// /// Provides linear time removal of all analysis results for a function and /// the ultimate storage for a particular cached analysis result. AnalysisResultListMapT AnalysisResultLists; - /// \brief Map from an analysis ID and function to a particular cached + /// Map from an analysis ID and function to a particular cached /// analysis result. AnalysisResultMapT AnalysisResults; - /// \brief Indicates whether we log to \c llvm::dbgs(). + /// Indicates whether we log to \c llvm::dbgs(). bool DebugLogging; }; extern template class AnalysisManager; -/// \brief Convenience typedef for the Module analysis manager. +/// Convenience typedef for the Module analysis manager. using ModuleAnalysisManager = AnalysisManager; extern template class AnalysisManager; -/// \brief Convenience typedef for the Function analysis manager. +/// Convenience typedef for the Function analysis manager. using FunctionAnalysisManager = AnalysisManager; -/// \brief An analysis over an "outer" IR unit that provides access to an +/// An analysis over an "outer" IR unit that provides access to an /// analysis manager over an "inner" IR unit. The inner unit must be contained /// in the outer unit. /// @@ -977,10 +977,10 @@ public: return *this; } - /// \brief Accessor for the analysis manager. + /// Accessor for the analysis manager. AnalysisManagerT &getManager() { return *InnerAM; } - /// \brief Handler for invalidation of the outer IR unit, \c IRUnitT. + /// Handler for invalidation of the outer IR unit, \c IRUnitT. /// /// If the proxy analysis itself is not preserved, we assume that the set of /// inner IR objects contained in IRUnit may have changed. In this case, @@ -1001,7 +1001,7 @@ public: explicit InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {} - /// \brief Run the analysis pass and create our proxy result object. + /// Run the analysis pass and create our proxy result object. /// /// This doesn't do any interesting work; it is primarily used to insert our /// proxy result object into the outer analysis cache so that we can proxy @@ -1040,7 +1040,7 @@ bool FunctionAnalysisManagerModuleProxy::Result::invalidate( extern template class InnerAnalysisManagerProxy; -/// \brief An analysis over an "inner" IR unit that provides access to an +/// An analysis over an "inner" IR unit that provides access to an /// analysis manager over a "outer" IR unit. The inner unit must be contained /// in the outer unit. /// @@ -1063,7 +1063,7 @@ class OuterAnalysisManagerProxy : public AnalysisInfoMixin< OuterAnalysisManagerProxy> { public: - /// \brief Result proxy object for \c OuterAnalysisManagerProxy. + /// Result proxy object for \c OuterAnalysisManagerProxy. class Result { public: explicit Result(const AnalysisManagerT &AM) : AM(&AM) {} @@ -1130,7 +1130,7 @@ public: OuterAnalysisManagerProxy(const AnalysisManagerT &AM) : AM(&AM) {} - /// \brief Run the analysis pass and create our proxy result object. + /// Run the analysis pass and create our proxy result object. /// Nothing to see here, it just forwards the \c AM reference into the /// result. Result run(IRUnitT &, AnalysisManager &, @@ -1157,7 +1157,7 @@ extern template class OuterAnalysisManagerProxy; -/// \brief Trivial adaptor that maps from a module to its functions. +/// Trivial adaptor that maps from a module to its functions. /// /// Designed to allow composition of a FunctionPass(Manager) and /// a ModulePassManager, by running the FunctionPass(Manager) over every @@ -1187,7 +1187,7 @@ public: explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) : Pass(std::move(Pass)) {} - /// \brief Runs the function pass across every function in the module. + /// Runs the function pass across every function in the module. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) { FunctionAnalysisManager &FAM = AM.getResult(M).getManager(); @@ -1223,7 +1223,7 @@ private: FunctionPassT Pass; }; -/// \brief A function to deduce a function pass type and wrap it in the +/// A function to deduce a function pass type and wrap it in the /// templated adaptor. template ModuleToFunctionPassAdaptor @@ -1231,7 +1231,7 @@ createModuleToFunctionPassAdaptor(FunctionPassT Pass) { return ModuleToFunctionPassAdaptor(std::move(Pass)); } -/// \brief A utility pass template to force an analysis result to be available. +/// A utility pass template to force an analysis result to be available. /// /// If there are extra arguments at the pass's run level there may also be /// extra arguments to the analysis manager's \c getResult routine. We can't @@ -1246,7 +1246,7 @@ template > { - /// \brief Run this pass over some unit of IR. + /// Run this pass over some unit of IR. /// /// This pass can be run over any unit of IR and use any analysis manager /// provided they satisfy the basic API requirements. When this pass is @@ -1261,12 +1261,12 @@ struct RequireAnalysisPass } }; -/// \brief A no-op pass template which simply forces a specific analysis result +/// A no-op pass template which simply forces a specific analysis result /// to be invalidated. template struct InvalidateAnalysisPass : PassInfoMixin> { - /// \brief Run this pass over some unit of IR. + /// Run this pass over some unit of IR. /// /// This pass can be run over any unit of IR and use any analysis manager, /// provided they satisfy the basic API requirements. When this pass is @@ -1280,12 +1280,12 @@ struct InvalidateAnalysisPass } }; -/// \brief A utility pass that does nothing, but preserves no analyses. +/// A utility pass that does nothing, but preserves no analyses. /// /// Because this preserves no analyses, any analysis passes queried after this /// pass runs will recompute fresh results. struct InvalidateAllAnalysesPass : PassInfoMixin { - /// \brief Run this pass over some unit of IR. + /// Run this pass over some unit of IR. template PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) { return PreservedAnalyses::none(); diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h index 9195d4dfa4287d26729ecca5cc54653e2a4f6b69..16a3258b41210053afea054180e3458a7b189bda 100644 --- a/include/llvm/IR/PassManagerInternal.h +++ b/include/llvm/IR/PassManagerInternal.h @@ -29,17 +29,17 @@ template class AllAnalysesOn; template class AnalysisManager; class PreservedAnalyses; -/// \brief Implementation details of the pass manager interfaces. +/// Implementation details of the pass manager interfaces. namespace detail { -/// \brief Template for the abstract base class used to dispatch +/// Template for the abstract base class used to dispatch /// polymorphically over pass objects. template struct PassConcept { // Boiler plate necessary for the container of derived classes. virtual ~PassConcept() = default; - /// \brief The polymorphic API which runs the pass over a given IR entity. + /// The polymorphic API which runs the pass over a given IR entity. /// /// Note that actual pass object can omit the analysis manager argument if /// desired. Also that the analysis manager may be null if there is no @@ -47,11 +47,11 @@ struct PassConcept { virtual PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) = 0; - /// \brief Polymorphic method to access the name of a pass. + /// Polymorphic method to access the name of a pass. virtual StringRef name() = 0; }; -/// \brief A template wrapper used to implement the polymorphic API. +/// A template wrapper used to implement the polymorphic API. /// /// Can be instantiated for any object which provides a \c run method accepting /// an \c IRUnitT& and an \c AnalysisManager&. It requires the pass to @@ -85,7 +85,7 @@ struct PassModel : PassConcept { PassT Pass; }; -/// \brief Abstract concept of an analysis result. +/// Abstract concept of an analysis result. /// /// This concept is parameterized over the IR unit that this result pertains /// to. @@ -93,7 +93,7 @@ template struct AnalysisResultConcept { virtual ~AnalysisResultConcept() = default; - /// \brief Method to try and mark a result as invalid. + /// Method to try and mark a result as invalid. /// /// When the outer analysis manager detects a change in some underlying /// unit of the IR, it will call this method on all of the results cached. @@ -112,7 +112,7 @@ struct AnalysisResultConcept { InvalidatorT &Inv) = 0; }; -/// \brief SFINAE metafunction for computing whether \c ResultT provides an +/// SFINAE metafunction for computing whether \c ResultT provides an /// \c invalidate member function. template class ResultHasInvalidateMethod { using EnabledType = char; @@ -148,7 +148,7 @@ public: enum { Value = sizeof(check(rank<2>())) == sizeof(EnabledType) }; }; -/// \brief Wrapper to model the analysis result concept. +/// Wrapper to model the analysis result concept. /// /// By default, this will implement the invalidate method with a trivial /// implementation so that the actual analysis result doesn't need to provide @@ -160,7 +160,7 @@ template ::Value> struct AnalysisResultModel; -/// \brief Specialization of \c AnalysisResultModel which provides the default +/// Specialization of \c AnalysisResultModel which provides the default /// invalidate functionality. template @@ -184,7 +184,7 @@ struct AnalysisResultModel @@ -223,7 +223,7 @@ struct AnalysisResultModel &AM, ExtraArgTs... ExtraArgs) = 0; - /// \brief Polymorphic method to access the name of a pass. + /// Polymorphic method to access the name of a pass. virtual StringRef name() = 0; }; -/// \brief Wrapper to model the analysis pass concept. +/// Wrapper to model the analysis pass concept. /// /// Can wrap any type which implements a suitable \c run method. The method /// must accept an \c IRUnitT& and an \c AnalysisManager& as arguments @@ -283,7 +283,7 @@ struct AnalysisPassModel : AnalysisPassConcept; - /// \brief The model delegates to the \c PassT::run method. + /// The model delegates to the \c PassT::run method. /// /// The return is wrapped in an \c AnalysisResultModel. std::unique_ptr< @@ -293,7 +293,7 @@ struct AnalysisPassModel : AnalysisPassConcept(Pass.run(IR, AM, ExtraArgs...)); } - /// \brief The model delegates to a static \c PassT::name method. + /// The model delegates to a static \c PassT::name method. /// /// The returned string ref must point to constant immutable data! StringRef name() override { return PassT::name(); } diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 304b84bc85d2a0da96279f1f3ff73a9164295d7d..dcca931b16dbc3a67b9385827382934033f9b36d 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -132,18 +132,6 @@ inline match_combine_and m_CombineAnd(const LTy &L, const RTy &R) { return match_combine_and(L, R); } -struct match_zero { - template bool match(ITy *V) { - if (const auto *C = dyn_cast(V)) - return C->isNullValue(); - return false; - } -}; - -/// Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. -inline match_zero m_Zero() { return match_zero(); } - struct apint_match { const APInt *&Res; @@ -365,6 +353,27 @@ inline cst_pred_ty m_One() { return cst_pred_ty(); } +struct is_zero_int { + bool isValue(const APInt &C) { return C.isNullValue(); } +}; +/// Match an integer 0 or a vector with all elements equal to 0. +/// For vectors, this includes constants with undefined elements. +inline cst_pred_ty m_ZeroInt() { + return cst_pred_ty(); +} + +struct is_zero { + template bool match(ITy *V) { + auto *C = dyn_cast(V); + return C && (C->isNullValue() || cst_pred_ty().match(C)); + } +}; +/// Match any null constant or a vector with all elements equal to 0. +/// For vectors, this includes constants with undefined elements. +inline is_zero m_Zero() { + return is_zero(); +} + struct is_power2 { bool isValue(const APInt &C) { return C.isPowerOf2(); } }; @@ -480,6 +489,22 @@ struct specificval_ty { /// Match if we have a specific specified value. inline specificval_ty m_Specific(const Value *V) { return V; } +/// Stores a reference to the Value *, not the Value * itself, +/// thus can be used in commutative matchers. +template struct deferredval_ty { + Class *const &Val; + + deferredval_ty(Class *const &V) : Val(V) {} + + template bool match(ITy *const V) { return V == Val; } +}; + +/// A commutative-friendly version of m_Specific(). +inline deferredval_ty m_Deferred(Value *const &V) { return V; } +inline deferredval_ty m_Deferred(const Value *const &V) { + return V; +} + /// Match a specified floating point value or vector of all elements of /// that value. struct specific_fpval { @@ -553,13 +578,15 @@ struct AnyBinaryOp_match { LHS_t L; RHS_t R; + // The evaluation order is always stable, regardless of Commutability. + // The LHS is always matched first. AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template bool match(OpTy *V) { if (auto *I = dyn_cast(V)) return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || - (Commutable && R.match(I->getOperand(0)) && - L.match(I->getOperand(1))); + (Commutable && L.match(I->getOperand(1)) && + R.match(I->getOperand(0))); return false; } }; @@ -579,20 +606,22 @@ struct BinaryOp_match { LHS_t L; RHS_t R; + // The evaluation order is always stable, regardless of Commutability. + // The LHS is always matched first. BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template bool match(OpTy *V) { if (V->getValueID() == Value::InstructionVal + Opcode) { auto *I = cast(V); return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || - (Commutable && R.match(I->getOperand(0)) && - L.match(I->getOperand(1))); + (Commutable && L.match(I->getOperand(1)) && + R.match(I->getOperand(0))); } if (auto *CE = dyn_cast(V)) return CE->getOpcode() == Opcode && ((L.match(CE->getOperand(0)) && R.match(CE->getOperand(1))) || - (Commutable && R.match(CE->getOperand(0)) && - L.match(CE->getOperand(1)))); + (Commutable && L.match(CE->getOperand(1)) && + R.match(CE->getOperand(0)))); return false; } }; @@ -621,6 +650,13 @@ inline BinaryOp_match m_FSub(const LHS &L, return BinaryOp_match(L, R); } +/// Match 'fneg X' as 'fsub -0.0, X'. +template +inline BinaryOp_match, RHS, Instruction::FSub> +m_FNeg(const RHS &X) { + return m_FSub(m_NegZeroFP(), X); +} + template inline BinaryOp_match m_Mul(const LHS &L, const RHS &R) { @@ -910,14 +946,16 @@ struct CmpClass_match { LHS_t L; RHS_t R; + // The evaluation order is always stable, regardless of Commutability. + // The LHS is always matched first. CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS) : Predicate(Pred), L(LHS), R(RHS) {} template bool match(OpTy *V) { if (auto *I = dyn_cast(V)) if ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || - (Commutable && R.match(I->getOperand(0)) && - L.match(I->getOperand(1)))) { + (Commutable && L.match(I->getOperand(1)) && + R.match(I->getOperand(0)))) { Predicate = I->getPredicate(); return true; } @@ -1181,31 +1219,6 @@ private: /// Match an integer negate. template inline neg_match m_Neg(const LHS &L) { return L; } -template struct fneg_match { - LHS_t L; - - fneg_match(const LHS_t &LHS) : L(LHS) {} - - template bool match(OpTy *V) { - if (auto *O = dyn_cast(V)) - if (O->getOpcode() == Instruction::FSub) - return matchIfFNeg(O->getOperand(0), O->getOperand(1)); - return false; - } - -private: - bool matchIfFNeg(Value *LHS, Value *RHS) { - if (const auto *C = dyn_cast(LHS)) - return C->isNegativeZeroValue() && L.match(RHS); - return false; - } -}; - -/// Match a floating point negate. -template inline fneg_match m_FNeg(const LHS &L) { - return L; -} - //===----------------------------------------------------------------------===// // Matchers for control flow. // @@ -1260,6 +1273,8 @@ struct MaxMin_match { LHS_t L; RHS_t R; + // The evaluation order is always stable, regardless of Commutability. + // The LHS is always matched first. MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template bool match(OpTy *V) { @@ -1286,7 +1301,7 @@ struct MaxMin_match { return false; // It does! Bind the operands. return (L.match(LHS) && R.match(RHS)) || - (Commutable && R.match(LHS) && L.match(RHS)); + (Commutable && L.match(RHS) && R.match(LHS)); } }; diff --git a/include/llvm/IR/ProfileSummary.h b/include/llvm/IR/ProfileSummary.h index d85ce8c443ecbb084fe02da481010bc3a92dcbe2..e38663770a13935cecc18f436a9eb2bf74bfabc9 100644 --- a/include/llvm/IR/ProfileSummary.h +++ b/include/llvm/IR/ProfileSummary.h @@ -51,7 +51,7 @@ private: SummaryEntryVector DetailedSummary; uint64_t TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount; uint32_t NumCounts, NumFunctions; - /// \brief Return detailed summary as metadata. + /// Return detailed summary as metadata. Metadata *getDetailedSummaryMD(LLVMContext &Context); public: @@ -67,9 +67,9 @@ public: NumCounts(NumCounts), NumFunctions(NumFunctions) {} Kind getKind() const { return PSK; } - /// \brief Return summary information as metadata. + /// Return summary information as metadata. Metadata *getMD(LLVMContext &Context); - /// \brief Construct profile summary from metdata. + /// Construct profile summary from metdata. static ProfileSummary *getFromMD(Metadata *MD); SummaryEntryVector &getDetailedSummary() { return DetailedSummary; } uint32_t getNumFunctions() { return NumFunctions; } diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index a87f67ca707b9cd99a3384e6b6419ded2a974c8a..c8e905b21a306b8419d4af0907f37c216e5eb0cf 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -196,7 +196,7 @@ public: return make_range(arg_begin(), arg_end()); } - /// \brief Return true if the call or the callee has the given attribute. + /// Return true if the call or the callee has the given attribute. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { Function *F = getCalledFunction(); return getCallSite().paramHasAttr(i + CallArgsBeginPos, A) || diff --git a/include/llvm/IR/TrackingMDRef.h b/include/llvm/IR/TrackingMDRef.h index bdec904ad1e12d0f9de52e6724cbfb8a1ab5fbbf..084efada221fdfe9355281c2502f8c34537d1efa 100644 --- a/include/llvm/IR/TrackingMDRef.h +++ b/include/llvm/IR/TrackingMDRef.h @@ -20,7 +20,7 @@ namespace llvm { -/// \brief Tracking metadata reference. +/// Tracking metadata reference. /// /// This class behaves like \a TrackingVH, but for metadata. class TrackingMDRef { @@ -70,7 +70,7 @@ public: track(); } - /// \brief Check whether this has a trivial destructor. + /// Check whether this has a trivial destructor. /// /// If \c MD isn't replaceable, the destructor will be a no-op. bool hasTrivialDestructor() const { @@ -100,7 +100,7 @@ private: } }; -/// \brief Typed tracking ref. +/// Typed tracking ref. /// /// Track refererences of a particular type. It's useful to use this for \a /// MDNode and \a ValueAsMetadata. @@ -135,7 +135,7 @@ public: void reset() { Ref.reset(); } void reset(T *MD) { Ref.reset(static_cast(MD)); } - /// \brief Check whether this has a trivial destructor. + /// Check whether this has a trivial destructor. bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); } }; diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index 39a797643872b2f5640c5d8b5fe9c4a2d23e0141..ae120645dbd6c70ae0afe3f259a615b6b06c476e 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -229,7 +229,7 @@ public: /// Return true if this type could be converted with a lossless BitCast to /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the /// same size only where no re-interpretation of the bits is done. - /// @brief Determine if this type could be losslessly bitcast to Ty + /// Determine if this type could be losslessly bitcast to Ty bool canLosslesslyBitCastTo(Type *Ty) const; /// Return true if this type is empty, that is, it has no elements or all of diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 0ac13935c7cea0e42d71e3c0e05c5703ece0a4db..25c44e0871a9a44b5d679e42107ceca41cba807e 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -36,7 +36,7 @@ template struct simplify_type; class User; class Value; -/// \brief A Use represents the edge between a Value definition and its users. +/// A Use represents the edge between a Value definition and its users. /// /// This is notionally a two-dimensional linked list. It supports traversing /// all of the uses for a particular value definition. It also supports jumping @@ -57,7 +57,7 @@ class Use { public: Use(const Use &U) = delete; - /// \brief Provide a fast substitute to std::swap + /// Provide a fast substitute to std::swap /// that also works with less standard-compliant compilers void swap(Use &RHS); @@ -107,7 +107,7 @@ public: operator Value *() const { return Val; } Value *get() const { return Val; } - /// \brief Returns the User that contains this Use. + /// Returns the User that contains this Use. /// /// For an instruction operand, for example, this will return the /// instruction. @@ -123,16 +123,16 @@ public: Use *getNext() const { return Next; } - /// \brief Return the operand # of this use in its User. + /// Return the operand # of this use in its User. unsigned getOperandNo() const; - /// \brief Initializes the waymarking tags on an array of Uses. + /// Initializes the waymarking tags on an array of Uses. /// /// This sets up the array of Uses such that getUser() can find the User from /// any of those Uses. static Use *initTags(Use *Start, Use *Stop); - /// \brief Destroys Use operands when the number of operands of + /// Destroys Use operands when the number of operands of /// a User changes. static void zap(Use *Start, const Use *Stop, bool del = false); @@ -161,7 +161,7 @@ private: } }; -/// \brief Allow clients to treat uses just like values when using +/// Allow clients to treat uses just like values when using /// casting operators. template <> struct simplify_type { using SimpleType = Value *; diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h index a8b394fc6302e847dfd74a93a64da1273c415e02..b6bb0f19a0aaf6264437edfbfde7589c50e0de61 100644 --- a/include/llvm/IR/UseListOrder.h +++ b/include/llvm/IR/UseListOrder.h @@ -23,7 +23,7 @@ namespace llvm { class Function; class Value; -/// \brief Structure to hold a use-list order. +/// Structure to hold a use-list order. struct UseListOrder { const Value *V = nullptr; const Function *F = nullptr; diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 9d30be0270e1aad467f03da79e800abded86d7ea..d6a603ce845d17dbf571fbafc9d6255d2c48d614 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -36,7 +36,7 @@ namespace llvm { template class ArrayRef; template class MutableArrayRef; -/// \brief Compile-time customization of User operands. +/// Compile-time customization of User operands. /// /// Customizes operand-related allocators and accessors. template @@ -81,13 +81,13 @@ protected: "Error in initializing hung off uses for User"); } - /// \brief Allocate the array of Uses, followed by a pointer + /// Allocate the array of Uses, followed by a pointer /// (with bottom bit set) to the User. /// \param IsPhi identifies callers which are phi nodes and which need /// N BasicBlock* allocated along with N void allocHungoffUses(unsigned N, bool IsPhi = false); - /// \brief Grow the number of hung off uses. Note that allocHungoffUses + /// Grow the number of hung off uses. Note that allocHungoffUses /// should be called if there are no uses. void growHungoffUses(unsigned N, bool IsPhi = false); @@ -97,9 +97,9 @@ protected: public: User(const User &) = delete; - /// \brief Free memory allocated for User and Use objects. + /// Free memory allocated for User and Use objects. void operator delete(void *Usr); - /// \brief Placement delete - required by std, called if the ctor throws. + /// Placement delete - required by std, called if the ctor throws. void operator delete(void *Usr, unsigned) { // Note: If a subclass manipulates the information which is required to calculate the // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has @@ -111,7 +111,7 @@ public: llvm_unreachable("Constructor throws?"); #endif } - /// \brief Placement delete - required by std, called if the ctor throws. + /// Placement delete - required by std, called if the ctor throws. void operator delete(void *Usr, unsigned, bool) { // Note: If a subclass manipulates the information which is required to calculate the // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has @@ -210,7 +210,7 @@ public: NumUserOperands = NumOps; } - /// \brief Subclasses with hung off uses need to manage the operand count + /// Subclasses with hung off uses need to manage the operand count /// themselves. In these instances, the operand count isn't used to find the /// OperandList, so there's no issue in having the operand count change. void setNumHungOffUseOperands(unsigned NumOps) { @@ -242,7 +242,7 @@ public: return const_op_range(op_begin(), op_end()); } - /// \brief Iterator for directly iterating over the operand Values. + /// Iterator for directly iterating over the operand Values. struct value_op_iterator : iterator_adaptor_base; // Value Class //===----------------------------------------------------------------------===// -/// \brief LLVM Value Representation +/// LLVM Value Representation /// /// This is a very important LLVM class. It is the base class of all values /// computed by a program that may be used as operands to other values. Value is @@ -83,7 +83,7 @@ class Value { unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? protected: - /// \brief Hold subclass data that can be dropped. + /// Hold subclass data that can be dropped. /// /// This member is similar to SubclassData, however it is for holding /// information which may be used to aid optimization, but which may be @@ -91,7 +91,7 @@ protected: unsigned char SubclassOptionalData : 7; private: - /// \brief Hold arbitrary subclass data. + /// Hold arbitrary subclass data. /// /// This member is defined by this class, but is not used for anything. /// Subclasses can use it to hold whatever state they find useful. This @@ -99,7 +99,7 @@ private: unsigned short SubclassData; protected: - /// \brief The number of operands in the subclass. + /// The number of operands in the subclass. /// /// This member is defined by this class, but not used for anything. /// Subclasses can use it to store their number of operands, if they have @@ -173,7 +173,7 @@ private: bool operator==(const user_iterator_impl &x) const { return UI == x.UI; } bool operator!=(const user_iterator_impl &x) const { return !operator==(x); } - /// \brief Returns true if this iterator is equal to user_end() on the value. + /// Returns true if this iterator is equal to user_end() on the value. bool atEnd() const { return *this == user_iterator_impl(); } user_iterator_impl &operator++() { // Preincrement @@ -218,17 +218,17 @@ public: /// Delete a pointer to a generic Value. void deleteValue(); - /// \brief Support for debugging, callable in GDB: V->dump() + /// Support for debugging, callable in GDB: V->dump() void dump() const; - /// \brief Implement operator<< on Value. + /// Implement operator<< on Value. /// @{ void print(raw_ostream &O, bool IsForDebug = false) const; void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug = false) const; /// @} - /// \brief Print the name of this Value out to the specified raw_ostream. + /// Print the name of this Value out to the specified raw_ostream. /// /// This is useful when you just want to print 'int %reg126', not the /// instruction that generated it. If you specify a Module for context, then @@ -241,13 +241,13 @@ public: ModuleSlotTracker &MST) const; /// @} - /// \brief All values are typed, get the type of this value. + /// All values are typed, get the type of this value. Type *getType() const { return VTy; } - /// \brief All values hold a context through their type. + /// All values hold a context through their type. LLVMContext &getContext() const; - // \brief All values can potentially be named. + // All values can potentially be named. bool hasName() const { return HasName; } ValueName *getValueName() const; void setValueName(ValueName *VN); @@ -258,35 +258,35 @@ private: void setNameImpl(const Twine &Name); public: - /// \brief Return a constant reference to the value's name. + /// Return a constant reference to the value's name. /// /// This guaranteed to return the same reference as long as the value is not /// modified. If the value has a name, this does a hashtable lookup, so it's /// not free. StringRef getName() const; - /// \brief Change the name of the value. + /// Change the name of the value. /// /// Choose a new unique name if the provided name is taken. /// /// \param Name The new name; or "" if the value's name should be removed. void setName(const Twine &Name); - /// \brief Transfer the name from V to this value. + /// Transfer the name from V to this value. /// /// After taking V's name, sets V's name to empty. /// /// \note It is an error to call V->takeName(V). void takeName(Value *V); - /// \brief Change all uses of this to point to a new Value. + /// Change all uses of this to point to a new Value. /// /// Go through the uses list for this definition and make each use point to /// "V" instead of "this". After this completes, 'this's use list is /// guaranteed to be empty. void replaceAllUsesWith(Value *V); - /// \brief Change non-metadata uses of this to point to a new Value. + /// Change non-metadata uses of this to point to a new Value. /// /// Go through the uses list for this definition and make each use point to /// "V" instead of "this". This function skips metadata entries in the list. @@ -411,7 +411,7 @@ public: return materialized_users(); } - /// \brief Return true if there is exactly one user of this value. + /// Return true if there is exactly one user of this value. /// /// This is specialized because it is a common request and does not require /// traversing the whole use list. @@ -421,27 +421,27 @@ public: return ++I == E; } - /// \brief Return true if this Value has exactly N users. + /// Return true if this Value has exactly N users. bool hasNUses(unsigned N) const; - /// \brief Return true if this value has N users or more. + /// Return true if this value has N users or more. /// /// This is logically equivalent to getNumUses() >= N. bool hasNUsesOrMore(unsigned N) const; - /// \brief Check if this value is used in the specified basic block. + /// Check if this value is used in the specified basic block. bool isUsedInBasicBlock(const BasicBlock *BB) const; - /// \brief This method computes the number of uses of this Value. + /// This method computes the number of uses of this Value. /// /// This is a linear time operation. Use hasOneUse, hasNUses, or /// hasNUsesOrMore to check for specific values. unsigned getNumUses() const; - /// \brief This method should only be used by the Use class. + /// This method should only be used by the Use class. void addUse(Use &U) { U.addToList(&UseList); } - /// \brief Concrete subclass of this. + /// Concrete subclass of this. /// /// An enumeration for keeping track of the concrete subclass of Value that /// is actually instantiated. Values of this enumeration are kept in the @@ -456,7 +456,7 @@ public: #include "llvm/IR/Value.def" }; - /// \brief Return an ID for the concrete type of this object. + /// Return an ID for the concrete type of this object. /// /// This is used to implement the classof checks. This should not be used /// for any other purpose, as the values may change as LLVM evolves. Also, @@ -470,36 +470,36 @@ public: return SubclassID; } - /// \brief Return the raw optional flags value contained in this value. + /// Return the raw optional flags value contained in this value. /// /// This should only be used when testing two Values for equivalence. unsigned getRawSubclassOptionalData() const { return SubclassOptionalData; } - /// \brief Clear the optional flags contained in this value. + /// Clear the optional flags contained in this value. void clearSubclassOptionalData() { SubclassOptionalData = 0; } - /// \brief Check the optional flags for equality. + /// Check the optional flags for equality. bool hasSameSubclassOptionalData(const Value *V) const { return SubclassOptionalData == V->SubclassOptionalData; } - /// \brief Return true if there is a value handle associated with this value. + /// Return true if there is a value handle associated with this value. bool hasValueHandle() const { return HasValueHandle; } - /// \brief Return true if there is metadata referencing this value. + /// Return true if there is metadata referencing this value. bool isUsedByMetadata() const { return IsUsedByMD; } - /// \brief Return true if this value is a swifterror value. + /// Return true if this value is a swifterror value. /// /// swifterror values can be either a function argument or an alloca with a /// swifterror attribute. bool isSwiftError() const; - /// \brief Strip off pointer casts, all-zero GEPs, and aliases. + /// Strip off pointer casts, all-zero GEPs, and aliases. /// /// Returns the original uncasted value. If this is called on a non-pointer /// value, it returns 'this'. @@ -509,18 +509,19 @@ public: static_cast(this)->stripPointerCasts()); } - /// \brief Strip off pointer casts, all-zero GEPs, aliases and barriers. + /// Strip off pointer casts, all-zero GEPs, aliases and invariant group + /// info. /// /// Returns the original uncasted value. If this is called on a non-pointer /// value, it returns 'this'. This function should be used only in /// Alias analysis. - const Value *stripPointerCastsAndBarriers() const; - Value *stripPointerCastsAndBarriers() { + const Value *stripPointerCastsAndInvariantGroups() const; + Value *stripPointerCastsAndInvariantGroups() { return const_cast( - static_cast(this)->stripPointerCastsAndBarriers()); + static_cast(this)->stripPointerCastsAndInvariantGroups()); } - /// \brief Strip off pointer casts and all-zero GEPs. + /// Strip off pointer casts and all-zero GEPs. /// /// Returns the original uncasted value. If this is called on a non-pointer /// value, it returns 'this'. @@ -530,7 +531,7 @@ public: static_cast(this)->stripPointerCastsNoFollowAliases()); } - /// \brief Strip off pointer casts and all-constant inbounds GEPs. + /// Strip off pointer casts and all-constant inbounds GEPs. /// /// Returns the original pointer value. If this is called on a non-pointer /// value, it returns 'this'. @@ -540,7 +541,7 @@ public: static_cast(this)->stripInBoundsConstantOffsets()); } - /// \brief Accumulate offsets from \a stripInBoundsConstantOffsets(). + /// Accumulate offsets from \a stripInBoundsConstantOffsets(). /// /// Stores the resulting constant offset stripped into the APInt provided. /// The provided APInt will be extended or truncated as needed to be the @@ -555,7 +556,7 @@ public: ->stripAndAccumulateInBoundsConstantOffsets(DL, Offset)); } - /// \brief Strip off pointer casts and inbounds GEPs. + /// Strip off pointer casts and inbounds GEPs. /// /// Returns the original pointer value. If this is called on a non-pointer /// value, it returns 'this'. @@ -565,7 +566,7 @@ public: static_cast(this)->stripInBoundsOffsets()); } - /// \brief Returns the number of bytes known to be dereferenceable for the + /// Returns the number of bytes known to be dereferenceable for the /// pointer value. /// /// If CanBeNull is set by this function the pointer can either be null or be @@ -573,13 +574,13 @@ public: uint64_t getPointerDereferenceableBytes(const DataLayout &DL, bool &CanBeNull) const; - /// \brief Returns an alignment of the pointer value. + /// Returns an alignment of the pointer value. /// /// Returns an alignment which is either specified explicitly, e.g. via /// align attribute of a function argument, or guaranteed by DataLayout. unsigned getPointerAlignment(const DataLayout &DL) const; - /// \brief Translate PHI node to its predecessor from the given basic block. + /// Translate PHI node to its predecessor from the given basic block. /// /// If this value is a PHI node with CurBB as its parent, return the value in /// the PHI node corresponding to PredBB. If not, return ourself. This is @@ -592,14 +593,14 @@ public: static_cast(this)->DoPHITranslation(CurBB, PredBB)); } - /// \brief The maximum alignment for instructions. + /// The maximum alignment for instructions. /// /// This is the greatest alignment value supported by load, store, and alloca /// instructions, and global values. static const unsigned MaxAlignmentExponent = 29; static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent; - /// \brief Mutate the type of this Value to be of the specified type. + /// Mutate the type of this Value to be of the specified type. /// /// Note that this is an extremely dangerous operation which can create /// completely invalid IR very easily. It is strongly recommended that you @@ -609,17 +610,17 @@ public: VTy = Ty; } - /// \brief Sort the use-list. + /// Sort the use-list. /// /// Sorts the Value's use-list by Cmp using a stable mergesort. Cmp is /// expected to compare two \a Use references. template void sortUseList(Compare Cmp); - /// \brief Reverse the use-list. + /// Reverse the use-list. void reverseUseList(); private: - /// \brief Merge two lists together. + /// Merge two lists together. /// /// Merges \c L and \c R using \c Cmp. To enable stable sorts, always pushes /// "equal" items from L before items from R. diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index b45cc7b6dc029bf3ecc8e8950478eed9834aa951..d94472ce1be18d2724a8b434e0f9c98d4c4e0ad6 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -22,7 +22,7 @@ namespace llvm { -/// \brief This is the common base class of value handles. +/// This is the common base class of value handles. /// /// ValueHandle's are smart pointers to Value's that have special behavior when /// the value is deleted or ReplaceAllUsesWith'd. See the specific handles @@ -31,7 +31,7 @@ class ValueHandleBase { friend class Value; protected: - /// \brief This indicates what sub class the handle actually is. + /// This indicates what sub class the handle actually is. /// /// This is to avoid having a vtable for the light-weight handle pointers. The /// fully general Callback version does have a vtable. @@ -101,10 +101,10 @@ protected: V != DenseMapInfo::getTombstoneKey(); } - /// \brief Remove this ValueHandle from its current use list. + /// Remove this ValueHandle from its current use list. void RemoveFromUseList(); - /// \brief Clear the underlying pointer without clearing the use list. + /// Clear the underlying pointer without clearing the use list. /// /// This should only be used if a derived class has manually removed the /// handle from the use list. @@ -121,20 +121,20 @@ private: HandleBaseKind getKind() const { return PrevPair.getInt(); } void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); } - /// \brief Add this ValueHandle to the use list for V. + /// Add this ValueHandle to the use list for V. /// /// List is the address of either the head of the list or a Next node within /// the existing use list. void AddToExistingUseList(ValueHandleBase **List); - /// \brief Add this ValueHandle to the use list after Node. + /// Add this ValueHandle to the use list after Node. void AddToExistingUseListAfter(ValueHandleBase *Node); - /// \brief Add this ValueHandle to the use list for V. + /// Add this ValueHandle to the use list for V. void AddToUseList(); }; -/// \brief A nullable Value handle that is nullable. +/// A nullable Value handle that is nullable. /// /// This is a value handle that points to a value, and nulls itself /// out if that value is deleted. @@ -172,7 +172,7 @@ template <> struct simplify_type { static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } }; -/// \brief Value handle that is nullable, but tries to track the Value. +/// Value handle that is nullable, but tries to track the Value. /// /// This is a value handle that tries hard to point to a Value, even across /// RAUW operations, but will null itself out if the value is destroyed. this @@ -219,7 +219,7 @@ template <> struct simplify_type { } }; -/// \brief Value handle that asserts if the Value is deleted. +/// Value handle that asserts if the Value is deleted. /// /// This is a Value Handle that points to a value and asserts out if the value /// is destroyed while the handle is still live. This is very useful for @@ -318,7 +318,7 @@ struct isPodLike> { #endif }; -/// \brief Value handle that tracks a Value across RAUW. +/// Value handle that tracks a Value across RAUW. /// /// TrackingVH is designed for situations where a client needs to hold a handle /// to a Value (or subclass) across some operations which may move that value, @@ -379,7 +379,7 @@ public: ValueTy &operator*() const { return *getValPtr(); } }; -/// \brief Value handle with callbacks on RAUW and destruction. +/// Value handle with callbacks on RAUW and destruction. /// /// This is a value handle that allows subclasses to define callbacks that run /// when the underlying Value has RAUW called on it or is destroyed. This @@ -405,7 +405,7 @@ public: return getValPtr(); } - /// \brief Callback for Value destruction. + /// Callback for Value destruction. /// /// Called when this->getValPtr() is destroyed, inside ~Value(), so you /// may call any non-virtual Value method on getValPtr(), but no subclass @@ -418,7 +418,7 @@ public: /// Value that's being destroyed. virtual void deleted() { setValPtr(nullptr); } - /// \brief Callback for Value RAUW. + /// Callback for Value RAUW. /// /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, /// _before_ any of the uses have actually been replaced. If WeakTrackingVH diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h index 11d5823ee479b591a808dd1990a15719767b358b..e7e33918a61320a5970100e323fcf07b2995ce41 100644 --- a/include/llvm/IR/ValueMap.h +++ b/include/llvm/IR/ValueMap.h @@ -106,8 +106,12 @@ public: : Map(NumInitBuckets), Data() {} explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64) : Map(NumInitBuckets), Data(Data) {} + // ValueMap can't be copied nor moved, beucase the callbacks store pointer + // to it. ValueMap(const ValueMap &) = delete; + ValueMap(ValueMap &&) = delete; ValueMap &operator=(const ValueMap &) = delete; + ValueMap &operator=(ValueMap &&) = delete; bool hasMD() const { return bool(MDMap); } MDMapT &MD() { diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h index 26cbbfabfc0c5f72885377326518d2d7a15f6c69..012e717c7470c3e987ce73d71daff80ac494bc6b 100644 --- a/include/llvm/IR/ValueSymbolTable.h +++ b/include/llvm/IR/ValueSymbolTable.h @@ -48,13 +48,13 @@ class ValueSymbolTable { /// @name Types /// @{ public: - /// @brief A mapping of names to values. + /// A mapping of names to values. using ValueMap = StringMap; - /// @brief An iterator over a ValueMap. + /// An iterator over a ValueMap. using iterator = ValueMap::iterator; - /// @brief A const_iterator over a ValueMap. + /// A const_iterator over a ValueMap. using const_iterator = ValueMap::const_iterator; /// @} @@ -71,35 +71,35 @@ public: /// This method finds the value with the given \p Name in the /// the symbol table. /// @returns the value associated with the \p Name - /// @brief Lookup a named Value. + /// Lookup a named Value. Value *lookup(StringRef Name) const { return vmap.lookup(Name); } /// @returns true iff the symbol table is empty - /// @brief Determine if the symbol table is empty + /// Determine if the symbol table is empty inline bool empty() const { return vmap.empty(); } - /// @brief The number of name/type pairs is returned. + /// The number of name/type pairs is returned. inline unsigned size() const { return unsigned(vmap.size()); } /// This function can be used from the debugger to display the /// content of the symbol table while debugging. - /// @brief Print out symbol table on stderr + /// Print out symbol table on stderr void dump() const; /// @} /// @name Iteration /// @{ - /// @brief Get an iterator that from the beginning of the symbol table. + /// Get an iterator that from the beginning of the symbol table. inline iterator begin() { return vmap.begin(); } - /// @brief Get a const_iterator that from the beginning of the symbol table. + /// Get a const_iterator that from the beginning of the symbol table. inline const_iterator begin() const { return vmap.begin(); } - /// @brief Get an iterator to the end of the symbol table. + /// Get an iterator to the end of the symbol table. inline iterator end() { return vmap.end(); } - /// @brief Get a const_iterator to the end of the symbol table. + /// Get a const_iterator to the end of the symbol table. inline const_iterator end() const { return vmap.end(); } /// @} @@ -111,7 +111,7 @@ private: /// This method adds the provided value \p N to the symbol table. The Value /// must have a name which is used to place the value in the symbol table. /// If the inserted name conflicts, this renames the value. - /// @brief Add a named value to the symbol table + /// Add a named value to the symbol table void reinsertValue(Value *V); /// createValueName - This method attempts to create a value name and insert diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h index bc10f330bc8a8e46cc27f300813b36807507016a..7255132e1e6534b85ca1f0c43c3b33c33259e0da 100644 --- a/include/llvm/IR/Verifier.h +++ b/include/llvm/IR/Verifier.h @@ -80,7 +80,7 @@ public: bool visitTBAAMetadata(Instruction &I, const MDNode *MD); }; -/// \brief Check a function for errors, useful for use when debugging a +/// Check a function for errors, useful for use when debugging a /// pass. /// /// If there are no errors, the function returns false. If an error is found, @@ -88,7 +88,7 @@ public: /// returned. bool verifyFunction(const Function &F, raw_ostream *OS = nullptr); -/// \brief Check a module for errors. +/// Check a module for errors. /// /// If there are no errors, the function returns false. If an error is /// found, a message describing the error is written to OS (if @@ -124,7 +124,7 @@ public: /// "recovered" from by stripping the debug info. bool verifyModule(bool &BrokenDebugInfo, const Module &M, raw_ostream *OS); -/// \brief Create a verifier pass. +/// Create a verifier pass. /// /// Check a module or function for validity. This is essentially a pass wrapped /// around the above verifyFunction and verifyModule routines and diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 5aa5112038bf16f9a236f511d35c032fb281028a..55132d38c20348aa238dcb01f7ef77ca8e99584e 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -37,6 +37,9 @@ void initializeVectorization(PassRegistry&); /// Initialize all passes linked into the InstCombine library. void initializeInstCombine(PassRegistry&); +/// Initialize all passes linked into the AggressiveInstCombine library. +void initializeAggressiveInstCombine(PassRegistry&); + /// Initialize all passes linked into the IPO library. void initializeIPO(PassRegistry&); @@ -88,6 +91,7 @@ void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&); void initializeCFGPrinterLegacyPassPass(PassRegistry&); void initializeCFGSimplifyPassPass(PassRegistry&); void initializeCFGViewerLegacyPassPass(PassRegistry&); +void initializeCFIInstrInserterPass(PassRegistry&); void initializeCFLAndersAAWrapperPassPass(PassRegistry&); void initializeCFLSteensAAWrapperPassPass(PassRegistry&); void initializeCallGraphDOTPrinterPass(PassRegistry&); @@ -158,6 +162,7 @@ void initializeGlobalOptLegacyPassPass(PassRegistry&); void initializeGlobalSplitPass(PassRegistry&); void initializeGlobalsAAWrapperPassPass(PassRegistry&); void initializeGuardWideningLegacyPassPass(PassRegistry&); +void initializeLoopGuardWideningLegacyPassPass(PassRegistry&); void initializeIPCPPass(PassRegistry&); void initializeIPSCCPLegacyPassPass(PassRegistry&); void initializeIRTranslatorPass(PassRegistry&); @@ -210,6 +215,7 @@ void initializeLoopDistributeLegacyPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&); void initializeLoopInfoWrapperPassPass(PassRegistry&); +void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&); void initializeLoopInterchangePass(PassRegistry&); void initializeLoopLoadEliminationPass(PassRegistry&); void initializeLoopPassPass(PassRegistry&); @@ -383,6 +389,7 @@ void initializeUnreachableMachineBlockElimPass(PassRegistry&); void initializeVerifierLegacyPassPass(PassRegistry&); void initializeVirtRegMapPass(PassRegistry&); void initializeVirtRegRewriterPass(PassRegistry&); +void initializeWasmEHPreparePass(PassRegistry&); void initializeWholeProgramDevirtPass(PassRegistry&); void initializeWinEHPreparePass(PassRegistry&); void initializeWriteBitcodePassPass(PassRegistry&); diff --git a/include/llvm/LTO/Config.h b/include/llvm/LTO/Config.h index 4bd981c090b12f632640b6d579d4ce6b12e6d144..57bba5e34840d53621dc98624accc46084bad1c7 100644 --- a/include/llvm/LTO/Config.h +++ b/include/llvm/LTO/Config.h @@ -73,6 +73,14 @@ struct Config { /// Sample PGO profile path. std::string SampleProfile; + /// The directory to store .dwo files. + std::string DwoDir; + + /// The path to write a .dwo file to. This should generally only be used when + /// running an individual backend directly via thinBackend(), as otherwise + /// all .dwo files will be written to the same path. + std::string DwoPath; + /// Optimization remarks file path. std::string RemarksFilename = ""; @@ -82,6 +90,9 @@ struct Config { /// Whether to emit the pass manager debuggging informations. bool DebugPassManager = false; + /// Statistics output file path. + std::string StatsFile; + bool ShouldDiscardValueNames = true; DiagnosticHandlerFunction DiagHandler; diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 2d7956da71d16c6fb5854df4247726af731aa201..a49c4aad8651843cd032ac52a5f723f3b17b1e83 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -39,9 +39,11 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/Support/Valgrind.h" +#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/ObjCARC.h" @@ -65,6 +67,7 @@ namespace { (void) llvm::createAAEvalPass(); (void) llvm::createAggressiveDCEPass(); + (void) llvm::createAggressiveInstCombinerPass(); (void) llvm::createBitTrackingDCEPass(); (void) llvm::createArgumentPromotionPass(); (void) llvm::createAlignmentFromAssumptionsPass(); @@ -108,6 +111,7 @@ namespace { (void) llvm::createGlobalOptimizerPass(); (void) llvm::createGlobalsAAWrapperPass(); (void) llvm::createGuardWideningPass(); + (void) llvm::createLoopGuardWideningPass(); (void) llvm::createIPConstantPropagationPass(); (void) llvm::createIPSCCPPass(); (void) llvm::createInductiveRangeCheckEliminationPass(); diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h index 628e0112bd9d9f5ce5808d725528e154387d5353..7776c720ec5379a6d56f36f2ba74ef97512586b0 100644 --- a/include/llvm/Linker/Linker.h +++ b/include/llvm/Linker/Linker.h @@ -34,7 +34,7 @@ public: Linker(Module &M); - /// \brief Link \p Src into the composite. + /// Link \p Src into the composite. /// /// Passing OverrideSymbols as true will have symbols from Src /// shadow those in the Dest. diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index a8a5850899e3f0841b3dd1b35b1b0545d0ceb471..1272829b1f6b5edb61aede9c7d1d530a8c83b7f2 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -16,6 +16,7 @@ #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFragment.h" +#include "llvm/Support/Endian.h" #include #include @@ -29,6 +30,7 @@ struct MCFixupKindInfo; class MCFragment; class MCInst; class MCObjectStreamer; +class MCObjectTargetWriter; class MCObjectWriter; struct MCCodePaddingContext; class MCRelaxableFragment; @@ -41,21 +43,31 @@ class MCAsmBackend { std::unique_ptr CodePadder; protected: // Can only create subclasses. - MCAsmBackend(); - MCAsmBackend(std::unique_ptr TargetCodePadder); + MCAsmBackend(support::endianness Endian); public: MCAsmBackend(const MCAsmBackend &) = delete; MCAsmBackend &operator=(const MCAsmBackend &) = delete; virtual ~MCAsmBackend(); + const support::endianness Endian; + /// lifetime management virtual void reset() {} /// Create a new MCObjectWriter instance for use by the assembler backend to /// emit the final object file. - virtual std::unique_ptr - createObjectWriter(raw_pwrite_stream &OS) const = 0; + std::unique_ptr + createObjectWriter(raw_pwrite_stream &OS) const; + + /// Create an MCObjectWriter that writes two object files: a .o file which is + /// linked into the final program and a .dwo file which is used by debuggers. + /// This function is only supported with ELF targets. + std::unique_ptr + createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const; + + virtual std::unique_ptr + createObjectTargetWriter() const = 0; /// \name Target Fixup Interfaces /// @{ @@ -84,6 +96,10 @@ public: const MCValue &Target, MutableArrayRef Data, uint64_t Value, bool IsResolved) const = 0; + /// Check whether the given target requires emitting differences of two + /// symbols as a set of relocations. + virtual bool requiresDiffExpressionRelocations() const { return false; } + /// @} /// \name Target Relaxation Interfaces @@ -99,7 +115,8 @@ public: virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, uint64_t Value, const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const; + const MCAsmLayout &Layout, + const bool WasForced) const; /// Simple predicate for targets where !Resolved implies requiring relaxation virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, @@ -127,7 +144,7 @@ public: /// target cannot generate such a sequence, it should return an error. /// /// \return - True on success. - virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0; + virtual bool writeNopData(raw_ostream &OS, uint64_t Count) const = 0; /// Give backend an opportunity to finish layout after relaxation virtual void finishLayout(MCAssembler const &Asm, @@ -136,7 +153,7 @@ public: /// Handle any target-specific assembler flags. By default, do nothing. virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} - /// \brief Generate the compact unwind encoding for the CFI instructions. + /// Generate the compact unwind encoding for the CFI instructions. virtual uint32_t generateCompactUnwindEncoding(ArrayRef) const { return 0; diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index c538c46fc0728f05dccd1ecdcda39283edf78fa7..ac722a007e995116297569433066c2475d662a50 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -344,6 +344,10 @@ protected: /// For example, foo(plt) instead of foo@plt. Defaults to false. bool UseParensForSymbolVariant = false; + /// True if the target supports flags in ".loc" directive, false if only + /// location is allowed. + bool SupportsExtendedDwarfLocDirective = true; + //===--- Prologue State ----------------------------------------------===// std::vector InitialFrameState; @@ -416,7 +420,7 @@ public: return nullptr; } - /// \brief True if the section is atomized using the symbols in it. + /// True if the section is atomized using the symbols in it. /// This is false if the section is not atomized at all (most ELF sections) or /// if it is atomized based on its contents (MachO' __TEXT,__cstring for /// example). @@ -579,6 +583,9 @@ public: bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; } bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; } + bool supportsExtendedDwarfLocDirective() const { + return SupportsExtendedDwarfLocDirective; + } void addInitialFrameState(const MCCFIInstruction &Inst) { InitialFrameState.push_back(Inst); diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index 1b20d5b804a4ba546ddf2bc541421600848d1e5d..b711db319302945d3a59974aec5b6724a0f21db8 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -37,11 +37,11 @@ class MCAsmLayout { /// lower ordinal will be valid. mutable DenseMap LastValidFragment; - /// \brief Make sure that the layout for the given fragment is valid, lazily + /// Make sure that the layout for the given fragment is valid, lazily /// computing it if necessary. void ensureValid(const MCFragment *F) const; - /// \brief Is the layout for this fragment valid? + /// Is the layout for this fragment valid? bool isFragmentValid(const MCFragment *F) const; public: @@ -50,12 +50,12 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Invalidate the fragments starting with F because it has been + /// Invalidate the fragments starting with F because it has been /// resized. The fragment's size should have already been updated, but /// its bundle padding will be recomputed. void invalidateFragmentsFrom(MCFragment *F); - /// \brief Perform layout for a single fragment, assuming that the previous + /// Perform layout for a single fragment, assuming that the previous /// fragment has already been laid out correctly, and the parent section has /// been initialized. void layoutFragment(MCFragment *Fragment); @@ -72,31 +72,31 @@ public: /// \name Fragment Layout Data /// @{ - /// \brief Get the offset of the given fragment inside its containing section. + /// Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment *F) const; /// @} /// \name Utility Functions /// @{ - /// \brief Get the address space size of the given section, as it effects + /// Get the address space size of the given section, as it effects /// layout. This may differ from the size reported by \see getSectionSize() by /// not including section tail padding. uint64_t getSectionAddressSize(const MCSection *Sec) const; - /// \brief Get the data size of the given section, as emitted to the object + /// Get the data size of the given section, as emitted to the object /// file. This may include additional padding, or be 0 for virtual sections. uint64_t getSectionFileSize(const MCSection *Sec) const; - /// \brief Get the offset of the given symbol, as computed in the current + /// Get the offset of the given symbol, as computed in the current /// layout. /// \return True on success. bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const; - /// \brief Variant that reports a fatal error if the offset is not computable. + /// Variant that reports a fatal error if the offset is not computable. uint64_t getSymbolOffset(const MCSymbol &S) const; - /// \brief If this symbol is equivalent to A + Constant, return A. + /// If this symbol is equivalent to A + Constant, return A. const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const; /// @} diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index b91b04414021ace5731f18897a14fbb5dbc51d69..34bf180be1f6a5227936c1215e7967106a4a0c0a 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -99,11 +99,11 @@ public: private: MCContext &Context; - MCAsmBackend &Backend; + std::unique_ptr Backend; - MCCodeEmitter &Emitter; + std::unique_ptr Emitter; - MCObjectWriter &Writer; + std::unique_ptr Writer; SectionListType Sections; @@ -130,7 +130,7 @@ private: // refactoring too. mutable SmallPtrSet ThumbFuncs; - /// \brief The bundle alignment size currently set in the assembler. + /// The bundle alignment size currently set in the assembler. /// /// By default it's 0, which means bundling is disabled. unsigned BundleAlignSize; @@ -162,12 +162,14 @@ private: /// evaluates to. /// \param Value [out] On return, the value of the fixup as currently laid /// out. + /// \param WasForced [out] On return, the value in the fixup is set to the + /// correct value if WasForced is true, even if evaluateFixup returns false. /// \return Whether the fixup value was fully resolved. This is true if the /// \p Value result is fixed, otherwise the value may change due to /// relocation. bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, - uint64_t &Value) const; + uint64_t &Value, bool &WasForced) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). @@ -178,11 +180,11 @@ private: bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, const MCAsmLayout &Layout) const; - /// \brief Perform one layout iteration and return true if any offsets + /// Perform one layout iteration and return true if any offsets /// were adjusted. bool layoutOnce(MCAsmLayout &Layout); - /// \brief Perform one layout iteration of the given section and return true + /// Perform one layout iteration of the given section and return true /// if any offsets were adjusted. bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec); @@ -214,8 +216,9 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context, MCAsmBackend &Backend, - MCCodeEmitter &Emitter, MCObjectWriter &Writer); + MCAssembler(MCContext &Context, std::unique_ptr Backend, + std::unique_ptr Emitter, + std::unique_ptr Writer); MCAssembler(const MCAssembler &) = delete; MCAssembler &operator=(const MCAssembler &) = delete; ~MCAssembler(); @@ -235,8 +238,8 @@ public: /// defining a separate atom. bool isSymbolLinkerVisible(const MCSymbol &SD) const; - /// Emit the section contents using the given object writer. - void writeSectionData(const MCSection *Section, + /// Emit the section contents to \p OS. + void writeSectionData(raw_ostream &OS, const MCSection *Section, const MCAsmLayout &Layout) const; /// Check whether a given symbol has been flagged with .thumb_func. @@ -274,11 +277,17 @@ public: MCContext &getContext() const { return Context; } - MCAsmBackend &getBackend() const { return Backend; } + MCAsmBackend *getBackendPtr() const { return Backend.get(); } - MCCodeEmitter &getEmitter() const { return Emitter; } + MCCodeEmitter *getEmitterPtr() const { return Emitter.get(); } - MCObjectWriter &getWriter() const { return Writer; } + MCObjectWriter *getWriterPtr() const { return Writer.get(); } + + MCAsmBackend &getBackend() const { return *Backend; } + + MCCodeEmitter &getEmitter() const { return *Emitter; } + + MCObjectWriter &getWriter() const { return *Writer; } MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; } void setDWARFLinetableParams(MCDwarfLineTableParams P) { LTParams = P; } @@ -409,6 +418,13 @@ public: const MCLOHContainer &getLOHContainer() const { return const_cast(this)->getLOHContainer(); } + + struct CGProfileEntry { + const MCSymbolRefExpr *From; + const MCSymbolRefExpr *To; + uint64_t Count; + }; + std::vector CGProfile; /// @} /// \name Backend Data Access /// @{ @@ -424,17 +440,17 @@ public: FileNames.push_back(FileName); } - /// \brief Write the necessary bundle padding to the given object writer. + /// Write the necessary bundle padding to \p OS. /// Expects a fragment \p F containing instructions and its size \p FSize. - void writeFragmentPadding(const MCFragment &F, uint64_t FSize, - MCObjectWriter *OW) const; + void writeFragmentPadding(raw_ostream &OS, const MCFragment &F, + uint64_t FSize) const; /// @} void dump() const; }; -/// \brief Compute the amount of padding required before the fragment \p F to +/// Compute the amount of padding required before the fragment \p F to /// obey bundling restrictions, where \p FOffset is the fragment's offset in /// its section and \p FSize is the fragment's size. uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F, diff --git a/include/llvm/MC/MCCodePadder.h b/include/llvm/MC/MCCodePadder.h index b7772b64a27d805c3ae72703d4dc83281b481368..4dde6bf59272440441debf06905c2411aa452371 100644 --- a/include/llvm/MC/MCCodePadder.h +++ b/include/llvm/MC/MCCodePadder.h @@ -28,7 +28,6 @@ typedef SmallVector MCPFRange; struct MCCodePaddingContext { bool IsPaddingActive; - bool IsBasicBlockInsideInnermostLoop; bool IsBasicBlockReachableViaFallthrough; bool IsBasicBlockReachableViaBranch; }; diff --git a/include/llvm/MC/MCCodeView.h b/include/llvm/MC/MCCodeView.h index c8f14515ed343ee09ce7b4a81072fc4bfc45a712..1d9e3c6698cf701d3d42bc46d5e20fba3efb4033 100644 --- a/include/llvm/MC/MCCodeView.h +++ b/include/llvm/MC/MCCodeView.h @@ -27,7 +27,7 @@ class MCObjectStreamer; class MCStreamer; class CodeViewContext; -/// \brief Instances of this class represent the information from a +/// Instances of this class represent the information from a /// .cv_loc directive. class MCCVLoc { uint32_t FunctionId; @@ -50,13 +50,13 @@ private: // CodeViewContext manages these public: unsigned getFunctionId() const { return FunctionId; } - /// \brief Get the FileNum of this MCCVLoc. + /// Get the FileNum of this MCCVLoc. unsigned getFileNum() const { return FileNum; } - /// \brief Get the Line of this MCCVLoc. + /// Get the Line of this MCCVLoc. unsigned getLine() const { return Line; } - /// \brief Get the Column of this MCCVLoc. + /// Get the Column of this MCCVLoc. unsigned getColumn() const { return Column; } bool isPrologueEnd() const { return PrologueEnd; } @@ -64,13 +64,13 @@ public: void setFunctionId(unsigned FID) { FunctionId = FID; } - /// \brief Set the FileNum of this MCCVLoc. + /// Set the FileNum of this MCCVLoc. void setFileNum(unsigned fileNum) { FileNum = fileNum; } - /// \brief Set the Line of this MCCVLoc. + /// Set the Line of this MCCVLoc. void setLine(unsigned line) { Line = line; } - /// \brief Set the Column of this MCCVLoc. + /// Set the Column of this MCCVLoc. void setColumn(unsigned column) { assert(column <= UINT16_MAX); Column = column; @@ -80,7 +80,7 @@ public: void setIsStmt(bool IS) { IsStmt = IS; } }; -/// \brief Instances of this class represent the line information for +/// Instances of this class represent the line information for /// the CodeView line table entries. Which is created after a machine /// instruction is assembled and uses an address from a temporary label /// created at the current address in the current section and the info from @@ -201,7 +201,7 @@ public: bool isValidCVFileNumber(unsigned FileNumber); - /// \brief Add a line entry. + /// Add a line entry. void addLineEntry(const MCCVLineEntry &LineEntry); std::vector getFunctionLineEntries(unsigned FuncId); diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index c110ffd3a772400fdcecee931225a0a8877da519..1a8a0c08d9460e9a55f4957f7d92ca99b78ad5fe 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -272,7 +272,7 @@ namespace llvm { unsigned UniqueID, const MCSymbolELF *Associated); - /// \brief Map of currently defined macros. + /// Map of currently defined macros. StringMap MacroMap; public: @@ -295,6 +295,10 @@ namespace llvm { CodeViewContext &getCVContext(); + /// Clear the current cv_loc, if there is one. Avoids lazily creating a + /// CodeViewContext if none is needed. + void clearCVLocSeen(); + void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; } @@ -338,7 +342,7 @@ namespace llvm { /// Gets a symbol that will be defined to the final stack offset of a local /// variable after codegen. /// - /// \param Idx - The index of a local variable passed to @llvm.localescape. + /// \param Idx - The index of a local variable passed to \@llvm.localescape. MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx); MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName); @@ -478,20 +482,20 @@ namespace llvm { /// \name Dwarf Management /// @{ - /// \brief Get the compilation directory for DW_AT_comp_dir + /// Get the compilation directory for DW_AT_comp_dir /// The compilation directory should be set with \c setCompilationDir before /// calling this function. If it is unset, an empty string will be returned. StringRef getCompilationDir() const { return CompilationDir; } - /// \brief Set the compilation directory for DW_AT_comp_dir + /// Set the compilation directory for DW_AT_comp_dir void setCompilationDir(StringRef S) { CompilationDir = S.str(); } - /// \brief Get the main file name for use in error messages and debug + /// Get the main file name for use in error messages and debug /// info. This can be set to ensure we've got the correct file name /// after preprocessing or for -save-temps. const std::string &getMainFileName() const { return MainFileName; } - /// \brief Set the main file name and override the default. + /// Set the main file name and override the default. void setMainFileName(StringRef S) { MainFileName = S; } /// Creates an entry in the dwarf file and directory tables. @@ -649,7 +653,7 @@ namespace llvm { // operator new and delete aren't allowed inside namespaces. // The throw specifications are mandated by the standard. -/// \brief Placement new for using the MCContext's allocator. +/// Placement new for using the MCContext's allocator. /// /// This placement form of operator new uses the MCContext's allocator for /// obtaining memory. It is a non-throwing new, which means that it returns @@ -675,7 +679,7 @@ inline void *operator new(size_t Bytes, llvm::MCContext &C, size_t Alignment = 8) noexcept { return C.allocate(Bytes, Alignment); } -/// \brief Placement delete companion to the new above. +/// Placement delete companion to the new above. /// /// This operator is just a companion to the new above. There is no way of /// invoking it directly; see the new operator for more details. This operator @@ -709,7 +713,7 @@ inline void *operator new[](size_t Bytes, llvm::MCContext &C, return C.allocate(Bytes, Alignment); } -/// \brief Placement delete[] companion to the new[] above. +/// Placement delete[] companion to the new[] above. /// /// This operator is just a companion to the new[] above. There is no way of /// invoking it directly; see the new[] operator for more details. This operator diff --git a/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h b/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h index bd3e5d4638e5461638af133411b3b0acce2494a5..df909a0dccd3fb4367dac7c71f2412d235e33f0c 100644 --- a/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h +++ b/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h @@ -22,7 +22,7 @@ namespace llvm { -/// \brief Symbolize using user-provided, C API, callbacks. +/// Symbolize using user-provided, C API, callbacks. /// /// See llvm-c/Disassembler.h. class MCExternalSymbolizer : public MCSymbolizer { diff --git a/include/llvm/MC/MCDisassembler/MCRelocationInfo.h b/include/llvm/MC/MCDisassembler/MCRelocationInfo.h index 7836e886c303c883503bc4fdf6c264a53316f8ef..6030ae660d38b843c17462ac9b16df531e23be53 100644 --- a/include/llvm/MC/MCDisassembler/MCRelocationInfo.h +++ b/include/llvm/MC/MCDisassembler/MCRelocationInfo.h @@ -21,7 +21,7 @@ namespace llvm { class MCContext; class MCExpr; -/// \brief Create MCExprs from relocations found in an object file. +/// Create MCExprs from relocations found in an object file. class MCRelocationInfo { protected: MCContext &Ctx; @@ -32,7 +32,7 @@ public: MCRelocationInfo &operator=(const MCRelocationInfo &) = delete; virtual ~MCRelocationInfo(); - /// \brief Create an MCExpr for the target-specific \p VariantKind. + /// Create an MCExpr for the target-specific \p VariantKind. /// The VariantKinds are defined in llvm-c/Disassembler.h. /// Used by MCExternalSymbolizer. /// \returns If possible, an MCExpr corresponding to VariantKind, else 0. diff --git a/include/llvm/MC/MCDisassembler/MCSymbolizer.h b/include/llvm/MC/MCDisassembler/MCSymbolizer.h index d85cf5e066f5ad09276003423e73c679fc3d6d14..0bfa569474ec59e40a7e586eef4a862862cbed88 100644 --- a/include/llvm/MC/MCDisassembler/MCSymbolizer.h +++ b/include/llvm/MC/MCDisassembler/MCSymbolizer.h @@ -27,7 +27,7 @@ class MCContext; class MCInst; class raw_ostream; -/// \brief Symbolize and annotate disassembled instructions. +/// Symbolize and annotate disassembled instructions. /// /// For now this mimics the old symbolization logic (from both ARM and x86), that /// relied on user-provided (C API) callbacks to do the actual symbol lookup in @@ -42,7 +42,7 @@ protected: std::unique_ptr RelInfo; public: - /// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo. + /// Construct an MCSymbolizer, taking ownership of \p RelInfo. MCSymbolizer(MCContext &Ctx, std::unique_ptr RelInfo) : Ctx(Ctx), RelInfo(std::move(RelInfo)) { } @@ -51,7 +51,7 @@ public: MCSymbolizer &operator=(const MCSymbolizer &) = delete; virtual ~MCSymbolizer(); - /// \brief Try to add a symbolic operand instead of \p Value to the MCInst. + /// Try to add a symbolic operand instead of \p Value to the MCInst. /// /// Instead of having a difficult to read immediate, a symbolic operand would /// represent this immediate in a more understandable way, for instance as a @@ -70,7 +70,7 @@ public: bool IsBranch, uint64_t Offset, uint64_t InstSize) = 0; - /// \brief Try to add a comment on the PC-relative load. + /// Try to add a comment on the PC-relative load. /// For instance, in Mach-O, this is used to add annotations to instructions /// that use C string literals, as found in __cstring. virtual void tryAddingPcLoadReferenceComment(raw_ostream &cStream, diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 5cdb176e8e2477522eacc6d23ca289bd2b5a8ee0..3b0d3db9760684571d6a5dbacfc4f98d13941080 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -42,16 +42,16 @@ class raw_ostream; class SMLoc; class SourceMgr; -/// \brief Instances of this class represent the name of the dwarf +/// Instances of this class represent the name of the dwarf /// .file directive and its associated dwarf file number in the MC file, /// and MCDwarfFile's are created and uniqued by the MCContext class where /// the file number for each is its index into the vector of DwarfFiles (note /// index 0 is not used and not a valid dwarf file number). struct MCDwarfFile { - // \brief The base name of the file without its directory path. + // The base name of the file without its directory path. std::string Name; - // \brief The index into the list of directory names for this file name. + // The index into the list of directory names for this file name. unsigned DirIndex; /// The MD5 checksum, if there is one. Non-owning pointer to data allocated @@ -63,7 +63,7 @@ struct MCDwarfFile { Optional Source; }; -/// \brief Instances of this class represent the information from a +/// Instances of this class represent the information from a /// dwarf .loc directive. class MCDwarfLoc { uint32_t FileNum; @@ -95,55 +95,55 @@ private: // MCContext manages these // for an MCDwarfLoc object. public: - /// \brief Get the FileNum of this MCDwarfLoc. + /// Get the FileNum of this MCDwarfLoc. unsigned getFileNum() const { return FileNum; } - /// \brief Get the Line of this MCDwarfLoc. + /// Get the Line of this MCDwarfLoc. unsigned getLine() const { return Line; } - /// \brief Get the Column of this MCDwarfLoc. + /// Get the Column of this MCDwarfLoc. unsigned getColumn() const { return Column; } - /// \brief Get the Flags of this MCDwarfLoc. + /// Get the Flags of this MCDwarfLoc. unsigned getFlags() const { return Flags; } - /// \brief Get the Isa of this MCDwarfLoc. + /// Get the Isa of this MCDwarfLoc. unsigned getIsa() const { return Isa; } - /// \brief Get the Discriminator of this MCDwarfLoc. + /// Get the Discriminator of this MCDwarfLoc. unsigned getDiscriminator() const { return Discriminator; } - /// \brief Set the FileNum of this MCDwarfLoc. + /// Set the FileNum of this MCDwarfLoc. void setFileNum(unsigned fileNum) { FileNum = fileNum; } - /// \brief Set the Line of this MCDwarfLoc. + /// Set the Line of this MCDwarfLoc. void setLine(unsigned line) { Line = line; } - /// \brief Set the Column of this MCDwarfLoc. + /// Set the Column of this MCDwarfLoc. void setColumn(unsigned column) { assert(column <= UINT16_MAX); Column = column; } - /// \brief Set the Flags of this MCDwarfLoc. + /// Set the Flags of this MCDwarfLoc. void setFlags(unsigned flags) { assert(flags <= UINT8_MAX); Flags = flags; } - /// \brief Set the Isa of this MCDwarfLoc. + /// Set the Isa of this MCDwarfLoc. void setIsa(unsigned isa) { assert(isa <= UINT8_MAX); Isa = isa; } - /// \brief Set the Discriminator of this MCDwarfLoc. + /// Set the Discriminator of this MCDwarfLoc. void setDiscriminator(unsigned discriminator) { Discriminator = discriminator; } }; -/// \brief Instances of this class represent the line information for +/// Instances of this class represent the line information for /// the dwarf line table entries. Which is created after a machine /// instruction is assembled and uses an address from a temporary label /// created at the current address in the current section and the info from @@ -168,13 +168,13 @@ public: static void Make(MCObjectStreamer *MCOS, MCSection *Section); }; -/// \brief Instances of this class represent the line information for a compile +/// Instances of this class represent the line information for a compile /// unit where machine instructions have been assembled after seeing .loc /// directives. This is the information used to build the dwarf line /// table for a section. class MCLineSection { public: - // \brief Add an entry to this MCLineSection's line entries. + // Add an entry to this MCLineSection's line entries. void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { MCLineDivisions[Sec].push_back(LineEntry); } @@ -422,41 +422,41 @@ private: } public: - /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from + /// .cfi_def_cfa defines a rule for computing CFA as: take address from /// Register and add Offset to it. static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register, int Offset) { return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); } - /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now + /// .cfi_def_cfa_register modifies a rule for computing CFA. From now /// on Register will be used instead of the old one. Offset remains the same. static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) { return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); } - /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register + /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register /// remains the same, but offset is new. Note that it is the absolute offset /// that will be added to a defined register to the compute CFA address. static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); } - /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but + /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but /// Offset is a relative value that is added/subtracted from the previous /// offset. static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) { return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); } - /// \brief .cfi_offset Previous value of Register is saved at offset Offset + /// .cfi_offset Previous value of Register is saved at offset Offset /// from CFA. static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset) { return MCCFIInstruction(OpOffset, L, Register, Offset, ""); } - /// \brief .cfi_rel_offset Previous value of Register is saved at offset + /// .cfi_rel_offset Previous value of Register is saved at offset /// Offset from the current CFA register. This is transformed to .cfi_offset /// using the known displacement of the CFA register from the CFA. static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register, @@ -464,54 +464,54 @@ public: return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); } - /// \brief .cfi_register Previous value of Register1 is saved in + /// .cfi_register Previous value of Register1 is saved in /// register Register2. static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) { return MCCFIInstruction(OpRegister, L, Register1, Register2); } - /// \brief .cfi_window_save SPARC register window is saved. + /// .cfi_window_save SPARC register window is saved. static MCCFIInstruction createWindowSave(MCSymbol *L) { return MCCFIInstruction(OpWindowSave, L, 0, 0, ""); } - /// \brief .cfi_restore says that the rule for Register is now the same as it + /// .cfi_restore says that the rule for Register is now the same as it /// was at the beginning of the function, after all initial instructions added /// by .cfi_startproc were executed. static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { return MCCFIInstruction(OpRestore, L, Register, 0, ""); } - /// \brief .cfi_undefined From now on the previous value of Register can't be + /// .cfi_undefined From now on the previous value of Register can't be /// restored anymore. static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { return MCCFIInstruction(OpUndefined, L, Register, 0, ""); } - /// \brief .cfi_same_value Current value of Register is the same as in the + /// .cfi_same_value Current value of Register is the same as in the /// previous frame. I.e., no restoration is needed. static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { return MCCFIInstruction(OpSameValue, L, Register, 0, ""); } - /// \brief .cfi_remember_state Save all current rules for all registers. + /// .cfi_remember_state Save all current rules for all registers. static MCCFIInstruction createRememberState(MCSymbol *L) { return MCCFIInstruction(OpRememberState, L, 0, 0, ""); } - /// \brief .cfi_restore_state Restore the previously saved state. + /// .cfi_restore_state Restore the previously saved state. static MCCFIInstruction createRestoreState(MCSymbol *L) { return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); } - /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind + /// .cfi_escape Allows the user to add arbitrary bytes to the unwind /// info. static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { return MCCFIInstruction(OpEscape, L, 0, 0, Vals); } - /// \brief A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE + /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) { return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, ""); } diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index fd8d118ccdc5ede397ca02436a91712756fed15f..bff58fef6af9cad3f994db451c6958531cfccd56 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -12,6 +12,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" #include @@ -50,7 +51,7 @@ struct ELFRelocationEntry { void dump() const { print(errs()); } }; -class MCELFObjectTargetWriter { +class MCELFObjectTargetWriter : public MCObjectTargetWriter { const uint8_t OSABI; const uint16_t EMachine; const unsigned HasRelocationAddend : 1; @@ -63,6 +64,11 @@ protected: public: virtual ~MCELFObjectTargetWriter() = default; + virtual Triple::ObjectFormatType getFormat() const { return Triple::ELF; } + static bool classof(const MCObjectTargetWriter *W) { + return W->getFormat() == Triple::ELF; + } + static uint8_t getOSABI(Triple::OSType OSType) { switch (OSType) { case Triple::CloudABI: @@ -132,7 +138,7 @@ public: } }; -/// \brief Construct a new ELF writer instance. +/// Construct a new ELF writer instance. /// /// \param MOTW - The target specific ELF writer subclass. /// \param OS - The stream to write to. @@ -141,6 +147,11 @@ std::unique_ptr createELFObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS, bool IsLittleEndian); +std::unique_ptr +createELFDwoObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS, + bool IsLittleEndian); + } // end namespace llvm #endif // LLVM_MC_MCELFOBJECTWRITER_H diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 2f23cd64ee03f5073a10996c9d64ea16ad343051..b1b083f8fef32b2a13246e98ae0bda278a9aee2f 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -24,7 +24,8 @@ class MCInst; class MCELFStreamer : public MCObjectStreamer { public: MCELFStreamer(MCContext &Context, std::unique_ptr TAB, - raw_pwrite_stream &OS, std::unique_ptr Emitter); + std::unique_ptr OW, + std::unique_ptr Emitter); ~MCELFStreamer() override = default; @@ -68,6 +69,9 @@ public: void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override; + void emitCGProfileEntry(const MCSymbolRefExpr *From, + const MCSymbolRefExpr *To, uint64_t Count) override; + void FinishImpl() override; void EmitBundleAlignMode(unsigned AlignPow2) override; @@ -80,8 +84,10 @@ private: void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; void fixSymbolsInTLSFixups(const MCExpr *expr); + void finalizeCGProfileEntry(const MCSymbolRefExpr *&S); + void finalizeCGProfile(); - /// \brief Merge the content of the fragment \p EF into the fragment \p DF. + /// Merge the content of the fragment \p EF into the fragment \p DF. void mergeFragment(MCDataFragment *, MCDataFragment *); bool SeenIdent = false; @@ -93,7 +99,7 @@ private: MCELFStreamer *createARMELFStreamer(MCContext &Context, std::unique_ptr TAB, - raw_pwrite_stream &OS, + std::unique_ptr OW, std::unique_ptr Emitter, bool RelaxAll, bool IsThumb); diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index fcbbe650d26f3f150da7bc6eacc927eb1fad3b8c..55279a0d213de4aa8d1be680bcb6e5402fb4a8fc 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -31,7 +31,7 @@ class StringRef; using SectionAddrMap = DenseMap; -/// \brief Base class for the full range of assembler expressions which are +/// Base class for the full range of assembler expressions which are /// needed for parsing. class MCExpr { public: @@ -85,7 +85,7 @@ public: /// \name Expression Evaluation /// @{ - /// \brief Try to evaluate the expression to an absolute value. + /// Try to evaluate the expression to an absolute value. /// /// \param Res - The absolute value, if evaluation succeeds. /// \param Layout - The assembler layout object to use for evaluating symbol @@ -96,11 +96,12 @@ public: const SectionAddrMap &Addrs) const; bool evaluateAsAbsolute(int64_t &Res) const; bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const; bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; - /// \brief Try to evaluate the expression to a relocatable value, i.e. an + /// Try to evaluate the expression to a relocatable value, i.e. an /// expression of the fixed form (a - b + constant). /// /// \param Res - The relocatable value, if evaluation succeeds. @@ -110,14 +111,14 @@ public: bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const; - /// \brief Try to evaluate the expression to the form (a - b + constant) where + /// Try to evaluate the expression to the form (a - b + constant) where /// neither a nor b are variables. /// /// This is a more aggressive variant of evaluateAsRelocatable. The intended /// use is for when relocations are not available, like the .size directive. bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; - /// \brief Find the "associated section" for this expression, which is + /// Find the "associated section" for this expression, which is /// currently defined as the absolute section for constants, or /// otherwise the section associated with the first defined symbol in the /// expression. @@ -131,7 +132,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { return OS; } -//// \brief Represent a constant integer expression. +//// Represent a constant integer expression. class MCConstantExpr : public MCExpr { int64_t Value; @@ -157,7 +158,7 @@ public: } }; -/// \brief Represent a reference to a symbol from inside an expression. +/// Represent a reference to a symbol from inside an expression. /// /// A symbol reference in an expression may be a use of a label, a use of an /// assembler variable (defined constant), or constitute an implicit definition @@ -346,7 +347,7 @@ public: } }; -/// \brief Unary assembler expressions. +/// Unary assembler expressions. class MCUnaryExpr : public MCExpr { public: enum Opcode { @@ -390,10 +391,10 @@ public: /// \name Accessors /// @{ - /// \brief Get the kind of this unary expression. + /// Get the kind of this unary expression. Opcode getOpcode() const { return Op; } - /// \brief Get the child of this unary expression. + /// Get the child of this unary expression. const MCExpr *getSubExpr() const { return Expr; } /// @} @@ -403,7 +404,7 @@ public: } }; -/// \brief Binary assembler expressions. +/// Binary assembler expressions. class MCBinaryExpr : public MCExpr { public: enum Opcode { @@ -547,13 +548,13 @@ public: /// \name Accessors /// @{ - /// \brief Get the kind of this binary expression. + /// Get the kind of this binary expression. Opcode getOpcode() const { return Op; } - /// \brief Get the left-hand side expression of the binary operator. + /// Get the left-hand side expression of the binary operator. const MCExpr *getLHS() const { return LHS; } - /// \brief Get the right-hand side expression of the binary operator. + /// Get the right-hand side expression of the binary operator. const MCExpr *getRHS() const { return RHS; } /// @} @@ -563,7 +564,7 @@ public: } }; -/// \brief This is an extension point for target-specific MCExpr subclasses to +/// This is an extension point for target-specific MCExpr subclasses to /// implement. /// /// NOTE: All subclasses are required to have trivial destructors because diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index b83086c327f2e3015e4eef3980a0c257db8b662a..5f301eafc556795a3e2470d5ddc820959f206e62 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -19,7 +19,7 @@ namespace llvm { class MCExpr; -/// \brief Extensible enumeration to represent the type of a fixup. +/// Extensible enumeration to represent the type of a fixup. enum MCFixupKind { FK_Data_1 = 0, ///< A one-byte fixup. FK_Data_2, ///< A two-byte fixup. @@ -41,6 +41,14 @@ enum MCFixupKind { FK_SecRel_2, ///< A two-byte section relative fixup. FK_SecRel_4, ///< A four-byte section relative fixup. FK_SecRel_8, ///< A eight-byte section relative fixup. + FK_Data_Add_1, ///< A one-byte add fixup. + FK_Data_Add_2, ///< A two-byte add fixup. + FK_Data_Add_4, ///< A four-byte add fixup. + FK_Data_Add_8, ///< A eight-byte add fixup. + FK_Data_Sub_1, ///< A one-byte sub fixup. + FK_Data_Sub_2, ///< A two-byte sub fixup. + FK_Data_Sub_4, ///< A four-byte sub fixup. + FK_Data_Sub_8, ///< A eight-byte sub fixup. FirstTargetFixupKind = 128, @@ -49,7 +57,7 @@ enum MCFixupKind { MaxTargetFixupKind = (1 << 8) }; -/// \brief Encode information on a single operation to perform on a byte +/// Encode information on a single operation to perform on a byte /// sequence (e.g., an encoded instruction) which requires assemble- or run- /// time patching. /// @@ -90,6 +98,28 @@ public: return FI; } + /// Return a fixup corresponding to the add half of a add/sub fixup pair for + /// the given Fixup. + static MCFixup createAddFor(const MCFixup &Fixup) { + MCFixup FI; + FI.Value = Fixup.getValue(); + FI.Offset = Fixup.getOffset(); + FI.Kind = (unsigned)getAddKindForKind(Fixup.getKind()); + FI.Loc = Fixup.getLoc(); + return FI; + } + + /// Return a fixup corresponding to the sub half of a add/sub fixup pair for + /// the given Fixup. + static MCFixup createSubFor(const MCFixup &Fixup) { + MCFixup FI; + FI.Value = Fixup.getValue(); + FI.Offset = Fixup.getOffset(); + FI.Kind = (unsigned)getSubKindForKind(Fixup.getKind()); + FI.Loc = Fixup.getLoc(); + return FI; + } + MCFixupKind getKind() const { return MCFixupKind(Kind); } uint32_t getOffset() const { return Offset; } @@ -97,7 +127,7 @@ public: const MCExpr *getValue() const { return Value; } - /// \brief Return the generic fixup kind for a value with the given size. It + /// Return the generic fixup kind for a value with the given size. It /// is an error to pass an unsupported size. static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { switch (Size) { @@ -109,6 +139,30 @@ public: } } + /// Return the generic fixup kind for an addition with a given size. It + /// is an error to pass an unsupported size. + static MCFixupKind getAddKindForKind(unsigned Kind) { + switch (Kind) { + default: llvm_unreachable("Unknown type to convert!"); + case FK_Data_1: return FK_Data_Add_1; + case FK_Data_2: return FK_Data_Add_2; + case FK_Data_4: return FK_Data_Add_4; + case FK_Data_8: return FK_Data_Add_8; + } + } + + /// Return the generic fixup kind for an subtraction with a given size. It + /// is an error to pass an unsupported size. + static MCFixupKind getSubKindForKind(unsigned Kind) { + switch (Kind) { + default: llvm_unreachable("Unknown type to convert!"); + case FK_Data_1: return FK_Data_Sub_1; + case FK_Data_2: return FK_Data_Sub_2; + case FK_Data_4: return FK_Data_Sub_4; + case FK_Data_8: return FK_Data_Sub_8; + } + } + SMLoc getLoc() const { return Loc; } }; diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h index 58183bd778e634c9ca2f3e2be823891dbe9d1145..483abb39403fff8fee18ae42a2ca60d2c6f64f5e 100644 --- a/include/llvm/MC/MCFixupKindInfo.h +++ b/include/llvm/MC/MCFixupKindInfo.h @@ -12,7 +12,7 @@ namespace llvm { -/// \brief Target independent information on a fixup kind. +/// Target independent information on a fixup kind. struct MCFixupKindInfo { enum FixupKindFlags { /// Is this fixup kind PCrelative? This is used by the assembler backend to diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index 38c365538e3cbdf3f354f3c796a0a0b5734ee897..95878f81c86ce057d91167a43a4d2d7bacb1e15b 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -56,7 +56,7 @@ protected: bool HasInstructions; private: - /// \brief Should this fragment be aligned to the end of a bundle? + /// Should this fragment be aligned to the end of a bundle? bool AlignToBundleEnd; uint8_t BundlePadding; @@ -67,7 +67,7 @@ private: /// The data for the section this fragment is in. MCSection *Parent; - /// Atom - The atom this fragment is in, as represented by it's defining + /// Atom - The atom this fragment is in, as represented by its defining /// symbol. const MCSymbol *Atom; @@ -110,26 +110,26 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - /// \brief Does this fragment have instructions emitted into it? By default + /// Does this fragment have instructions emitted into it? By default /// this is false, but specific fragment types may set it to true. bool hasInstructions() const { return HasInstructions; } - /// \brief Should this fragment be placed at the end of an aligned bundle? + /// Should this fragment be placed at the end of an aligned bundle? bool alignToBundleEnd() const { return AlignToBundleEnd; } void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } - /// \brief Get the padding size that must be inserted before this fragment. + /// Get the padding size that must be inserted before this fragment. /// Used for bundling. By default, no padding is inserted. /// Note that padding size is restricted to 8 bits. This is an optimization /// to reduce the amount of space used for each fragment. In practice, larger /// padding should never be required. uint8_t getBundlePadding() const { return BundlePadding; } - /// \brief Set the padding size for this fragment. By default it's a no-op, + /// Set the padding size for this fragment. By default it's a no-op, /// and only some fragments have a meaningful implementation. void setBundlePadding(uint8_t N) { BundlePadding = N; } - /// \brief Return true if given frgment has FT_Dummy type. + /// Return true if given frgment has FT_Dummy type. bool isDummy() const { return Kind == FT_Dummy; } void dump() const; @@ -419,22 +419,23 @@ public: class MCFillFragment : public MCFragment { /// Value to use for filling bytes. - uint8_t Value; - + uint64_t Value; + uint8_t ValueSize; /// The number of bytes to insert. - const MCExpr &Size; + const MCExpr &NumValues; /// Source location of the directive that this fragment was created for. SMLoc Loc; public: - MCFillFragment(uint8_t Value, const MCExpr &Size, SMLoc Loc, - MCSection *Sec = nullptr) - : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size), Loc(Loc) { - } - - uint8_t getValue() const { return Value; } - const MCExpr &getSize() const { return Size; } + MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues, + SMLoc Loc, MCSection *Sec = nullptr) + : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(VSize), + NumValues(NumValues), Loc(Loc) {} + + uint64_t getValue() const { return Value; } + uint8_t getValueSize() const { return ValueSize; } + const MCExpr &getNumValues() const { return NumValues; } SMLoc getLoc() const { return Loc; } diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index db28fd0fd6d9d6308d47e78fe2df341f8cf8decc..67bb11a703872731d4eeb9693bb321ab0f9558ed 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -30,7 +30,7 @@ class MCInst; class MCInstPrinter; class raw_ostream; -/// \brief Instances of this class represent operands of the MCInst class. +/// Instances of this class represent operands of the MCInst class. /// This is a simple discriminated union. class MCOperand { enum MachineOperandType : unsigned char { @@ -61,13 +61,13 @@ public: bool isExpr() const { return Kind == kExpr; } bool isInst() const { return Kind == kInst; } - /// \brief Returns the register number. + /// Returns the register number. unsigned getReg() const { assert(isReg() && "This is not a register operand!"); return RegVal; } - /// \brief Set the register number. + /// Set the register number. void setReg(unsigned Reg) { assert(isReg() && "This is not a register operand!"); RegVal = Reg; @@ -150,11 +150,13 @@ public: void print(raw_ostream &OS) const; void dump() const; + bool isBareSymbolRef() const; + bool evaluateAsConstantImm(int64_t &Imm) const; }; template <> struct isPodLike { static const bool value = true; }; -/// \brief Instances of this class represent a single low-level machine +/// Instances of this class represent a single low-level machine /// instruction. class MCInst { unsigned Opcode = 0; @@ -201,7 +203,7 @@ public: void print(raw_ostream &OS) const; void dump() const; - /// \brief Dump the MCInst as prettily as possible using the additional MC + /// Dump the MCInst as prettily as possible using the additional MC /// structures, if given. Operators are separated by the \p Separator /// string. void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr, diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h index 30609bdb8b27a39b2d388756201424b8e3dde505..c5c4f481e7df8b7f1da0d9c96b43e7b833ac091c 100644 --- a/include/llvm/MC/MCInstBuilder.h +++ b/include/llvm/MC/MCInstBuilder.h @@ -23,42 +23,42 @@ class MCInstBuilder { MCInst Inst; public: - /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode. + /// Create a new MCInstBuilder for an MCInst with a specific opcode. MCInstBuilder(unsigned Opcode) { Inst.setOpcode(Opcode); } - /// \brief Add a new register operand. + /// Add a new register operand. MCInstBuilder &addReg(unsigned Reg) { Inst.addOperand(MCOperand::createReg(Reg)); return *this; } - /// \brief Add a new integer immediate operand. + /// Add a new integer immediate operand. MCInstBuilder &addImm(int64_t Val) { Inst.addOperand(MCOperand::createImm(Val)); return *this; } - /// \brief Add a new floating point immediate operand. + /// Add a new floating point immediate operand. MCInstBuilder &addFPImm(double Val) { Inst.addOperand(MCOperand::createFPImm(Val)); return *this; } - /// \brief Add a new MCExpr operand. + /// Add a new MCExpr operand. MCInstBuilder &addExpr(const MCExpr *Val) { Inst.addOperand(MCOperand::createExpr(Val)); return *this; } - /// \brief Add a new MCInst operand. + /// Add a new MCInst operand. MCInstBuilder &addInst(const MCInst *Val) { Inst.addOperand(MCOperand::createInst(Val)); return *this; } - /// \brief Add an operand. + /// Add an operand. MCInstBuilder &addOperand(const MCOperand &Op) { Inst.addOperand(Op); return *this; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 069403074b31c7c3c76a7061add6d126687d736c..b8bb085538dec60846f01a9bea7769d7303a2720 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -36,11 +36,11 @@ enum Style { } // end namespace HexStyle -/// \brief This is an instance of a target assembly language printer that +/// This is an instance of a target assembly language printer that /// converts an MCInst to valid target assembly syntax. class MCInstPrinter { protected: - /// \brief A stream that comments can be emitted to if desired. Each comment + /// A stream that comments can be emitted to if desired. Each comment /// must end with a newline. This will be null if verbose assembly emission /// is disable. raw_ostream *CommentStream = nullptr; @@ -66,18 +66,18 @@ public: virtual ~MCInstPrinter(); - /// \brief Specify a stream to emit comments to. + /// Specify a stream to emit comments to. void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } - /// \brief Print the specified MCInst to the specified raw_ostream. + /// Print the specified MCInst to the specified raw_ostream. virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) = 0; - /// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or + /// Return the name of the specified opcode enum (e.g. "MOV32ri") or /// empty if we can't resolve it. StringRef getOpcodeName(unsigned Opcode) const; - /// \brief Print the assembler register name. + /// Print the assembler register name. virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; bool getUseMarkup() const { return UseMarkup; } diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h index dd3e1df477b45bb728ab67bd94b62f2b9a64b720..2898c2712416bc8fb65d9d3b553ed4d942203b5c 100644 --- a/include/llvm/MC/MCInstrAnalysis.h +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -60,7 +60,7 @@ public: return Info->get(Inst.getOpcode()).isTerminator(); } - /// \brief Given a branch instruction try to get the address the branch + /// Given a branch instruction try to get the address the branch /// targets. Return true on success, and the address in Target. virtual bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index ff4c756a66a1293c730619f02feb82837f7674c5..3f8749571ef4b56761950a176ff124cd667fa575 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -35,12 +35,12 @@ enum OperandConstraint { EARLY_CLOBBER // Operand is an early clobber register operand }; -/// \brief These are flags set on operands, but should be considered +/// These are flags set on operands, but should be considered /// private, all access should go through the MCOperandInfo accessors. /// See the accessors for a description of what these are. enum OperandFlags { LookupPtrRegClass = 0, Predicate, OptionalDef }; -/// \brief Operands are tagged with one of the values of this enum. +/// Operands are tagged with one of the values of this enum. enum OperandType { OPERAND_UNKNOWN = 0, OPERAND_IMMEDIATE = 1, @@ -60,42 +60,39 @@ enum OperandType { OPERAND_FIRST_TARGET = 12, }; -enum GenericOperandType { -}; - } -/// \brief This holds information about one operand of a machine instruction, +/// This holds information about one operand of a machine instruction, /// indicating the register class for register operands, etc. class MCOperandInfo { public: - /// \brief This specifies the register class enumeration of the operand + /// This specifies the register class enumeration of the operand /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. int16_t RegClass; - /// \brief These are flags from the MCOI::OperandFlags enum. + /// These are flags from the MCOI::OperandFlags enum. uint8_t Flags; - /// \brief Information about the type of the operand. + /// Information about the type of the operand. uint8_t OperandType; - /// \brief The lower 16 bits are used to specify which constraints are set. + /// The lower 16 bits are used to specify which constraints are set. /// The higher 16 bits are used to specify the value of constraints (4 bits /// each). uint32_t Constraints; - /// \brief Set if this operand is a pointer value and it requires a callback + /// Set if this operand is a pointer value and it requires a callback /// to look up its register class. bool isLookupPtrRegClass() const { return Flags & (1 << MCOI::LookupPtrRegClass); } - /// \brief Set if this is one of the operands that made up of the predicate + /// Set if this is one of the operands that made up of the predicate /// operand that controls an isPredicable() instruction. bool isPredicate() const { return Flags & (1 << MCOI::Predicate); } - /// \brief Set if this operand is a optional def. + /// Set if this operand is a optional def. bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); } bool isGenericType() const { @@ -114,7 +111,7 @@ public: //===----------------------------------------------------------------------===// namespace MCID { -/// \brief These should be considered private to the implementation of the +/// These should be considered private to the implementation of the /// MCInstrDesc class. Clients should use the predicate methods on MCInstrDesc, /// not use these directly. These all correspond to bitfields in the /// MCInstrDesc::Flags field. @@ -130,6 +127,7 @@ enum Flag { IndirectBranch, Compare, MoveImm, + MoveReg, Bitcast, Select, DelaySlot, @@ -155,7 +153,7 @@ enum Flag { }; } -/// \brief Describe properties that are true of each instruction in the target +/// Describe properties that are true of each instruction in the target /// description file. This captures information about side effects, register /// use and many other things. There is one instance of this struct for each /// target instruction class, and the MachineInstr class points to this struct @@ -177,12 +175,12 @@ public: // deprecated due to a "complex" reason, below. int64_t DeprecatedFeature; - // A complex method to determine is a certain is deprecated or not, and return - // the reason for deprecation. + // A complex method to determine if a certain instruction is deprecated or + // not, and return the reason for deprecation. bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &, std::string &); - /// \brief Returns the value of the specific constraint if + /// Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const { @@ -194,15 +192,15 @@ public: return -1; } - /// \brief Returns true if a certain instruction is deprecated and if so + /// Returns true if a certain instruction is deprecated and if so /// returns the reason in \p Info. bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, std::string &Info) const; - /// \brief Return the opcode number for this descriptor. + /// Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; } - /// \brief Return the number of declared MachineOperands for this + /// Return the number of declared MachineOperands for this /// MachineInstruction. Note that variadic (isVariadic() returns true) /// instructions may have additional operands at the end of the list, and note /// that the machine instruction may include implicit register def/uses as @@ -218,44 +216,47 @@ public: return make_range(opInfo_begin(), opInfo_end()); } - /// \brief Return the number of MachineOperands that are register + /// Return the number of MachineOperands that are register /// definitions. Register definitions always occur at the start of the /// machine operand list. This is the number of "outs" in the .td file, /// and does not include implicit defs. unsigned getNumDefs() const { return NumDefs; } - /// \brief Return flags of this instruction. + /// Return flags of this instruction. uint64_t getFlags() const { return Flags; } - /// \brief Return true if this instruction can have a variable number of + /// Return true if this instruction can have a variable number of /// operands. In this case, the variable operands will be after the normal /// operands but before the implicit definitions and uses (if any are /// present). bool isVariadic() const { return Flags & (1ULL << MCID::Variadic); } - /// \brief Set if this instruction has an optional definition, e.g. + /// Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. bool hasOptionalDef() const { return Flags & (1ULL << MCID::HasOptionalDef); } - /// \brief Return true if this is a pseudo instruction that doesn't + /// Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. bool isPseudo() const { return Flags & (1ULL << MCID::Pseudo); } - /// \brief Return true if the instruction is a return. + /// Return true if the instruction is a return. bool isReturn() const { return Flags & (1ULL << MCID::Return); } - /// \brief Return true if the instruction is an add instruction. + /// Return true if the instruction is an add instruction. bool isAdd() const { return Flags & (1ULL << MCID::Add); } - /// \brief Return true if the instruction is a call. + /// Return true if the instruction is a register to register move. + bool isMoveReg() const { return Flags & (1ULL << MCID::MoveReg); } + + /// Return true if the instruction is a call. bool isCall() const { return Flags & (1ULL << MCID::Call); } - /// \brief Returns true if the specified instruction stops control flow + /// Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. bool isBarrier() const { return Flags & (1ULL << MCID::Barrier); } - /// \brief Returns true if this instruction part of the terminator for + /// Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch /// instructions. /// @@ -263,17 +264,17 @@ public: /// but before control flow occurs. bool isTerminator() const { return Flags & (1ULL << MCID::Terminator); } - /// \brief Returns true if this is a conditional, unconditional, or + /// Returns true if this is a conditional, unconditional, or /// indirect branch. Predicates below can be used to discriminate between /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. bool isBranch() const { return Flags & (1ULL << MCID::Branch); } - /// \brief Return true if this is an indirect branch, such as a + /// Return true if this is an indirect branch, such as a /// branch through a register. bool isIndirectBranch() const { return Flags & (1ULL << MCID::IndirectBranch); } - /// \brief Return true if this is a branch which may fall + /// Return true if this is a branch which may fall /// through to the next instruction or may transfer control flow to some other /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more /// information about this branch. @@ -281,7 +282,7 @@ public: return isBranch() & !isBarrier() & !isIndirectBranch(); } - /// \brief Return true if this is a branch which always + /// Return true if this is a branch which always /// transfers control flow to some other block. The /// TargetInstrInfo::AnalyzeBranch method can be used to get more information /// about this branch. @@ -289,40 +290,40 @@ public: return isBranch() & isBarrier() & !isIndirectBranch(); } - /// \brief Return true if this is a branch or an instruction which directly + /// Return true if this is a branch or an instruction which directly /// writes to the program counter. Considered 'may' affect rather than /// 'does' affect as things like predication are not taken into account. bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const; - /// \brief Return true if this instruction has a predicate operand + /// Return true if this instruction has a predicate operand /// that controls execution. It may be set to 'always', or may be set to other /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. bool isPredicable() const { return Flags & (1ULL << MCID::Predicable); } - /// \brief Return true if this instruction is a comparison. + /// Return true if this instruction is a comparison. bool isCompare() const { return Flags & (1ULL << MCID::Compare); } - /// \brief Return true if this instruction is a move immediate + /// Return true if this instruction is a move immediate /// (including conditional moves) instruction. bool isMoveImmediate() const { return Flags & (1ULL << MCID::MoveImm); } - /// \brief Return true if this instruction is a bitcast instruction. + /// Return true if this instruction is a bitcast instruction. bool isBitcast() const { return Flags & (1ULL << MCID::Bitcast); } - /// \brief Return true if this is a select instruction. + /// Return true if this is a select instruction. bool isSelect() const { return Flags & (1ULL << MCID::Select); } - /// \brief Return true if this instruction cannot be safely + /// Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable() const { return Flags & (1ULL << MCID::NotDuplicable); } - /// \brief Returns true if the specified instruction has a delay slot which + /// Returns true if the specified instruction has a delay slot which /// must be filled by the code generator. bool hasDelaySlot() const { return Flags & (1ULL << MCID::DelaySlot); } - /// \brief Return true for instructions that can be folded as memory operands + /// Return true for instructions that can be folded as memory operands /// in other instructions. The most common use for this is instructions that /// are simple loads from memory that don't modify the loaded value in any /// way, but it can also be used for instructions that can be expressed as @@ -331,7 +332,7 @@ public: /// that return a value in their only virtual register definition. bool canFoldAsLoad() const { return Flags & (1ULL << MCID::FoldableAsLoad); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic REG_SEQUENCE instructions. /// E.g., on ARM, /// dX VMOVDRR rY, rZ @@ -343,7 +344,7 @@ public: /// override accordingly. bool isRegSequenceLike() const { return Flags & (1ULL << MCID::RegSequence); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic EXTRACT_SUBREG instructions. /// E.g., on ARM, /// rX, rY VMOVRRD dZ @@ -358,7 +359,7 @@ public: return Flags & (1ULL << MCID::ExtractSubreg); } - /// \brief Return true if this instruction behaves + /// Return true if this instruction behaves /// the same way as the generic INSERT_SUBREG instructions. /// E.g., on ARM, /// dX = VSETLNi32 dY, rZ, Imm @@ -371,7 +372,7 @@ public: bool isInsertSubregLike() const { return Flags & (1ULL << MCID::InsertSubreg); } - /// \brief Return true if this instruction is convergent. + /// Return true if this instruction is convergent. /// /// Convergent instructions may not be made control-dependent on any /// additional values. @@ -381,18 +382,18 @@ public: // Side Effect Analysis //===--------------------------------------------------------------------===// - /// \brief Return true if this instruction could possibly read memory. + /// Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. bool mayLoad() const { return Flags & (1ULL << MCID::MayLoad); } - /// \brief Return true if this instruction could possibly modify memory. + /// Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. bool mayStore() const { return Flags & (1ULL << MCID::MayStore); } - /// \brief Return true if this instruction has side + /// Return true if this instruction has side /// effects that are not modeled by other flags. This does not return true /// for instructions whose effects are captured by: /// @@ -412,7 +413,7 @@ public: // Flags that indicate whether an instruction can be modified by a method. //===--------------------------------------------------------------------===// - /// \brief Return true if this may be a 2- or 3-address instruction (of the + /// Return true if this may be a 2- or 3-address instruction (of the /// form "X = op Y, Z, ..."), which produces the same result if Y and Z are /// exchanged. If this flag is set, then the /// TargetInstrInfo::commuteInstruction method may be used to hack on the @@ -424,7 +425,7 @@ public: /// commute them. bool isCommutable() const { return Flags & (1ULL << MCID::Commutable); } - /// \brief Return true if this is a 2-address instruction which can be changed + /// Return true if this is a 2-address instruction which can be changed /// into a 3-address instruction if needed. Doing this transformation can be /// profitable in the register allocator, because it means that the /// instruction can use a 2-address form if possible, but degrade into a less @@ -442,7 +443,7 @@ public: return Flags & (1ULL << MCID::ConvertibleTo3Addr); } - /// \brief Return true if this instruction requires custom insertion support + /// Return true if this instruction requires custom insertion support /// when the DAG scheduler is inserting it into a machine basic block. If /// this is true for the instruction, it basically means that it is a pseudo /// instruction used at SelectionDAG time that is expanded out into magic code @@ -454,13 +455,13 @@ public: return Flags & (1ULL << MCID::UsesCustomInserter); } - /// \brief Return true if this instruction requires *adjustment* after + /// Return true if this instruction requires *adjustment* after /// instruction selection by calling a target hook. For example, this can be /// used to fill in ARM 's' optional operand depending on whether the /// conditional flag register is used. bool hasPostISelHook() const { return Flags & (1ULL << MCID::HasPostISelHook); } - /// \brief Returns true if this instruction is a candidate for remat. This + /// Returns true if this instruction is a candidate for remat. This /// flag is only used in TargetInstrInfo method isTriviallyRematerializable. /// /// If this flag is set, the isReallyTriviallyReMaterializable() @@ -470,7 +471,7 @@ public: return Flags & (1ULL << MCID::Rematerializable); } - /// \brief Returns true if this instruction has the same cost (or less) than a + /// Returns true if this instruction has the same cost (or less) than a /// move instruction. This is useful during certain types of optimizations /// (e.g., remat during two-address conversion or machine licm) where we would /// like to remat or hoist the instruction, but not if it costs more than @@ -481,7 +482,7 @@ public: /// for different subtargets. bool isAsCheapAsAMove() const { return Flags & (1ULL << MCID::CheapAsAMove); } - /// \brief Returns true if this instruction source operands have special + /// Returns true if this instruction source operands have special /// register allocation requirements that are not captured by the operand /// register classes. e.g. ARM::STRD's two source registers must be an even / /// odd pair, ARM::STM registers have to be in ascending order. Post-register @@ -491,7 +492,7 @@ public: return Flags & (1ULL << MCID::ExtraSrcRegAllocReq); } - /// \brief Returns true if this instruction def operands have special register + /// Returns true if this instruction def operands have special register /// allocation requirements that are not captured by the operand register /// classes. e.g. ARM::LDRD's two def registers must be an even / odd pair, /// ARM::LDM registers have to be in ascending order. Post-register @@ -501,7 +502,7 @@ public: return Flags & (1ULL << MCID::ExtraDefRegAllocReq); } - /// \brief Return a list of registers that are potentially read by any + /// Return a list of registers that are potentially read by any /// instance of this machine instruction. For example, on X86, the "adc" /// instruction adds two register operands and adds the carry bit in from the /// flags register. In this case, the instruction is marked as implicitly @@ -511,7 +512,7 @@ public: /// This method returns null if the instruction has no implicit uses. const MCPhysReg *getImplicitUses() const { return ImplicitUses; } - /// \brief Return the number of implicit uses this instruction has. + /// Return the number of implicit uses this instruction has. unsigned getNumImplicitUses() const { if (!ImplicitUses) return 0; @@ -521,7 +522,7 @@ public: return i; } - /// \brief Return a list of registers that are potentially written by any + /// Return a list of registers that are potentially written by any /// instance of this machine instruction. For example, on X86, many /// instructions implicitly set the flags register. In this case, they are /// marked as setting the FLAGS. Likewise, many instructions always deposit @@ -533,7 +534,7 @@ public: /// This method returns null if the instruction has no implicit defs. const MCPhysReg *getImplicitDefs() const { return ImplicitDefs; } - /// \brief Return the number of implicit defs this instruct has. + /// Return the number of implicit defs this instruct has. unsigned getNumImplicitDefs() const { if (!ImplicitDefs) return 0; @@ -543,7 +544,7 @@ public: return i; } - /// \brief Return true if this instruction implicitly + /// Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { if (const MCPhysReg *ImpUses = ImplicitUses) @@ -553,22 +554,22 @@ public: return false; } - /// \brief Return true if this instruction implicitly + /// Return true if this instruction implicitly /// defines the specified physical register. bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI = nullptr) const; - /// \brief Return the scheduling class for this instruction. The + /// Return the scheduling class for this instruction. The /// scheduling class is an index into the InstrItineraryData table. This /// returns zero if there is no known scheduling information for the /// instruction. unsigned getSchedClass() const { return SchedClass; } - /// \brief Return the number of bytes in the encoding of this instruction, + /// Return the number of bytes in the encoding of this instruction, /// or zero if the encoding size cannot be known from the opcode. unsigned getSize() const { return Size; } - /// \brief Find the index of the first operand in the + /// Find the index of the first operand in the /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int findFirstPredOperandIdx() const { @@ -580,7 +581,7 @@ public: return -1; } - /// \brief Return true if this instruction defines the specified physical + /// Return true if this instruction defines the specified physical /// register, either explicitly or implicitly. bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, const MCRegisterInfo &RI) const; diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h index 80f1f320b7c20c399d0630f9e831fab3514bb35f..18da87cf89296cf2c04b01061c37eea91ddc144b 100644 --- a/include/llvm/MC/MCInstrInfo.h +++ b/include/llvm/MC/MCInstrInfo.h @@ -20,7 +20,7 @@ namespace llvm { //--------------------------------------------------------------------------- -/// \brief Interface to description of machine instruction set. +/// Interface to description of machine instruction set. class MCInstrInfo { const MCInstrDesc *Desc; // Raw array to allow static init'n const unsigned *InstrNameIndices; // Array for name indices in InstrNameData @@ -28,7 +28,7 @@ class MCInstrInfo { unsigned NumOpcodes; // Number of entries in the desc array public: - /// \brief Initialize MCInstrInfo, called by TableGen auto-generated routines. + /// Initialize MCInstrInfo, called by TableGen auto-generated routines. /// *DO NOT USE*. void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND, unsigned NO) { @@ -40,14 +40,14 @@ public: unsigned getNumOpcodes() const { return NumOpcodes; } - /// \brief Return the machine instruction descriptor that corresponds to the + /// Return the machine instruction descriptor that corresponds to the /// specified instruction opcode. const MCInstrDesc &get(unsigned Opcode) const { assert(Opcode < NumOpcodes && "Invalid opcode!"); return Desc[Opcode]; } - /// \brief Returns the name for the instructions with the given opcode. + /// Returns the name for the instructions with the given opcode. StringRef getName(unsigned Opcode) const { assert(Opcode < NumOpcodes && "Invalid opcode!"); return StringRef(&InstrNameData[InstrNameIndices[Opcode]]); diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h index f0824e76d6c3b3a8e1df96b8c6385a506f761666..fe81376e0db72008532129f610f32485980b0179 100644 --- a/include/llvm/MC/MCInstrItineraries.h +++ b/include/llvm/MC/MCInstrItineraries.h @@ -67,12 +67,12 @@ struct InstrStage { int NextCycles_; ///< Number of machine cycles to next stage ReservationKinds Kind_; ///< Kind of the FU reservation - /// \brief Returns the number of cycles the stage is occupied. + /// Returns the number of cycles the stage is occupied. unsigned getCycles() const { return Cycles_; } - /// \brief Returns the choice of FUs. + /// Returns the choice of FUs. unsigned getUnits() const { return Units_; } @@ -81,7 +81,7 @@ struct InstrStage { return Kind_; } - /// \brief Returns the number of cycles from the start of this stage to the + /// Returns the number of cycles from the start of this stage to the /// start of the next stage in the itinerary unsigned getNextCycles() const { return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_; @@ -120,28 +120,28 @@ public: : SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(SchedModel.InstrItineraries) {} - /// \brief Returns true if there are no itineraries. + /// Returns true if there are no itineraries. bool isEmpty() const { return Itineraries == nullptr; } - /// \brief Returns true if the index is for the end marker itinerary. + /// Returns true if the index is for the end marker itinerary. bool isEndMarker(unsigned ItinClassIndx) const { return ((Itineraries[ItinClassIndx].FirstStage == UINT16_MAX) && (Itineraries[ItinClassIndx].LastStage == UINT16_MAX)); } - /// \brief Return the first stage of the itinerary. + /// Return the first stage of the itinerary. const InstrStage *beginStage(unsigned ItinClassIndx) const { unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage; return Stages + StageIdx; } - /// \brief Return the last+1 stage of the itinerary. + /// Return the last+1 stage of the itinerary. const InstrStage *endStage(unsigned ItinClassIndx) const { unsigned StageIdx = Itineraries[ItinClassIndx].LastStage; return Stages + StageIdx; } - /// \brief Return the total stage latency of the given class. The latency is + /// Return the total stage latency of the given class. The latency is /// the maximum completion time for any stage in the itinerary. If no stages /// exist, it defaults to one cycle. unsigned getStageLatency(unsigned ItinClassIndx) const { @@ -160,7 +160,7 @@ public: return Latency; } - /// \brief Return the cycle for the given class and operand. Return -1 if no + /// Return the cycle for the given class and operand. Return -1 if no /// cycle is specified for the operand. int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const { if (isEmpty()) @@ -174,7 +174,7 @@ public: return (int)OperandCycles[FirstIdx + OperandIdx]; } - /// \brief Return true if there is a pipeline forwarding between instructions + /// Return true if there is a pipeline forwarding between instructions /// of itinerary classes DefClass and UseClasses so that value produced by an /// instruction of itinerary class DefClass, operand index DefIdx can be /// bypassed when it's read by an instruction of itinerary class UseClass, @@ -197,7 +197,7 @@ public: Forwardings[FirstUseIdx + UseIdx]; } - /// \brief Compute and return the use operand latency of a given itinerary + /// Compute and return the use operand latency of a given itinerary /// class and operand index if the value is produced by an instruction of the /// specified itinerary class and def operand index. int getOperandLatency(unsigned DefClass, unsigned DefIdx, @@ -221,7 +221,7 @@ public: return UseCycle; } - /// \brief Return the number of micro-ops that the given class decodes to. + /// Return the number of micro-ops that the given class decodes to. /// Return -1 for classes that require dynamic lookup via TargetInstrInfo. int getNumMicroOps(unsigned ItinClassIndx) const { if (isEmpty()) diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h index b6579fd654ab405a896357fa536945e4215cf125..aaf70691fc01aae0649f6d36851caf9b3a6a371e 100644 --- a/include/llvm/MC/MCLabel.h +++ b/include/llvm/MC/MCLabel.h @@ -18,11 +18,11 @@ namespace llvm { class raw_ostream; -/// \brief Instances of this class represent a label name in the MC file, +/// Instances of this class represent a label name in the MC file, /// and MCLabel are created and uniqued by the MCContext class. MCLabel /// should only be constructed for valid instances in the object file. class MCLabel { - // \brief The instance number of this Directional Local Label. + // The instance number of this Directional Local Label. unsigned Instance; private: // MCContext creates and uniques these. @@ -34,16 +34,16 @@ public: MCLabel(const MCLabel &) = delete; MCLabel &operator=(const MCLabel &) = delete; - /// \brief Get the current instance of this Directional Local Label. + /// Get the current instance of this Directional Local Label. unsigned getInstance() const { return Instance; } - /// \brief Increment the current instance of this Directional Local Label. + /// Increment the current instance of this Directional Local Label. unsigned incInstance() { return ++Instance; } - /// \brief Print the value to the stream \p OS. + /// Print the value to the stream \p OS. void print(raw_ostream &OS) const; - /// \brief Print the value to stderr. + /// Print the value to stderr. void dump() const; }; diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 594869f74632d7d9f368429e7c76f9bb354520d8..22fbeb72a4ec6c4b3e3b5d03dfe35be3f02e87df 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -26,7 +26,7 @@ namespace llvm { class MachObjectWriter; -class MCMachObjectTargetWriter { +class MCMachObjectTargetWriter : public MCObjectTargetWriter { const unsigned Is64Bit : 1; const uint32_t CPUType; const uint32_t CPUSubtype; @@ -43,6 +43,11 @@ protected: public: virtual ~MCMachObjectTargetWriter(); + virtual Triple::ObjectFormatType getFormat() const { return Triple::MachO; } + static bool classof(const MCObjectTargetWriter *W) { + return W->getFormat() == Triple::MachO; + } + /// \name Lifetime Management /// @{ @@ -116,11 +121,15 @@ class MachObjectWriter : public MCObjectWriter { MachSymbolData *findSymbolData(const MCSymbol &Sym); + void writeWithPadding(StringRef Str, uint64_t Size); + public: MachObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) - : MCObjectWriter(OS, IsLittleEndian), - TargetObjectWriter(std::move(MOTW)) {} + : TargetObjectWriter(std::move(MOTW)), + W(OS, IsLittleEndian ? support::little : support::big) {} + + support::endian::Writer W; const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const; @@ -260,7 +269,7 @@ public: const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; }; /// Construct a new Mach-O writer instance. diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index c99f2521f8f5f31be0a8146f35946a36846e25c7..d50c052a99abffeac08f96ef1f730a54174d0c53 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -92,11 +92,11 @@ protected: // can be enabled by a compiler flag. MCSection *DwarfPubNamesSection; - /// DWARF5 Experimental Debug Info Sections - /// DwarfAccelNamesSection, DwarfAccelObjCSection, - /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - - /// If we use the DWARF accelerated hash tables then we want to emit these - /// sections. + /// Accelerator table sections. DwarfDebugNamesSection is the DWARF v5 + /// accelerator table, while DwarfAccelNamesSection, DwarfAccelObjCSection, + /// DwarfAccelNamespaceSection, DwarfAccelTypesSection are pre-DWARF v5 + /// extensions. + MCSection *DwarfDebugNamesSection; MCSection *DwarfAccelNamesSection; MCSection *DwarfAccelObjCSection; MCSection *DwarfAccelNamespaceSection; @@ -183,6 +183,7 @@ protected: MCSection *ConstTextCoalSection; MCSection *ConstDataSection; MCSection *DataCoalSection; + MCSection *ConstDataCoalSection; MCSection *DataCommonSection; MCSection *DataBSSSection; MCSection *FourByteConstantSection; @@ -254,7 +255,9 @@ public: MCSection *getDwarfRangesSection() const { return DwarfRangesSection; } MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; } - // DWARF5 Experimental Debug Info Sections + MCSection *getDwarfDebugNamesSection() const { + return DwarfDebugNamesSection; + } MCSection *getDwarfAccelNamesSection() const { return DwarfAccelNamesSection; } @@ -326,6 +329,9 @@ public: } const MCSection *getConstDataSection() const { return ConstDataSection; } const MCSection *getDataCoalSection() const { return DataCoalSection; } + const MCSection *getConstDataCoalSection() const { + return ConstDataCoalSection; + } const MCSection *getDataCommonSection() const { return DataCommonSection; } MCSection *getDataBSSSection() const { return DataBSSSection; } const MCSection *getFourByteConstantSection() const { diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 8e9b4ac56320fc791da9774512df88dfebbb3337..498a8af9011243a59e77ef05422ebfd7f7faa406 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -26,7 +26,7 @@ class MCAsmBackend; class raw_ostream; class raw_pwrite_stream; -/// \brief Streaming object file generation interface. +/// Streaming object file generation interface. /// /// This class provides an implementation of the MCStreamer interface which is /// suitable for use with the assembler backend. Specific object file formats @@ -34,9 +34,6 @@ class raw_pwrite_stream; /// to that file format or custom semantics expected by the object writer /// implementation. class MCObjectStreamer : public MCStreamer { - std::unique_ptr ObjectWriter; - std::unique_ptr TAB; - std::unique_ptr Emitter; std::unique_ptr Assembler; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; @@ -51,7 +48,7 @@ class MCObjectStreamer : public MCStreamer { protected: MCObjectStreamer(MCContext &Context, std::unique_ptr TAB, - raw_pwrite_stream &OS, + std::unique_ptr OW, std::unique_ptr Emitter); ~MCObjectStreamer(); @@ -88,11 +85,13 @@ protected: /// will be used as a symbol offset within the fragment. void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); + void addFragmentAtoms(); + public: void visitUsedSymbol(const MCSymbol &Sym) override; MCAssembler &getAssembler() { return *Assembler; } - + MCAssembler *getAssemblerPtr() override; /// \name MCStreamer Interface /// @{ @@ -108,7 +107,7 @@ public: void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool = false) override; - /// \brief Emit an instruction to a special fragment, because this instruction + /// Emit an instruction to a special fragment, because this instruction /// can change its size during relaxation. virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index cd90690fb1863ea1b5f3ae7bccf9a9512cad159a..873b0d56bff94011ae2d9b8d9fbfbb51385b047f 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -12,6 +12,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/raw_ostream.h" @@ -36,22 +37,9 @@ class MCValue; /// points. Once assembly is complete, the object writer is given the /// MCAssembler instance, which contains all the symbol and section data which /// should be emitted as part of writeObject(). -/// -/// The object writer also contains a number of helper methods for writing -/// binary data to the output stream. class MCObjectWriter { - raw_pwrite_stream *OS; - protected: - unsigned IsLittleEndian : 1; - - // Can only create subclasses. - MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian) - : OS(&OS), IsLittleEndian(IsLittleEndian) {} - - unsigned getInitialOffset() { - return OS->tell(); - } + MCObjectWriter() = default; public: MCObjectWriter(const MCObjectWriter &) = delete; @@ -61,11 +49,6 @@ public: /// lifetime management virtual void reset() {} - bool isLittleEndian() const { return IsLittleEndian; } - - raw_pwrite_stream &getStream() { return *OS; } - void setStream(raw_pwrite_stream &NewOS) { OS = &NewOS; } - /// \name High-Level API /// @{ @@ -109,90 +92,22 @@ public: bool InSet, bool IsPCRel) const; - /// Write the object file. + /// Write the object file and returns the number of bytes written. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations /// generated. - virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; + virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; /// @} - /// \name Binary Output - /// @{ - - void write8(uint8_t Value) { *OS << char(Value); } - - void writeLE16(uint16_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void writeLE32(uint32_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void writeLE64(uint64_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void writeBE16(uint16_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void writeBE32(uint32_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void writeBE64(uint64_t Value) { - support::endian::Writer(*OS).write(Value); - } - - void write16(uint16_t Value) { - if (IsLittleEndian) - writeLE16(Value); - else - writeBE16(Value); - } - - void write32(uint32_t Value) { - if (IsLittleEndian) - writeLE32(Value); - else - writeBE32(Value); - } - - void write64(uint64_t Value) { - if (IsLittleEndian) - writeLE64(Value); - else - writeBE64(Value); - } - - void WriteZeros(unsigned N) { - const char Zeros[16] = {0}; - - for (unsigned i = 0, e = N / 16; i != e; ++i) - *OS << StringRef(Zeros, 16); - - *OS << StringRef(Zeros, N % 16); - } - - void writeBytes(const SmallVectorImpl &ByteVec, - unsigned ZeroFillSize = 0) { - writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); - } - - void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) { - // TODO: this version may need to go away once all fragment contents are - // converted to SmallVector - assert( - (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && - "data size greater than fill size, unexpected large write will occur"); - *OS << Str; - if (ZeroFillSize) - WriteZeros(ZeroFillSize - Str.size()); - } +}; - /// @} +/// Base class for classes that define behaviour that is specific to both the +/// target and the object format. +class MCObjectTargetWriter { +public: + virtual ~MCObjectTargetWriter() = default; + virtual Triple::ObjectFormatType getFormat() const = 0; }; } // end namespace llvm diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 0f79c4777ea93d548533c5e7fb9b0c6747861a43..28f0432c8158a8a0ebefd87dd0e729616e4ec86d 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -91,7 +91,7 @@ private: IdKind Kind; }; -/// \brief Generic Sema callback for assembly parser. +/// Generic Sema callback for assembly parser. class MCAsmParserSemaCallback { public: virtual ~MCAsmParserSemaCallback(); @@ -105,7 +105,7 @@ public: unsigned &Offset) = 0; }; -/// \brief Generic assembler parser interface, for use by target specific +/// Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { public: @@ -153,7 +153,7 @@ public: virtual MCContext &getContext() = 0; - /// \brief Return the output streamer for the assembler. + /// Return the output streamer for the assembler. virtual MCStreamer &getStreamer() = 0; MCTargetAsmParser &getTargetParser() const { return *TargetParser; } @@ -168,13 +168,13 @@ public: void setEnablePrintSchedInfo(bool Value) { EnablePrintSchedInfo = Value; } bool shouldPrintSchedInfo() { return EnablePrintSchedInfo; } - /// \brief Run the parser on the input source buffer. + /// Run the parser on the input source buffer. virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; virtual void setParsingInlineAsm(bool V) = 0; virtual bool isParsingInlineAsm() = 0; - /// \brief Parse MS-style inline assembly. + /// Parse MS-style inline assembly. virtual bool parseMSInlineAsm( void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl> &OpDecls, @@ -182,22 +182,22 @@ public: SmallVectorImpl &Clobbers, const MCInstrInfo *MII, const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0; - /// \brief Emit a note at the location \p L, with the message \p Msg. + /// Emit a note at the location \p L, with the message \p Msg. virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0; - /// \brief Emit a warning at the location \p L, with the message \p Msg. + /// Emit a warning at the location \p L, with the message \p Msg. /// /// \return The return value is true, if warnings are fatal. virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0; - /// \brief Return an error at the location \p L, with the message \p Msg. This + /// Return an error at the location \p L, with the message \p Msg. This /// may be modified before being emitted. /// /// \return The return value is always true, as an idiomatic convenience to /// clients. bool Error(SMLoc L, const Twine &Msg, SMRange Range = None); - /// \brief Emit an error at the location \p L, with the message \p Msg. + /// Emit an error at the location \p L, with the message \p Msg. /// /// \return The return value is always true, as an idiomatic convenience to /// clients. @@ -216,19 +216,19 @@ public: bool addErrorSuffix(const Twine &Suffix); - /// \brief Get the next AsmToken in the stream, possibly handling file + /// Get the next AsmToken in the stream, possibly handling file /// inclusion first. virtual const AsmToken &Lex() = 0; - /// \brief Get the current AsmToken from the stream. + /// Get the current AsmToken from the stream. const AsmToken &getTok() const; - /// \brief Report an error at the current lexer location. + /// Report an error at the current lexer location. bool TokError(const Twine &Msg, SMRange Range = None); bool parseTokenLoc(SMLoc &Loc); bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token"); - /// \brief Attempt to parse and consume token, returning true on + /// Attempt to parse and consume token, returning true on /// success. bool parseOptionalToken(AsmToken::TokenKind T); @@ -241,23 +241,23 @@ public: bool check(bool P, const Twine &Msg); bool check(bool P, SMLoc Loc, const Twine &Msg); - /// \brief Parse an identifier or string (as a quoted identifier) and set \p + /// Parse an identifier or string (as a quoted identifier) and set \p /// Res to the identifier contents. virtual bool parseIdentifier(StringRef &Res) = 0; - /// \brief Parse up to the end of statement and return the contents from the + /// Parse up to the end of statement and return the contents from the /// current token until the end of the statement; the current token on exit /// will be either the EndOfStatement or EOF. virtual StringRef parseStringToEndOfStatement() = 0; - /// \brief Parse the current token as a string which may include escaped + /// Parse the current token as a string which may include escaped /// characters and return the string contents. virtual bool parseEscapedString(std::string &Data) = 0; - /// \brief Skip to the end of the current statement, for error recovery. + /// Skip to the end of the current statement, for error recovery. virtual void eatToEndOfStatement() = 0; - /// \brief Parse an arbitrary expression. + /// Parse an arbitrary expression. /// /// \param Res - The value of the expression. The result is undefined /// on error. @@ -265,14 +265,14 @@ public: virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; bool parseExpression(const MCExpr *&Res); - /// \brief Parse a primary expression. + /// Parse a primary expression. /// /// \param Res - The value of the expression. The result is undefined /// on error. /// \return - False on success. virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0; - /// \brief Parse an arbitrary expression, assuming that an initial '(' has + /// Parse an arbitrary expression, assuming that an initial '(' has /// already been consumed. /// /// \param Res - The value of the expression. The result is undefined @@ -280,19 +280,19 @@ public: /// \return - False on success. virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; - /// \brief Parse an expression which must evaluate to an absolute value. + /// Parse an expression which must evaluate to an absolute value. /// /// \param Res - The value of the absolute expression. The result is undefined /// on error. /// \return - False on success. virtual bool parseAbsoluteExpression(int64_t &Res) = 0; - /// \brief Ensure that we have a valid section set in the streamer. Otherwise, + /// Ensure that we have a valid section set in the streamer. Otherwise, /// report an error and switch to .text. /// \return - False on success. virtual bool checkForValidSection() = 0; - /// \brief Parse an arbitrary expression of a specified parenthesis depth, + /// Parse an arbitrary expression of a specified parenthesis depth, /// assuming that the initial '(' characters have already been consumed. /// /// \param ParenDepth - Specifies how many trailing expressions outside the @@ -304,7 +304,7 @@ public: SMLoc &EndLoc) = 0; }; -/// \brief Create an MCAsmParser instance. +/// Create an MCAsmParser instance. MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB = 0); diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index ffb8d7a4a26a2022bcab6a632f61e04071644688..1a132bceddc57c4def1217e3ea2cafbb30ddecf1 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -20,7 +20,7 @@ namespace llvm { class Twine; -/// \brief Generic interface for extending the MCAsmParser, +/// Generic interface for extending the MCAsmParser, /// which is implemented by target and object file assembly parser /// implementations. class MCAsmParserExtension { @@ -45,7 +45,7 @@ public: MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete; virtual ~MCAsmParserExtension(); - /// \brief Initialize the extension for parsing using the given \p Parser. + /// Initialize the extension for parsing using the given \p Parser. /// The extension should use the AsmParser interfaces to register its /// parsing routines. virtual void Initialize(MCAsmParser &Parser); diff --git a/include/llvm/MC/MCParser/MCTargetAsmParser.h b/include/llvm/MC/MCParser/MCTargetAsmParser.h index d628794b32e232fae4c673c07c70b9c503a4289a..257a2b154d75c0f085070a9e749e72f19793c851 100644 --- a/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -133,6 +133,53 @@ enum OperandMatchResultTy { MatchOperand_ParseFail // operand matched but had errors }; +enum class DiagnosticPredicateTy { + Match, + NearMatch, + NoMatch, +}; + +// When an operand is parsed, the assembler will try to iterate through a set of +// possible operand classes that the operand might match and call the +// corresponding PredicateMethod to determine that. +// +// If there are two AsmOperands that would give a specific diagnostic if there +// is no match, there is currently no mechanism to distinguish which operand is +// a closer match. The DiagnosticPredicate distinguishes between 'completely +// no match' and 'near match', so the assembler can decide whether to give a +// specific diagnostic, or use 'InvalidOperand' and continue to find a +// 'better matching' diagnostic. +// +// For example: +// opcode opnd0, onpd1, opnd2 +// +// where: +// opnd2 could be an 'immediate of range [-8, 7]' +// opnd2 could be a 'register + shift/extend'. +// +// If opnd2 is a valid register, but with a wrong shift/extend suffix, it makes +// little sense to give a diagnostic that the operand should be an immediate +// in range [-8, 7]. +// +// This is a light-weight alternative to the 'NearMissInfo' approach +// below which collects *all* possible diagnostics. This alternative +// is optional and fully backward compatible with existing +// PredicateMethods that return a 'bool' (match or no match). +struct DiagnosticPredicate { + DiagnosticPredicateTy Type; + + explicit DiagnosticPredicate(bool Match) + : Type(Match ? DiagnosticPredicateTy::Match + : DiagnosticPredicateTy::NearMatch) {} + DiagnosticPredicate(DiagnosticPredicateTy T) : Type(T) {} + DiagnosticPredicate(const DiagnosticPredicate &) = default; + + operator bool() const { return Type == DiagnosticPredicateTy::Match; } + bool isMatch() const { return Type == DiagnosticPredicateTy::Match; } + bool isNearMatch() const { return Type == DiagnosticPredicateTy::NearMatch; } + bool isNoMatch() const { return Type == DiagnosticPredicateTy::NoMatch; } +}; + // When matching of an assembly instruction fails, there may be multiple // encodings that are close to being a match. It's often ambiguous which one // the programmer intended to use, so we want to report an error which mentions diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index c57c9ef709dad985f71820bc1c880a95ba395b33..6edfc30b0aa6d2188f9b96ed74086952061c71fe 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -240,7 +240,7 @@ public: friend class MCRegUnitMaskIterator; friend class MCRegUnitRootIterator; - /// \brief Initialize MCRegisterInfo, called by TableGen + /// Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, unsigned PC, @@ -283,7 +283,7 @@ public: Dwarf2LRegsSize = 0; } - /// \brief Used to initialize LLVM register to Dwarf + /// Used to initialize LLVM register to Dwarf /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -297,7 +297,7 @@ public: } } - /// \brief Used to initialize Dwarf register to LLVM + /// Used to initialize Dwarf register to LLVM /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -324,7 +324,7 @@ public: L2CVRegs[LLVMReg] = CVReg; } - /// \brief This method should return the register where the return + /// This method should return the register where the return /// address can be found. unsigned getRARegister() const { return RAReg; @@ -341,86 +341,86 @@ public: return Desc[RegNo]; } - /// \brief Provide a get method, equivalent to [], but more useful with a + /// Provide a get method, equivalent to [], but more useful with a /// pointer to this object. const MCRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } - /// \brief Returns the physical register number of sub-register "Index" + /// Returns the physical register number of sub-register "Index" /// for physical register RegNo. Return zero if the sub-register does not /// exist. unsigned getSubReg(unsigned Reg, unsigned Idx) const; - /// \brief Return a super-register of the specified register + /// Return a super-register of the specified register /// Reg so its sub-register of index SubIdx is Reg. unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const; - /// \brief For a given register pair, return the sub-register index + /// For a given register pair, return the sub-register index /// if the second register is a sub-register of the first. Return zero /// otherwise. unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; - /// \brief Get the size of the bit range covered by a sub-register index. + /// Get the size of the bit range covered by a sub-register index. /// If the index isn't continuous, return the sum of the sizes of its parts. /// If the index is used to access subregisters of different sizes, return -1. unsigned getSubRegIdxSize(unsigned Idx) const; - /// \brief Get the offset of the bit range covered by a sub-register index. + /// Get the offset of the bit range covered by a sub-register index. /// If an Offset doesn't make sense (the index isn't continuous, or is used to /// access sub-registers at different offsets), return -1. unsigned getSubRegIdxOffset(unsigned Idx) const; - /// \brief Return the human-readable symbolic target-specific name for the + /// Return the human-readable symbolic target-specific name for the /// specified physical register. const char *getName(unsigned RegNo) const { return RegStrings + get(RegNo).Name; } - /// \brief Return the number of registers this target has (useful for + /// Return the number of registers this target has (useful for /// sizing arrays holding per register information) unsigned getNumRegs() const { return NumRegs; } - /// \brief Return the number of sub-register indices + /// Return the number of sub-register indices /// understood by the target. Index 0 is reserved for the no-op sub-register, /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. unsigned getNumSubRegIndices() const { return NumSubRegIndices; } - /// \brief Return the number of (native) register units in the + /// Return the number of (native) register units in the /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They /// can be accessed through MCRegUnitIterator defined below. unsigned getNumRegUnits() const { return NumRegUnits; } - /// \brief Map a target register to an equivalent dwarf register + /// Map a target register to an equivalent dwarf register /// number. Returns -1 if there is no equivalent value. The second /// parameter allows targets to use different numberings for EH info and /// debugging info. int getDwarfRegNum(unsigned RegNum, bool isEH) const; - /// \brief Map a dwarf register back to a target register. + /// Map a dwarf register back to a target register. int getLLVMRegNum(unsigned RegNum, bool isEH) const; - /// \brief Map a DWARF EH register back to a target register (same as + /// Map a DWARF EH register back to a target register (same as /// getLLVMRegNum(RegNum, true)) but return -1 if there is no mapping, /// rather than asserting that there must be one. int getLLVMRegNumFromEH(unsigned RegNum) const; - /// \brief Map a target EH register number to an equivalent DWARF register + /// Map a target EH register number to an equivalent DWARF register /// number. int getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const; - /// \brief Map a target register to an equivalent SEH register + /// Map a target register to an equivalent SEH register /// number. Returns LLVM register number if there is no equivalent value. int getSEHRegNum(unsigned RegNum) const; - /// \brief Map a target register to an equivalent CodeView register + /// Map a target register to an equivalent CodeView register /// number. int getCodeViewRegNum(unsigned RegNum) const; @@ -434,7 +434,7 @@ public: return (unsigned)(regclass_end()-regclass_begin()); } - /// \brief Returns the register class associated with the enumeration + /// Returns the register class associated with the enumeration /// value. See class MCOperandInfo. const MCRegisterClass& getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); @@ -445,33 +445,33 @@ public: return RegClassStrings + Class->NameIdx; } - /// \brief Returns the encoding for RegNo + /// Returns the encoding for RegNo uint16_t getEncodingValue(unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to get encoding for invalid register number!"); return RegEncodingTable[RegNo]; } - /// \brief Returns true if RegB is a sub-register of RegA. + /// Returns true if RegB is a sub-register of RegA. bool isSubRegister(unsigned RegA, unsigned RegB) const { return isSuperRegister(RegB, RegA); } - /// \brief Returns true if RegB is a super-register of RegA. + /// Returns true if RegB is a super-register of RegA. bool isSuperRegister(unsigned RegA, unsigned RegB) const; - /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA. + /// Returns true if RegB is a sub-register of RegA or if RegB == RegA. bool isSubRegisterEq(unsigned RegA, unsigned RegB) const { return isSuperRegisterEq(RegB, RegA); } - /// \brief Returns true if RegB is a super-register of RegA or if + /// Returns true if RegB is a super-register of RegA or if /// RegB == RegA. bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const { return RegA == RegB || isSuperRegister(RegA, RegB); } - /// \brief Returns true if RegB is a super-register or sub-register of RegA + /// Returns true if RegB is a super-register or sub-register of RegA /// or if RegB == RegA. bool isSuperOrSubRegisterEq(unsigned RegA, unsigned RegB) const { return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB); @@ -651,17 +651,17 @@ public: Reg1 = MCRI->RegUnitRoots[RegUnit][1]; } - /// \brief Dereference to get the current root register. + /// Dereference to get the current root register. unsigned operator*() const { return Reg0; } - /// \brief Check if the iterator is at the end of the list. + /// Check if the iterator is at the end of the list. bool isValid() const { return Reg0; } - /// \brief Preincrement to move to the next root register. + /// Preincrement to move to the next root register. void operator++() { assert(isValid() && "Cannot move off the end of the list."); Reg0 = Reg1; diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 62f8efd8dfb06f2f679f4622b707cf93534d7e80..5aa51d416fe1d3d0a2ec22db6ddabdbf90339e3c 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -16,6 +16,7 @@ #define LLVM_MC_MCSCHEDULE_H #include "llvm/ADT/Optional.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/DataTypes.h" #include @@ -23,6 +24,9 @@ namespace llvm { struct InstrItinerary; class MCSubtargetInfo; +class MCInstrInfo; +class MCInst; +class InstrItineraryData; /// Define a kind of processor resource that will be modeled by the scheduler. struct MCProcResourceDesc { @@ -128,6 +132,64 @@ struct MCSchedClassDesc { } }; +/// Specify the cost of a register definition in terms of number of physical +/// register allocated at register renaming stage. For example, AMD Jaguar. +/// natively supports 128-bit data types, and operations on 256-bit registers +/// (i.e. YMM registers) are internally split into two COPs (complex operations) +/// and each COP updates a physical register. Basically, on Jaguar, a YMM +/// register write effectively consumes two physical registers. That means, +/// the cost of a YMM write in the BtVer2 model is 2. +struct MCRegisterCostEntry { + unsigned RegisterClassID; + unsigned Cost; +}; + +/// A register file descriptor. +/// +/// This struct allows to describe processor register files. In particular, it +/// helps describing the size of the register file, as well as the cost of +/// allocating a register file at register renaming stage. +/// FIXME: this struct can be extended to provide information about the number +/// of read/write ports to the register file. A value of zero for field +/// 'NumPhysRegs' means: this register file has an unbounded number of physical +/// registers. +struct MCRegisterFileDesc { + const char *Name; + uint16_t NumPhysRegs; + uint16_t NumRegisterCostEntries; + // Index of the first cost entry in MCExtraProcessorInfo::RegisterCostTable. + uint16_t RegisterCostEntryIdx; +}; + +/// Provide extra details about the machine processor. +/// +/// This is a collection of "optional" processor information that is not +/// normally used by the LLVM machine schedulers, but that can be consumed by +/// external tools like llvm-mca to improve the quality of the peformance +/// analysis. +struct MCExtraProcessorInfo { + // Actual size of the reorder buffer in hardware. + unsigned ReorderBufferSize; + // Number of instructions retired per cycle. + unsigned MaxRetirePerCycle; + const MCRegisterFileDesc *RegisterFiles; + unsigned NumRegisterFiles; + const MCRegisterCostEntry *RegisterCostTable; + unsigned NumRegisterCostEntries; + + struct PfmCountersInfo { + // An optional name of a performance counter that can be used to measure + // cycles. + const char *CycleCounter; + + // For each MCProcResourceDesc defined by the processor, an optional list of + // names of performance counters that can be used to measure the resource + // utilization. + const char **IssueCounters; + }; + PfmCountersInfo PfmCounters; +}; + /// Machine model for scheduling, bundling, and heuristics. /// /// The machine model directly provides basic information about the @@ -138,9 +200,62 @@ struct MCSchedClassDesc { /// provides a detailed reservation table describing each cycle of instruction /// execution. Subtargets may define any or all of the above categories of data /// depending on the type of CPU and selected scheduler. +/// +/// The machine independent properties defined here are used by the scheduler as +/// an abstract machine model. A real micro-architecture has a number of +/// buffers, queues, and stages. Declaring that a given machine-independent +/// abstract property corresponds to a specific physical property across all +/// subtargets can't be done. Nonetheless, the abstract model is +/// useful. Futhermore, subtargets typically extend this model with processor +/// specific resources to model any hardware features that can be exploited by +/// sceduling heuristics and aren't sufficiently represented in the abstract. +/// +/// The abstract pipeline is built around the notion of an "issue point". This +/// is merely a reference point for counting machine cycles. The physical +/// machine will have pipeline stages that delay execution. The scheduler does +/// not model those delays because they are irrelevant as long as they are +/// consistent. Inaccuracies arise when instructions have different execution +/// delays relative to each other, in addition to their intrinsic latency. Those +/// special cases can be handled by TableGen constructs such as, ReadAdvance, +/// which reduces latency when reading data, and ResourceCycles, which consumes +/// a processor resource when writing data for a number of abstract +/// cycles. +/// +/// TODO: One tool currently missing is the ability to add a delay to +/// ResourceCycles. That would be easy to add and would likely cover all cases +/// currently handled by the legacy itinerary tables. +/// +/// A note on out-of-order execution and, more generally, instruction +/// buffers. Part of the CPU pipeline is always in-order. The issue point, which +/// is the point of reference for counting cycles, only makes sense as an +/// in-order part of the pipeline. Other parts of the pipeline are sometimes +/// falling behind and sometimes catching up. It's only interesting to model +/// those other, decoupled parts of the pipeline if they may be predictably +/// resource constrained in a way that the scheduler can exploit. +/// +/// The LLVM machine model distinguishes between in-order constraints and +/// out-of-order constraints so that the target's scheduling strategy can apply +/// appropriate heuristics. For a well-balanced CPU pipeline, out-of-order +/// resources would not typically be treated as a hard scheduling +/// constraint. For example, in the GenericScheduler, a delay caused by limited +/// out-of-order resources is not directly reflected in the number of cycles +/// that the scheduler sees between issuing an instruction and its dependent +/// instructions. In other words, out-of-order resources don't directly increase +/// the latency between pairs of instructions. However, they can still be used +/// to detect potential bottlenecks across a sequence of instructions and bias +/// the scheduling heuristics appropriately. struct MCSchedModel { // IssueWidth is the maximum number of instructions that may be scheduled in - // the same per-cycle group. + // the same per-cycle group. This is meant to be a hard in-order constraint + // (a.k.a. "hazard"). In the GenericScheduler strategy, no more than + // IssueWidth micro-ops can ever be scheduled in a particular cycle. + // + // In practice, IssueWidth is useful to model any bottleneck between the + // decoder (after micro-op expansion) and the out-of-order reservation + // stations or the decoder bandwidth itself. If the total number of + // reservation stations is also a bottleneck, or if any other pipeline stage + // has a bandwidth limitation, then that can be naturally modeled by adding an + // out-of-order processor resource. unsigned IssueWidth; static const unsigned DefaultIssueWidth = 1; @@ -198,11 +313,21 @@ struct MCSchedModel { friend class InstrItineraryData; const InstrItinerary *InstrItineraries; + const MCExtraProcessorInfo *ExtraProcessorInfo; + + bool hasExtraProcessorInfo() const { return ExtraProcessorInfo; } + unsigned getProcessorID() const { return ProcID; } /// Does this machine model include instruction-level scheduling. bool hasInstrSchedModel() const { return SchedClassTable; } + const MCExtraProcessorInfo &getExtraProcessorInfo() const { + assert(hasExtraProcessorInfo() && + "No extra information available for this model"); + return *ExtraProcessorInfo; + } + /// Return true if this machine model data for all instructions with a /// scheduling class (itinerary class or SchedRW list). bool isComplete() const { return CompleteModel; } @@ -232,16 +357,27 @@ struct MCSchedModel { static int computeInstrLatency(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc); - /// Returns the reciprocal throughput information from a MCSchedClassDesc. + int computeInstrLatency(const MCSubtargetInfo &STI, unsigned SClass) const; + int computeInstrLatency(const MCSubtargetInfo &STI, const MCInstrInfo &MCII, + const MCInst &Inst) const; + + // Returns the reciprocal throughput information from a MCSchedClassDesc. static Optional getReciprocalThroughput(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc); + static Optional + getReciprocalThroughput(unsigned SchedClass, const InstrItineraryData &IID); + + Optional + getReciprocalThroughput(const MCSubtargetInfo &STI, const MCInstrInfo &MCII, + const MCInst &Inst) const; + /// Returns the default initialized model. static const MCSchedModel &GetDefaultSchedModel() { return Default; } static const MCSchedModel Default; }; -} // End llvm namespace +} // namespace llvm #endif diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 2771b1e67eaba7f9d49c3566349401432fd9c9b7..ba5c60d3ba585fec09366b8498c799b4fa54c299 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -40,7 +40,7 @@ class MCSection { public: enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm }; - /// \brief Express the state of bundle locked groups while emitting code. + /// Express the state of bundle locked groups while emitting code. enum BundleLockStateType { NotBundleLocked, BundleLocked, @@ -65,13 +65,13 @@ private: /// The index of this section in the layout order. unsigned LayoutOrder; - /// \brief Keeping track of bundle-locked state. + /// Keeping track of bundle-locked state. BundleLockStateType BundleLockState = NotBundleLocked; - /// \brief Current nesting depth of bundle_lock directives. + /// Current nesting depth of bundle_lock directives. unsigned BundleLockNestingDepth = 0; - /// \brief We've seen a bundle_lock directive but not its first instruction + /// We've seen a bundle_lock directive but not its first instruction /// yet. bool BundleGroupBeforeFirstInst : 1; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 582a836023b570e6d4bf275332c4f2de37e2d4b1..db4f885a7d9c1c954548e8398a9eb2bf84429f7e 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -170,7 +170,7 @@ private: std::unique_ptr ConstantPools; }; -/// \brief Streaming machine code generation interface. +/// Streaming machine code generation interface. /// /// This interface is intended to provide a programatic interface that is very /// similar to the level that an assembler .s file provides. It has callbacks @@ -197,11 +197,11 @@ class MCStreamer { /// closed. Otherwise, issue an error and return null. WinEH::FrameInfo *EnsureValidWinFrameInfo(SMLoc Loc); - /// \brief Tracks an index to represent the order a symbol was emitted in. + /// Tracks an index to represent the order a symbol was emitted in. /// Zero means we did not emit that symbol. DenseMap SymbolOrdering; - /// \brief This is stack of current and previous section values saved by + /// This is stack of current and previous section values saved by /// PushSection. SmallVector, 4> SectionStack; @@ -211,6 +211,8 @@ class MCStreamer { /// requires. unsigned NextWinCFIID = 0; + bool UseAssemblerInfoForParsing; + protected: MCStreamer(MCContext &Ctx); @@ -247,6 +249,11 @@ public: MCContext &getContext() const { return Context; } + virtual MCAssembler *getAssemblerPtr() { return nullptr; } + + void setUseAssemblerInfoForParsing(bool v) { UseAssemblerInfoForParsing = v; } + bool getUseAssemblerInfoForParsing() { return UseAssemblerInfoForParsing; } + MCTargetStreamer *getTargetStreamer() { return TargetStreamer.get(); } @@ -268,19 +275,19 @@ public: /// \name Assembly File Formatting. /// @{ - /// \brief Return true if this streamer supports verbose assembly and if it is + /// Return true if this streamer supports verbose assembly and if it is /// enabled. virtual bool isVerboseAsm() const { return false; } - /// \brief Return true if this asm streamer supports emitting unformatted text + /// Return true if this asm streamer supports emitting unformatted text /// to the .s file with EmitRawText. virtual bool hasRawTextSupport() const { return false; } - /// \brief Is the integrated assembler required for this streamer to function + /// Is the integrated assembler required for this streamer to function /// correctly? virtual bool isIntegratedAssemblerRequired() const { return false; } - /// \brief Add a textual comment. + /// Add a textual comment. /// /// Typically for comments that can be emitted to the generated .s /// file if applicable as a QoI issue to make the output of the compiler @@ -295,22 +302,22 @@ public: /// with a false value. virtual void AddComment(const Twine &T, bool EOL = true) {} - /// \brief Return a raw_ostream that comments can be written to. Unlike + /// Return a raw_ostream that comments can be written to. Unlike /// AddComment, you are required to terminate comments with \n if you use this /// method. virtual raw_ostream &GetCommentOS(); - /// \brief Print T and prefix it with the comment string (normally #) and + /// Print T and prefix it with the comment string (normally #) and /// optionally a tab. This prints the comment immediately, not at the end of /// the current line. It is basically a safe version of EmitRawText: since it /// only prints comments, the object streamer ignores it instead of asserting. virtual void emitRawComment(const Twine &T, bool TabPrefix = true); - /// \brief Add explicit comment T. T is required to be a valid + /// Add explicit comment T. T is required to be a valid /// comment in the output and does not need to be escaped. virtual void addExplicitComment(const Twine &T); - /// \brief Emit added explicit comments. + /// Emit added explicit comments. virtual void emitExplicitComments(); /// AddBlankLine - Emit a blank line to a .s file to pretty it up. @@ -321,7 +328,7 @@ public: /// \name Symbol & Section Management /// @{ - /// \brief Return the current section that the streamer is emitting code to. + /// Return the current section that the streamer is emitting code to. MCSectionSubPair getCurrentSection() const { if (!SectionStack.empty()) return SectionStack.back().first; @@ -329,32 +336,32 @@ public: } MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; } - /// \brief Return the previous section that the streamer is emitting code to. + /// Return the previous section that the streamer is emitting code to. MCSectionSubPair getPreviousSection() const { if (!SectionStack.empty()) return SectionStack.back().second; return MCSectionSubPair(); } - /// \brief Returns an index to represent the order a symbol was emitted in. + /// Returns an index to represent the order a symbol was emitted in. /// (zero if we did not emit that symbol) unsigned GetSymbolOrder(const MCSymbol *Sym) const { return SymbolOrdering.lookup(Sym); } - /// \brief Update streamer for a new active section. + /// Update streamer for a new active section. /// /// This is called by PopSection and SwitchSection, if the current /// section changes. virtual void ChangeSection(MCSection *, const MCExpr *); - /// \brief Save the current and previous section on the section stack. + /// Save the current and previous section on the section stack. void PushSection() { SectionStack.push_back( std::make_pair(getCurrentSection(), getPreviousSection())); } - /// \brief Restore the current and previous section from the section stack. + /// Restore the current and previous section from the section stack. /// Calls ChangeSection as needed. /// /// Returns false if the stack was empty. @@ -388,7 +395,7 @@ public: virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection = nullptr); - /// \brief Set the current section where code is being emitted to \p Section. + /// Set the current section where code is being emitted to \p Section. /// This is required to update CurSection. This version does not call /// ChangeSection. void SwitchSectionNoChange(MCSection *Section, @@ -400,18 +407,18 @@ public: SectionStack.back().first = MCSectionSubPair(Section, Subsection); } - /// \brief Create the default sections and set the initial one. + /// Create the default sections and set the initial one. virtual void InitSections(bool NoExecStack); MCSymbol *endSection(MCSection *Section); - /// \brief Sets the symbol's section. + /// Sets the symbol's section. /// /// Each emitted symbol will be tracked in the ordering table, /// so we can sort on them later. void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment); - /// \brief Emit a label for \p Symbol into the current section. + /// Emit a label for \p Symbol into the current section. /// /// This corresponds to an assembler statement such as: /// foo: @@ -425,17 +432,17 @@ public: virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); - /// \brief Note in the output the specified \p Flag. + /// Note in the output the specified \p Flag. virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); - /// \brief Emit the given list \p Options of strings as linker + /// Emit the given list \p Options of strings as linker /// options into the output. virtual void EmitLinkerOptions(ArrayRef Kind) {} - /// \brief Note in the output the specified region \p Kind. + /// Note in the output the specified region \p Kind. virtual void EmitDataRegion(MCDataRegionType Kind) {} - /// \brief Specify the Mach-O minimum deployment target version. + /// Specify the Mach-O minimum deployment target version. virtual void EmitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update) {} @@ -446,11 +453,11 @@ public: void EmitVersionForTarget(const Triple &Target); - /// \brief Note in the output that the specified \p Func is a Thumb mode + /// Note in the output that the specified \p Func is a Thumb mode /// function (ARM target only). virtual void EmitThumbFunc(MCSymbol *Func); - /// \brief Emit an assignment of \p Value to \p Symbol. + /// Emit an assignment of \p Value to \p Symbol. /// /// This corresponds to an assembler statement such as: /// symbol = value @@ -463,7 +470,7 @@ public: /// \param Value - The value for the symbol. virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); - /// \brief Emit an weak reference from \p Alias to \p Symbol. + /// Emit an weak reference from \p Alias to \p Symbol. /// /// This corresponds to an assembler statement such as: /// .weakref alias, symbol @@ -472,56 +479,56 @@ public: /// \param Symbol - The symbol being aliased. virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - /// \brief Add the given \p Attribute to \p Symbol. + /// Add the given \p Attribute to \p Symbol. virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) = 0; - /// \brief Set the \p DescValue for the \p Symbol. + /// Set the \p DescValue for the \p Symbol. /// /// \param Symbol - The symbol to have its n_desc field set. /// \param DescValue - The value to set into the n_desc field. virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); - /// \brief Start emitting COFF symbol definition + /// Start emitting COFF symbol definition /// /// \param Symbol - The symbol to have its External & Type fields set. virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); - /// \brief Emit the storage class of the symbol. + /// Emit the storage class of the symbol. /// /// \param StorageClass - The storage class the symbol should have. virtual void EmitCOFFSymbolStorageClass(int StorageClass); - /// \brief Emit the type of the symbol. + /// Emit the type of the symbol. /// /// \param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h) virtual void EmitCOFFSymbolType(int Type); - /// \brief Marks the end of the symbol definition. + /// Marks the end of the symbol definition. virtual void EndCOFFSymbolDef(); virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol); - /// \brief Emits the symbol table index of a Symbol into the current section. + /// Emits the symbol table index of a Symbol into the current section. virtual void EmitCOFFSymbolIndex(MCSymbol const *Symbol); - /// \brief Emits a COFF section index. + /// Emits a COFF section index. /// /// \param Symbol - Symbol the section number relocation should point to. virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol); - /// \brief Emits a COFF section relative relocation. + /// Emits a COFF section relative relocation. /// /// \param Symbol - Symbol the section relative relocation should point to. virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset); - /// \brief Emit an ELF .size directive. + /// Emit an ELF .size directive. /// /// This corresponds to an assembler statement such as: /// .size symbol, expression virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value); - /// \brief Emit an ELF .symver directive. + /// Emit an ELF .symver directive. /// /// This corresponds to an assembler statement such as: /// .symver _start, foo@@SOME_VERSION @@ -530,11 +537,11 @@ public: virtual void emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee); - /// \brief Emit a Linker Optimization Hint (LOH) directive. + /// Emit a Linker Optimization Hint (LOH) directive. /// \param Args - Arguments of the LOH. virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {} - /// \brief Emit a common symbol. + /// Emit a common symbol. /// /// \param Symbol - The common symbol to emit. /// \param Size - The size of the common symbol. @@ -543,7 +550,7 @@ public: virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) = 0; - /// \brief Emit a local common (.lcomm) symbol. + /// Emit a local common (.lcomm) symbol. /// /// \param Symbol - The common symbol to emit. /// \param Size - The size of the common symbol. @@ -551,7 +558,7 @@ public: virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); - /// \brief Emit the zerofill section and an optional symbol. + /// Emit the zerofill section and an optional symbol. /// /// \param Section - The zerofill section to create and or to put the symbol /// \param Symbol - The zerofill symbol to emit, if non-NULL. @@ -561,7 +568,7 @@ public: virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) = 0; - /// \brief Emit a thread local bss (.tbss) symbol. + /// Emit a thread local bss (.tbss) symbol. /// /// \param Section - The thread local common section. /// \param Symbol - The thread local common symbol to emit. @@ -575,7 +582,7 @@ public: /// \name Generating Data /// @{ - /// \brief Emit the bytes in \p Data into the output. + /// Emit the bytes in \p Data into the output. /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. @@ -585,7 +592,7 @@ public: /// method uses .byte directives instead of .ascii or .asciz for readability. virtual void EmitBinaryData(StringRef Data); - /// \brief Emit the expression \p Value into the output as a native + /// Emit the expression \p Value into the output as a native /// integer of the given \p Size bytes. /// /// This is used to implement assembler directives such as .word, .quad, @@ -600,7 +607,7 @@ public: void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc()); - /// \brief Special case of EmitValue that avoids the client having + /// Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size); @@ -608,66 +615,66 @@ public: virtual void EmitSLEB128Value(const MCExpr *Value); - /// \brief Special case of EmitULEB128Value that avoids the client having to + /// Special case of EmitULEB128Value that avoids the client having to /// pass in a MCExpr for constant integers. void EmitULEB128IntValue(uint64_t Value); - /// \brief Special case of EmitSLEB128Value that avoids the client having to + /// Special case of EmitSLEB128Value that avoids the client having to /// pass in a MCExpr for constant integers. void EmitSLEB128IntValue(int64_t Value); - /// \brief Special case of EmitValue that avoids the client having to pass in + /// Special case of EmitValue that avoids the client having to pass in /// a MCExpr for MCSymbols. void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative = false); - /// \brief Emit the expression \p Value into the output as a dtprel + /// Emit the expression \p Value into the output as a dtprel /// (64-bit DTP relative) value. /// /// This is used to implement assembler directives such as .dtpreldword on /// targets that support them. virtual void EmitDTPRel64Value(const MCExpr *Value); - /// \brief Emit the expression \p Value into the output as a dtprel + /// Emit the expression \p Value into the output as a dtprel /// (32-bit DTP relative) value. /// /// This is used to implement assembler directives such as .dtprelword on /// targets that support them. virtual void EmitDTPRel32Value(const MCExpr *Value); - /// \brief Emit the expression \p Value into the output as a tprel + /// Emit the expression \p Value into the output as a tprel /// (64-bit TP relative) value. /// /// This is used to implement assembler directives such as .tpreldword on /// targets that support them. virtual void EmitTPRel64Value(const MCExpr *Value); - /// \brief Emit the expression \p Value into the output as a tprel + /// Emit the expression \p Value into the output as a tprel /// (32-bit TP relative) value. /// /// This is used to implement assembler directives such as .tprelword on /// targets that support them. virtual void EmitTPRel32Value(const MCExpr *Value); - /// \brief Emit the expression \p Value into the output as a gprel64 (64-bit + /// Emit the expression \p Value into the output as a gprel64 (64-bit /// GP relative) value. /// /// This is used to implement assembler directives such as .gpdword on /// targets that support them. virtual void EmitGPRel64Value(const MCExpr *Value); - /// \brief Emit the expression \p Value into the output as a gprel32 (32-bit + /// Emit the expression \p Value into the output as a gprel32 (32-bit /// GP relative) value. /// /// This is used to implement assembler directives such as .gprel32 on /// targets that support them. virtual void EmitGPRel32Value(const MCExpr *Value); - /// \brief Emit NumBytes bytes worth of the value specified by FillValue. + /// Emit NumBytes bytes worth of the value specified by FillValue. /// This implements directives such as '.space'. void emitFill(uint64_t NumBytes, uint8_t FillValue); - /// \brief Emit \p Size bytes worth of the value specified by \p FillValue. + /// Emit \p Size bytes worth of the value specified by \p FillValue. /// /// This is used to implement assembler directives such as .space or .skip. /// @@ -677,7 +684,7 @@ public: virtual void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc = SMLoc()); - /// \brief Emit \p NumValues copies of \p Size bytes. Each \p Size bytes is + /// Emit \p NumValues copies of \p Size bytes. Each \p Size bytes is /// taken from the lowest order 4 bytes of \p Expr expression. /// /// This is used to implement assembler directives such as .fill. @@ -688,11 +695,11 @@ public: virtual void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, SMLoc Loc = SMLoc()); - /// \brief Emit NumBytes worth of zeros. + /// Emit NumBytes worth of zeros. /// This function properly handles data in virtual sections. void EmitZeros(uint64_t NumBytes); - /// \brief Emit some number of copies of \p Value until the byte alignment \p + /// Emit some number of copies of \p Value until the byte alignment \p /// ByteAlignment is reached. /// /// If the number of bytes need to emit for the alignment is not a multiple @@ -713,7 +720,7 @@ public: unsigned ValueSize = 1, unsigned MaxBytesToEmit = 0); - /// \brief Emit nops until the byte alignment \p ByteAlignment is reached. + /// Emit nops until the byte alignment \p ByteAlignment is reached. /// /// This used to align code where the alignment bytes may be executed. This /// can emit different bytes for different sizes to optimize execution. @@ -726,7 +733,7 @@ public: virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0); - /// \brief Emit some number of copies of \p Value until the byte offset \p + /// Emit some number of copies of \p Value until the byte offset \p /// Offset is reached. /// /// This is used to implement assembler directives such as .org. @@ -745,15 +752,15 @@ public: /// @} - /// \brief Switch to a new logical file. This is used to implement the '.file + /// Switch to a new logical file. This is used to implement the '.file /// "foo.c"' assembler directive. virtual void EmitFileDirective(StringRef Filename); - /// \brief Emit the "identifiers" directive. This implements the + /// Emit the "identifiers" directive. This implements the /// '.ident "version foo"' assembler directive. virtual void EmitIdent(StringRef IdentString) {} - /// \brief Associate a filename with a specified logical file number. This + /// Associate a filename with a specified logical file number. This /// implements the DWARF2 '.file 4 "foo.c"' assembler directive. unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, @@ -781,7 +788,7 @@ public: Optional Source, unsigned CUID = 0); - /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler + /// This implements the DWARF2 '.loc fileno lineno ...' assembler /// directive. virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, @@ -795,27 +802,27 @@ public: ArrayRef Checksum, unsigned ChecksumKind); - /// \brief Introduces a function id for use with .cv_loc. + /// Introduces a function id for use with .cv_loc. virtual bool EmitCVFuncIdDirective(unsigned FunctionId); - /// \brief Introduces an inline call site id for use with .cv_loc. Includes + /// Introduces an inline call site id for use with .cv_loc. Includes /// extra information for inline line table generation. virtual bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc); - /// \brief This implements the CodeView '.cv_loc' assembler directive. + /// This implements the CodeView '.cv_loc' assembler directive. virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc); - /// \brief This implements the CodeView '.cv_linetable' assembler directive. + /// This implements the CodeView '.cv_linetable' assembler directive. virtual void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd); - /// \brief This implements the CodeView '.cv_inline_linetable' assembler + /// This implements the CodeView '.cv_inline_linetable' assembler /// directive. virtual void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, @@ -823,16 +830,16 @@ public: const MCSymbol *FnStartSym, const MCSymbol *FnEndSym); - /// \brief This implements the CodeView '.cv_def_range' assembler + /// This implements the CodeView '.cv_def_range' assembler /// directive. virtual void EmitCVDefRangeDirective( ArrayRef> Ranges, StringRef FixedSizePortion); - /// \brief This implements the CodeView '.cv_stringtable' assembler directive. + /// This implements the CodeView '.cv_stringtable' assembler directive. virtual void EmitCVStringTableDirective() {} - /// \brief This implements the CodeView '.cv_filechecksums' assembler directive. + /// This implements the CodeView '.cv_filechecksums' assembler directive. virtual void EmitCVFileChecksumsDirective() {} /// This implements the CodeView '.cv_filechecksumoffset' assembler @@ -894,6 +901,9 @@ public: SMLoc Loc = SMLoc()); virtual void EmitWinEHHandlerData(SMLoc Loc = SMLoc()); + virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, + const MCSymbolRefExpr *To, uint64_t Count); + /// Get the .pdata section used for the given section. Typically the given /// section is either the main .text section or some other COMDAT .text /// section, but it may be any section containing code. @@ -904,7 +914,7 @@ public: virtual void EmitSyntaxDirective(); - /// \brief Emit a .reloc directive. + /// Emit a .reloc directive. /// Returns true if the relocation could not be emitted because Name is not /// known. virtual bool EmitRelocDirective(const MCExpr &Offset, StringRef Name, @@ -912,33 +922,33 @@ public: return true; } - /// \brief Emit the given \p Instruction into the current section. + /// Emit the given \p Instruction into the current section. /// PrintSchedInfo == true then schedul comment should be added to output virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo = false); - /// \brief Set the bundle alignment mode from now on in the section. + /// Set the bundle alignment mode from now on in the section. /// The argument is the power of 2 to which the alignment is set. The /// value 0 means turn the bundle alignment off. virtual void EmitBundleAlignMode(unsigned AlignPow2); - /// \brief The following instructions are a bundle-locked group. + /// The following instructions are a bundle-locked group. /// /// \param AlignToEnd - If true, the bundle-locked group will be aligned to /// the end of a bundle. virtual void EmitBundleLock(bool AlignToEnd); - /// \brief Ends a bundle-locked group. + /// Ends a bundle-locked group. virtual void EmitBundleUnlock(); - /// \brief If this file is backed by a assembly streamer, this dumps the + /// If this file is backed by a assembly streamer, this dumps the /// specified string in the output .s file. This capability is indicated by /// the hasRawTextSupport() predicate. By default this aborts. void EmitRawText(const Twine &String); - /// \brief Streamer specific finalization. + /// Streamer specific finalization. virtual void FinishImpl(); - /// \brief Finish emission of machine code. + /// Finish emission of machine code. void Finish(); virtual bool mayHaveInstructions(MCSection &Sec) const { return true; } diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 0a2b247ff80b14c33ce6bd74309b23b74968aeed..b3ce523d9c0ca4da9c5a3a8156019a600ef1c4f0 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -27,7 +27,6 @@ namespace llvm { -class MachineInstr; class MCInst; //===----------------------------------------------------------------------===// @@ -160,6 +159,13 @@ public: /// Initialize an InstrItineraryData instance. void initInstrItins(InstrItineraryData &InstrItins) const; + /// Resolve a variant scheduling class for the given MCInst and CPU. + virtual unsigned + resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, + unsigned CPUID) const { + return 0; + } + /// Check whether the CPU string is valid. bool isCPUStringValid(StringRef CPU) const { auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU); @@ -167,10 +173,6 @@ public: } /// Returns string representation of scheduler comment - virtual std::string getSchedInfoStr(const MachineInstr &MI) const { - return {}; - } - virtual std::string getSchedInfoStr(MCInst const &MCI) const { return {}; } diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index cc8fc02968a5d08d5792688158ed189822d4cdc1..4681a1be60c4467b883ba6dd560f9dd9cbcd8a2c 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -85,7 +85,7 @@ protected: /// "Lfoo" or ".foo". unsigned IsTemporary : 1; - /// \brief True if this symbol can be redefined. + /// True if this symbol can be redefined. unsigned IsRedefinable : 1; /// IsUsed - True if this symbol has been used. @@ -141,7 +141,7 @@ protected: friend class MCExpr; friend class MCContext; - /// \brief The name for a symbol. + /// The name for a symbol. /// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit /// system, the name is a pointer so isn't going to satisfy the 8 byte /// alignment of uint64_t. Account for that here. @@ -168,11 +168,11 @@ protected: private: void operator delete(void *); - /// \brief Placement delete - required by std, but never called. + /// Placement delete - required by std, but never called. void operator delete(void*, unsigned) { llvm_unreachable("Constructor throws?"); } - /// \brief Placement delete - required by std, but never called. + /// Placement delete - required by std, but never called. void operator delete(void*, unsigned, bool) { llvm_unreachable("Constructor throws?"); } @@ -185,7 +185,7 @@ private: return nullptr; } - /// \brief Get a reference to the name field. Requires that we have a name + /// Get a reference to the name field. Requires that we have a name const StringMapEntry *&getNameEntryPtr() { assert(FragmentAndHasName.getInt() && "Name is required"); NameEntryStorageTy *Name = reinterpret_cast(this); @@ -222,11 +222,11 @@ public: /// isUsed - Check if this is used. bool isUsed() const { return IsUsed; } - /// \brief Check if this symbol is redefinable. + /// Check if this symbol is redefinable. bool isRedefinable() const { return IsRedefinable; } - /// \brief Mark this symbol as redefinable. + /// Mark this symbol as redefinable. void setRedefinable(bool Value) { IsRedefinable = Value; } - /// \brief Prepare this symbol to be redefined. + /// Prepare this symbol to be redefined. void redefineIfPossible() { if (IsRedefinable) { if (SymbolContents == SymContentsVariable) { @@ -316,6 +316,8 @@ public: Index = Value; } + bool isUnset() const { return SymbolContents == SymContentsUnset; } + uint64_t getOffset() const { assert((SymbolContents == SymContentsUnset || SymbolContents == SymContentsOffset) && diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h index 25220e4a81090a18e75bddcb114fdbbb9a823867..6125c2050976849e38ec9b9268ffb348ea9a4cbf 100644 --- a/include/llvm/MC/MCSymbolMachO.h +++ b/include/llvm/MC/MCSymbolMachO.h @@ -14,7 +14,7 @@ namespace llvm { class MCSymbolMachO : public MCSymbol { - /// \brief We store the value for the 'desc' symbol field in the + /// We store the value for the 'desc' symbol field in the /// lowest 16 bits of the implementation defined flags. enum MachOSymbolFlags : uint16_t { // See . SF_DescFlagsMask = 0xFFFF, @@ -104,7 +104,7 @@ public: setFlags(Value & SF_DescFlagsMask); } - /// \brief Get the encoded value of the flags as they will be emitted in to + /// Get the encoded value of the flags as they will be emitted in to /// the MachO binary uint16_t getEncodedFlags(bool EncodeAsAltEntry) const { uint16_t Flags = getFlags(); diff --git a/include/llvm/MC/MCSymbolWasm.h b/include/llvm/MC/MCSymbolWasm.h index 10eadb03c43416f6c5580587e39fa6d36d8cc3f2..e043453dc73242b8d2d8b7f354aa4732ce98ea58 100644 --- a/include/llvm/MC/MCSymbolWasm.h +++ b/include/llvm/MC/MCSymbolWasm.h @@ -45,6 +45,7 @@ public: bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; } bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; } bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; } + bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; } wasm::WasmSymbolType getType() const { return Type; } void setType(wasm::WasmSymbolType type) { Type = type; } diff --git a/include/llvm/MC/MCTargetOptionsCommandFlags.def b/include/llvm/MC/MCTargetOptionsCommandFlags.inc similarity index 100% rename from include/llvm/MC/MCTargetOptionsCommandFlags.def rename to include/llvm/MC/MCTargetOptionsCommandFlags.inc diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index ff223f70303bc43a7229281e4f70c7d54d2abd36..11f5082ed3f4849feba5702ad612cbfe4e14e936 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -23,7 +23,7 @@ namespace llvm { class MCAsmInfo; class raw_ostream; -/// \brief This represents an "assembler immediate". +/// This represents an "assembler immediate". /// /// In its most general form, this can hold ":Kind:(SymbolA - SymbolB + /// imm64)". Not all targets supports relocations of this general form, but we @@ -49,13 +49,13 @@ public: const MCSymbolRefExpr *getSymB() const { return SymB; } uint32_t getRefKind() const { return RefKind; } - /// \brief Is this an absolute (as opposed to relocatable) value. + /// Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } - /// \brief Print the value to the stream \p OS. + /// Print the value to the stream \p OS. void print(raw_ostream &OS) const; - /// \brief Print the value to stderr. + /// Print the value to stderr. void dump() const; MCSymbolRefExpr::VariantKind getAccessVariant() const; diff --git a/include/llvm/MC/MCWasmObjectWriter.h b/include/llvm/MC/MCWasmObjectWriter.h index a4d5eb857b393ad77558c7a84fbb662ce351e63d..e45030f302ff735b358c8cd337425c81acdcc6ec 100644 --- a/include/llvm/MC/MCWasmObjectWriter.h +++ b/include/llvm/MC/MCWasmObjectWriter.h @@ -10,18 +10,16 @@ #ifndef LLVM_MC_MCWASMOBJECTWRITER_H #define LLVM_MC_MCWASMOBJECTWRITER_H -#include "llvm/ADT/Triple.h" -#include "llvm/BinaryFormat/Wasm.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/MC/MCObjectWriter.h" +#include namespace llvm { class MCFixup; -class MCObjectWriter; class MCValue; class raw_pwrite_stream; -class MCWasmObjectTargetWriter { +class MCWasmObjectTargetWriter : public MCObjectTargetWriter { const unsigned Is64Bit : 1; protected: @@ -30,6 +28,11 @@ protected: public: virtual ~MCWasmObjectTargetWriter(); + virtual Triple::ObjectFormatType getFormat() const { return Triple::Wasm; } + static bool classof(const MCObjectTargetWriter *W) { + return W->getFormat() == Triple::Wasm; + } + virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup) const = 0; @@ -39,7 +42,7 @@ public: /// @} }; -/// \brief Construct a new Wasm writer instance. +/// Construct a new Wasm writer instance. /// /// \param MOTW - The target specific Wasm writer subclass. /// \param OS - The stream to write to. diff --git a/include/llvm/MC/MCWasmStreamer.h b/include/llvm/MC/MCWasmStreamer.h index c0d45451a9ab1de60bc30be4ab5ed1e9051ea469..e2da11caa247d6281e0243ecb00df6fbf4b10d21 100644 --- a/include/llvm/MC/MCWasmStreamer.h +++ b/include/llvm/MC/MCWasmStreamer.h @@ -15,6 +15,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/DataTypes.h" @@ -27,8 +28,10 @@ class raw_ostream; class MCWasmStreamer : public MCObjectStreamer { public: MCWasmStreamer(MCContext &Context, std::unique_ptr TAB, - raw_pwrite_stream &OS, std::unique_ptr Emitter) - : MCObjectStreamer(Context, std::move(TAB), OS, std::move(Emitter)), + std::unique_ptr OW, + std::unique_ptr Emitter) + : MCObjectStreamer(Context, std::move(TAB), std::move(OW), + std::move(Emitter)), SeenIdent(false) {} ~MCWasmStreamer() override; @@ -73,7 +76,7 @@ private: void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; - /// \brief Merge the content of the fragment \p EF into the fragment \p DF. + /// Merge the content of the fragment \p EF into the fragment \p DF. void mergeFragment(MCDataFragment *, MCDataFragment *); bool SeenIdent; diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 3234bd93cad0ad6bf7de3f8539a3a39bc565aa75..c1d35ea1f6baaad1413290ceb70be19484d0004f 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H #define LLVM_MC_MCWINCOFFOBJECTWRITER_H +#include "llvm/MC/MCObjectWriter.h" #include namespace llvm { @@ -17,11 +18,10 @@ namespace llvm { class MCAsmBackend; class MCContext; class MCFixup; -class MCObjectWriter; class MCValue; class raw_pwrite_stream; - class MCWinCOFFObjectTargetWriter { + class MCWinCOFFObjectTargetWriter : public MCObjectTargetWriter { virtual void anchor(); const unsigned Machine; @@ -32,6 +32,11 @@ class raw_pwrite_stream; public: virtual ~MCWinCOFFObjectTargetWriter() = default; + virtual Triple::ObjectFormatType getFormat() const { return Triple::COFF; } + static bool classof(const MCObjectTargetWriter *W) { + return W->getFormat() == Triple::COFF; + } + unsigned getMachine() const { return Machine; } virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsCrossSection, @@ -39,7 +44,7 @@ class raw_pwrite_stream; virtual bool recordRelocation(const MCFixup &) const { return true; } }; - /// \brief Construct a new Win COFF writer instance. + /// Construct a new Win COFF writer instance. /// /// \param MOTW - The target specific WinCOFF writer subclass. /// \param OS - The stream to write to. diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index 60c17cac9f2870323d62dda612b3de2e6111cd9e..58f70b4b4c2c201690e14449d51f9e9e821e5ca3 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -28,7 +28,8 @@ class raw_pwrite_stream; class MCWinCOFFStreamer : public MCObjectStreamer { public: MCWinCOFFStreamer(MCContext &Context, std::unique_ptr MAB, - std::unique_ptr CE, raw_pwrite_stream &OS); + std::unique_ptr CE, + std::unique_ptr OW); /// state management void reset() override { diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h index 89bc55a02c27fe670f567309e55a9ebcffad09ad..265260fcee4d2f5e03e07b663412e9b689ee7cd7 100644 --- a/include/llvm/MC/StringTableBuilder.h +++ b/include/llvm/MC/StringTableBuilder.h @@ -20,7 +20,7 @@ namespace llvm { class raw_ostream; -/// \brief Utility for building string tables with deduplicated suffixes. +/// Utility for building string tables with deduplicated suffixes. class StringTableBuilder { public: enum Kind { ELF, WinCOFF, MachO, RAW, DWARF }; @@ -39,13 +39,13 @@ public: StringTableBuilder(Kind K, unsigned Alignment = 1); ~StringTableBuilder(); - /// \brief Add a string to the builder. Returns the position of S in the + /// Add a string to the builder. Returns the position of S in the /// table. The position will be changed if finalize is used. /// Can only be used before the table is finalized. size_t add(CachedHashStringRef S); size_t add(StringRef S) { return add(CachedHashStringRef(S)); } - /// \brief Analyze the strings and build the final table. No more strings can + /// Analyze the strings and build the final table. No more strings can /// be added after this point. void finalize(); @@ -53,7 +53,7 @@ public: /// returned by add will still be valid. void finalizeInOrder(); - /// \brief Get the offest of a string in the string table. Can only be used + /// Get the offest of a string in the string table. Can only be used /// after the table is finalized. size_t getOffset(CachedHashStringRef S) const; size_t getOffset(StringRef S) const { diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 5a1512bb9d36335aee7f6e4a8001a85adea95f24..9ef1e4875191fc14bf7d73f4d68ce5b12eb5b1cb 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -91,9 +91,9 @@ public: const Archive *Parent; ArchiveMemberHeader Header; - /// \brief Includes header but not padding byte. + /// Includes header but not padding byte. StringRef Data; - /// \brief Offset from Data to the start of the file. + /// Offset from Data to the start of the file. uint16_t StartOfFile; Expected isThinMember() const; diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 5e93691d1fd2b6d44e5a4ba93d451eb54e49f194..99745e24b8c862ded32c9850ab700878f048d3c6 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -156,7 +156,7 @@ public: } }; -/// @brief Create a Binary from Source, autodetecting the file type. +/// Create a Binary from Source, autodetecting the file type. /// /// @param Source The data to create the Binary from. Expected> createBinary(MemoryBufferRef Source, diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 9190149f38255d3c24e023fe260564878cbcdc58..2d1e9403dcfbdda20401e146f65411a98dfd7438 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -452,11 +452,12 @@ struct coff_section { if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD) return 1; - // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1. + // Bit [20:24] contains section alignment. 0 means use a default alignment + // of 16. uint32_t Shift = (Characteristics >> 20) & 0xF; if (Shift > 0) return 1U << (Shift - 1); - return 1; + return 16; } }; @@ -1012,8 +1013,7 @@ public: llvm_unreachable("null symbol table pointer!"); } - iterator_range - getRelocations(const coff_section *Sec) const; + ArrayRef getRelocations(const coff_section *Sec) const; std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const; uint64_t getSectionSize(const coff_section *Sec) const; diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index 7ca416ff1b225082e60f8d89d45486e830f99640..0a4556ad88845fb2af86ae7171a03a10aa1c8f94 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -74,6 +74,7 @@ struct COFFShortExport { std::string Name; std::string ExtName; std::string SymbolName; + std::string AliasTarget; uint16_t Ordinal = 0; bool Noname = false; @@ -81,10 +82,6 @@ struct COFFShortExport { bool Private = false; bool Constant = false; - bool isWeak() { - return ExtName.size() && ExtName != Name; - } - friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) { return L.Name == R.Name && L.ExtName == R.ExtName && L.Ordinal == R.Ordinal && L.Noname == R.Noname && @@ -98,8 +95,7 @@ struct COFFShortExport { Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef Exports, - COFF::MachineTypes Machine, bool MakeWeakAliases, - bool MinGW); + COFF::MachineTypes Machine, bool MinGW); } // namespace object } // namespace llvm diff --git a/include/llvm/Object/Decompressor.h b/include/llvm/Object/Decompressor.h index c8e888d285e4a820166a737f9881ff80920e5cc6..2a77d2ffbf687f676b0b0b72e53f8325a4657ffe 100644 --- a/include/llvm/Object/Decompressor.h +++ b/include/llvm/Object/Decompressor.h @@ -17,10 +17,10 @@ namespace llvm { namespace object { -/// @brief Decompressor helps to handle decompression of compressed sections. +/// Decompressor helps to handle decompression of compressed sections. class Decompressor { public: - /// @brief Create decompressor object. + /// Create decompressor object. /// @param Name Section name. /// @param Data Section content. /// @param IsLE Flag determines if Data is in little endian form. @@ -28,27 +28,27 @@ public: static Expected create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit); - /// @brief Resize the buffer and uncompress section data into it. + /// Resize the buffer and uncompress section data into it. /// @param Out Destination buffer. template Error resizeAndDecompress(T &Out) { Out.resize(DecompressedSize); return decompress({Out.data(), (size_t)DecompressedSize}); } - /// @brief Uncompress section data to raw buffer provided. + /// Uncompress section data to raw buffer provided. /// @param Buffer Destination buffer. Error decompress(MutableArrayRef Buffer); - /// @brief Return memory buffer size required for decompression. + /// Return memory buffer size required for decompression. uint64_t getDecompressedSize() { return DecompressedSize; } - /// @brief Return true if section is compressed, including gnu-styled case. + /// Return true if section is compressed, including gnu-styled case. static bool isCompressed(const object::SectionRef &Section); - /// @brief Return true if section is a ELF compressed one. + /// Return true if section is a ELF compressed one. static bool isCompressedELFSection(uint64_t Flags, StringRef Name); - /// @brief Return true if section name matches gnu style compressed one. + /// Return true if section name matches gnu style compressed one. static bool isGnuStyle(StringRef Name); private: diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 46504e74bc26c4d65217bf249c584b1e7146e760..06f49c4ac7313927c900ee5697cee9920b6e8d3a 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -111,7 +111,7 @@ public: void getRelocationTypeName(uint32_t Type, SmallVectorImpl &Result) const; - /// \brief Get the symbol for a given relocation. + /// Get the symbol for a given relocation. Expected getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const; @@ -145,7 +145,7 @@ public: Expected> android_relas(const Elf_Shdr *Sec) const; - /// \brief Iterate over program header table. + /// Iterate over program header table. Expected program_headers() const { if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr)) return createError("invalid e_phentsize"); diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 4d0010392387ef05732676b63277eb25b6e07b0d..e74b533f1d70f4a190e900580748a56e61b4be1c 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -270,7 +270,7 @@ protected: uint64_t getSectionOffset(DataRefImpl Sec) const override; StringRef getRelocationTypeName(uint32_t Type) const; - /// \brief Get the relocation section that contains \a Rel. + /// Get the relocation section that contains \a Rel. const Elf_Shdr *getRelSection(DataRefImpl Rel) const { auto RelSecOrErr = EF.getSection(Rel.d.a); if (!RelSecOrErr) diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 260ca96c9cc949e2de2c32c14ca212002d266b58..78a1b9848cbd525a17a328bbe4f338163887af2f 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -43,6 +43,7 @@ template struct Elf_Chdr_Impl; template struct Elf_Nhdr_Impl; template class Elf_Note_Impl; template class Elf_Note_Iterator_Impl; +template struct Elf_CGProfile_Impl; template struct ELFType { private: @@ -72,6 +73,7 @@ public: using Nhdr = Elf_Nhdr_Impl>; using Note = Elf_Note_Impl>; using NoteIterator = Elf_Note_Iterator_Impl>; + using CGProfile = Elf_CGProfile_Impl>; using DynRange = ArrayRef; using ShdrRange = ArrayRef; using SymRange = ArrayRef; @@ -148,7 +150,7 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base { using Elf_Shdr_Base::sh_entsize; using Elf_Shdr_Base::sh_size; - /// @brief Get the number of entities this section contains if it has any. + /// Get the number of entities this section contains if it has any. unsigned getEntityCount() const { if (sh_entsize == 0) return 0; @@ -678,6 +680,13 @@ public: } }; +template struct Elf_CGProfile_Impl { + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Elf_Word cgp_from; + Elf_Word cgp_to; + Elf_Xword cgp_weight; +}; + // MIPS .reginfo section template struct Elf_Mips_RegInfo; diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index 6c271b1a1f44c8dc2ff389895bc15d7a00f3caeb..559a91af94db5ec63be54761865a390485cbb1dd 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -50,11 +50,11 @@ public: return v->isIR(); } - /// \brief Finds and returns bitcode embedded in the given object file, or an + /// Finds and returns bitcode embedded in the given object file, or an /// error code if not found. static Expected findBitcodeInObject(const ObjectFile &Obj); - /// \brief Finds and returns bitcode in the given memory buffer (which may + /// Finds and returns bitcode in the given memory buffer (which may /// be either a bitcode file or a native object file with embedded bitcode), /// or an error code if not found. static Expected diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index 72837d0970c4b262920e7cac2d43d2912edeb596..9e70b0bc30c040d7dbe4786a19c86b27f5ed2b11 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -34,9 +34,9 @@ class MachOUniversalBinary : public Binary { public: class ObjectForArch { const MachOUniversalBinary *Parent; - /// \brief Index of object in the universal binary. + /// Index of object in the universal binary. uint32_t Index; - /// \brief Descriptor of the object. + /// Descriptor of the object. MachO::fat_arch Header; MachO::fat_arch_64 Header64; diff --git a/include/llvm/Object/ModuleSymbolTable.h b/include/llvm/Object/ModuleSymbolTable.h index 9e9322885388490fa97499a57e8d5d50256dcece..c3cbc27998e5ac2b057ad23fdc7927fd96c66382 100644 --- a/include/llvm/Object/ModuleSymbolTable.h +++ b/include/llvm/Object/ModuleSymbolTable.h @@ -57,6 +57,15 @@ public: static void CollectAsmSymbols( const Module &M, function_ref AsmSymbol); + + /// Parse inline ASM and collect the symvers directives that are defined in + /// the current module. + /// + /// For each found symbol, call \p AsmSymver with the name of the symbol and + /// its alias. + static void + CollectAsmSymvers(const Module &M, + function_ref AsmSymver); }; } // end namespace llvm diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 9c4ae94d3a69e7e313ee58ac284ae43658b1ee6c..f0685482b6a7cc0760e7c18efc8640d557739b49 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -65,7 +65,7 @@ public: symbol_iterator getSymbol() const; uint64_t getType() const; - /// @brief Get a string that represents the type of this relocation. + /// Get a string that represents the type of this relocation. /// /// This is for display purposes only. void getTypeName(SmallVectorImpl &Result) const; @@ -100,7 +100,7 @@ public: uint64_t getSize() const; std::error_code getContents(StringRef &Result) const; - /// @brief Get the alignment of this section as the actual value (not log 2). + /// Get the alignment of this section as the actual value (not log 2). uint64_t getAlignment() const; bool isCompressed() const; @@ -154,12 +154,12 @@ public: /// offset or a virtual address. uint64_t getValue() const; - /// @brief Get the alignment of this symbol as the actual value (not log 2). + /// Get the alignment of this symbol as the actual value (not log 2). uint32_t getAlignment() const; uint64_t getCommonSize() const; Expected getType() const; - /// @brief Get section this symbol is defined in reference to. Result is + /// Get section this symbol is defined in reference to. Result is /// end_sections() if it is undefined or is an absolute symbol. Expected getSection() const; @@ -275,7 +275,7 @@ public: return section_iterator_range(section_begin(), section_end()); } - /// @brief The number of bytes used to represent an address in this object + /// The number of bytes used to represent an address in this object /// file format. virtual uint8_t getBytesInAddress() const = 0; @@ -284,7 +284,7 @@ public: virtual SubtargetFeatures getFeatures() const = 0; virtual void setARMSubArch(Triple &TheTriple) const { } - /// @brief Create a triple from the data in this object file. + /// Create a triple from the data in this object file. Triple makeTriple() const; virtual std::error_code @@ -301,7 +301,7 @@ public: /// @returns Pointer to ObjectFile subclass to handle this type of object. /// @param ObjectPath The path to the object file. ObjectPath.isObject must /// return true. - /// @brief Create ObjectFile from path. + /// Create ObjectFile from path. static Expected> createObjectFile(StringRef ObjectPath); diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 2d0e938f06fdca0b810c8acba2cadf8c239f4058..008e109f6679e58c4e49c491b9f17652183f86e0 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -23,6 +23,7 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Wasm.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include @@ -31,7 +32,7 @@ namespace llvm { namespace object { -/// @brief Base class for object file relocation visitors. +/// Base class for object file relocation visitors. class RelocVisitor { public: explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {} @@ -46,6 +47,8 @@ public: return visitCOFF(Rel, R, Value); if (isa(ObjToVisit)) return visitMachO(Rel, R, Value); + if (isa(ObjToVisit)) + return visitWasm(Rel, R, Value); HasError = true; return 0; @@ -316,6 +319,27 @@ private: HasError = true; return 0; } + + uint64_t visitWasm(uint32_t Rel, RelocationRef R, uint64_t Value) { + if (ObjToVisit.getArch() == Triple::wasm32) { + switch (Rel) { + case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: + case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: + case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: + case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: + case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: + case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: + case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: + // For wasm section, its offset at 0 -- ignoring Value + return 0; + } + } + HasError = true; + return 0; + } }; } // end namespace object diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index d49acf3a38a3c06ea8ce597413df2e6d90cdae20..fd34e45feb624a134eec66fdd256b8d73bbc7b9a 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -21,6 +21,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/BinaryFormat/Wasm.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" @@ -53,6 +54,10 @@ public: return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL; } + bool isTypeSection() const { + return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION; + } + bool isDefined() const { return !isUndefined(); } bool isUndefined() const { @@ -83,20 +88,10 @@ public: return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK; } - void print(raw_ostream &Out) const { - Out << "Name=" << Info.Name << ", Kind=" << Info.Kind - << ", Flags=" << Info.Flags; - if (!isTypeData()) { - Out << ", ElemIndex=" << Info.ElementIndex; - } else if (isDefined()) { - Out << ", Segment=" << Info.DataRef.Segment; - Out << ", Offset=" << Info.DataRef.Offset; - Out << ", Size=" << Info.DataRef.Size; - } - } + void print(raw_ostream &Out) const; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - LLVM_DUMP_METHOD void dump() const { print(dbgs()); } + LLVM_DUMP_METHOD void dump() const; #endif }; @@ -198,6 +193,12 @@ public: SubtargetFeatures getFeatures() const override; bool isRelocatableObject() const override; + struct ReadContext { + const uint8_t *Start; + const uint8_t *Ptr; + const uint8_t *End; + }; + private: bool isValidFunctionIndex(uint32_t Index) const; bool isDefinedFunctionIndex(uint32_t Index) const; @@ -206,40 +207,36 @@ private: bool isValidFunctionSymbol(uint32_t Index) const; bool isValidGlobalSymbol(uint32_t Index) const; bool isValidDataSymbol(uint32_t Index) const; + bool isValidSectionSymbol(uint32_t Index) const; wasm::WasmFunction &getDefinedFunction(uint32_t Index); wasm::WasmGlobal &getDefinedGlobal(uint32_t Index); const WasmSection &getWasmSection(DataRefImpl Ref) const; const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const; - WasmSection* findCustomSectionByName(StringRef Name); - WasmSection* findSectionByType(uint32_t Type); - const uint8_t *getPtr(size_t Offset) const; Error parseSection(WasmSection &Sec); - Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr, - const uint8_t *End); + Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx); // Standard section types - Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End); - Error parseImportSection(const uint8_t *Ptr, const uint8_t *End); - Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End); - Error parseTableSection(const uint8_t *Ptr, const uint8_t *End); - Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End); - Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End); - Error parseExportSection(const uint8_t *Ptr, const uint8_t *End); - Error parseStartSection(const uint8_t *Ptr, const uint8_t *End); - Error parseElemSection(const uint8_t *Ptr, const uint8_t *End); - Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End); - Error parseDataSection(const uint8_t *Ptr, const uint8_t *End); + Error parseTypeSection(ReadContext &Ctx); + Error parseImportSection(ReadContext &Ctx); + Error parseFunctionSection(ReadContext &Ctx); + Error parseTableSection(ReadContext &Ctx); + Error parseMemorySection(ReadContext &Ctx); + Error parseGlobalSection(ReadContext &Ctx); + Error parseExportSection(ReadContext &Ctx); + Error parseStartSection(ReadContext &Ctx); + Error parseElemSection(ReadContext &Ctx); + Error parseCodeSection(ReadContext &Ctx); + Error parseDataSection(ReadContext &Ctx); // Custom section types - Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); - Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End); - Error parseLinkingSectionSymtab(const uint8_t *&Ptr, const uint8_t *End); - Error parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End); - Error parseRelocSection(StringRef Name, const uint8_t *Ptr, - const uint8_t *End); + Error parseNameSection(ReadContext &Ctx); + Error parseLinkingSection(ReadContext &Ctx); + Error parseLinkingSectionSymtab(ReadContext &Ctx); + Error parseLinkingSectionComdat(ReadContext &Ctx); + Error parseRelocSection(StringRef Name, ReadContext &Ctx); wasm::WasmObjectHeader Header; std::vector Sections; diff --git a/include/llvm/ObjectYAML/COFFYAML.h b/include/llvm/ObjectYAML/COFFYAML.h index 8794eaa6d59a810787fb14a4ebf82976833f1dee..78f021fc0386987e15140ff241bf8b3ad7992e04 100644 --- a/include/llvm/ObjectYAML/COFFYAML.h +++ b/include/llvm/ObjectYAML/COFFYAML.h @@ -67,6 +67,7 @@ struct Section { yaml::BinaryRef SectionData; std::vector DebugS; std::vector DebugT; + std::vector DebugP; Optional DebugH; std::vector Relocations; StringRef Name; diff --git a/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h b/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h index 4f0d9efb963bf462846416782070a7905bad6912..344966fe68919e166364ca6dfc1005f6bb29e5ca 100644 --- a/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h +++ b/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h @@ -32,10 +32,10 @@ namespace CodeViewYAML { struct GlobalHash { GlobalHash() = default; explicit GlobalHash(StringRef S) : Hash(S) { - assert(S.size() == 20 && "Invalid hash size!"); + assert(S.size() == 8 && "Invalid hash size!"); } explicit GlobalHash(ArrayRef S) : Hash(S) { - assert(S.size() == 20 && "Invalid hash size!"); + assert(S.size() == 8 && "Invalid hash size!"); } yaml::BinaryRef Hash; }; @@ -47,7 +47,7 @@ struct DebugHSection { std::vector Hashes; }; -DebugHSection fromDebugH(ArrayRef DebugT); +DebugHSection fromDebugH(ArrayRef DebugH); ArrayRef toDebugH(const DebugHSection &DebugH, BumpPtrAllocator &Alloc); diff --git a/include/llvm/ObjectYAML/CodeViewYAMLTypes.h b/include/llvm/ObjectYAML/CodeViewYAMLTypes.h index bc3b5567c2f9cf9f099e8a2692d61b022683d463..1b1306df4f53cea47dc6dcbb90b30c6ae75ad879 100644 --- a/include/llvm/ObjectYAML/CodeViewYAMLTypes.h +++ b/include/llvm/ObjectYAML/CodeViewYAMLTypes.h @@ -51,8 +51,10 @@ struct LeafRecord { static Expected fromCodeViewRecord(codeview::CVType Type); }; -std::vector fromDebugT(ArrayRef DebugT); -ArrayRef toDebugT(ArrayRef, BumpPtrAllocator &Alloc); +std::vector fromDebugT(ArrayRef DebugTorP, + StringRef SectionName); +ArrayRef toDebugT(ArrayRef, BumpPtrAllocator &Alloc, + StringRef SectionName); } // end namespace CodeViewYAML diff --git a/include/llvm/ObjectYAML/DWARFEmitter.h b/include/llvm/ObjectYAML/DWARFEmitter.h index 0d7d8b4efbdf622e2cc4b0616df1b8faf73aa659..ce32274219303e25891c0d235b3c154cdc4b6d40 100644 --- a/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/include/llvm/ObjectYAML/DWARFEmitter.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// /// \file -/// \brief Common declarations for yaml2obj +/// Common declarations for yaml2obj //===----------------------------------------------------------------------===// #ifndef LLVM_OBJECTYAML_DWARFEMITTER_H @@ -39,11 +39,12 @@ void EmitDebugInfo(raw_ostream &OS, const Data &DI); void EmitDebugLine(raw_ostream &OS, const Data &DI); Expected>> -EmitDebugSections(StringRef YAMLString, +EmitDebugSections(StringRef YAMLString, bool ApplyFixups = false, bool IsLittleEndian = sys::IsLittleEndianHost); +StringMap> +EmitDebugSections(llvm::DWARFYAML::Data &DI, bool ApplyFixups); } // end namespace DWARFYAML - } // end namespace llvm #endif // LLVM_OBJECTYAML_DWARFEMITTER_H diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h index 2162f0fef852099dcac96f8eeae4867f9e25ac1c..705c887789455e7d29166a573d6ccb9edb68ff21 100644 --- a/include/llvm/ObjectYAML/DWARFYAML.h +++ b/include/llvm/ObjectYAML/DWARFYAML.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file declares classes for handling the YAML representation +/// This file declares classes for handling the YAML representation /// of DWARF Debug Info. /// //===----------------------------------------------------------------------===// diff --git a/include/llvm/ObjectYAML/ELFYAML.h b/include/llvm/ObjectYAML/ELFYAML.h index 7ba83967330eb102004383a75ec4accac66b764f..6fc69735f1c76a08ba3fc87c1515e814dc130e40 100644 --- a/include/llvm/ObjectYAML/ELFYAML.h +++ b/include/llvm/ObjectYAML/ELFYAML.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file declares classes for handling the YAML representation +/// This file declares classes for handling the YAML representation /// of ELF. /// //===----------------------------------------------------------------------===// diff --git a/include/llvm/ObjectYAML/MachOYAML.h b/include/llvm/ObjectYAML/MachOYAML.h index 1fa8f92e516a700ca4a8c8c200b6ac654ca031fa..cec4f86185f08bcdddeb49a5b3aba9b7484a4523 100644 --- a/include/llvm/ObjectYAML/MachOYAML.h +++ b/include/llvm/ObjectYAML/MachOYAML.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file declares classes for handling the YAML representation +/// This file declares classes for handling the YAML representation /// of Mach-O. /// //===----------------------------------------------------------------------===// diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index 1c5e77e101b7a0562929433c67e22fc4207abbbe..8cd08e520560b50a6714e3a86b436331f84b5861 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file declares classes for handling the YAML representation +/// This file declares classes for handling the YAML representation /// of wasm binaries. /// //===----------------------------------------------------------------------===// @@ -195,6 +195,7 @@ struct LinkingSection : CustomSection { return C && C->Name == "linking"; } + uint32_t Version; std::vector SymbolTable; std::vector SegmentInfos; std::vector InitFunctions; diff --git a/include/llvm/ObjectYAML/YAML.h b/include/llvm/ObjectYAML/YAML.h index 93266dd67f1af0cdf2718d8f985a8b511799cf77..163cd8dfcf08c5c28cfc5f448b972a0c5c4bccc4 100644 --- a/include/llvm/ObjectYAML/YAML.h +++ b/include/llvm/ObjectYAML/YAML.h @@ -21,7 +21,7 @@ class raw_ostream; namespace yaml { -/// \brief Specialized YAMLIO scalar type for representing a binary blob. +/// Specialized YAMLIO scalar type for representing a binary blob. /// /// A typical use case would be to represent the content of a section in a /// binary file. @@ -64,11 +64,11 @@ namespace yaml { class BinaryRef { friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); - /// \brief Either raw binary data, or a string of hex bytes (must always + /// Either raw binary data, or a string of hex bytes (must always /// be an even number of characters). ArrayRef Data; - /// \brief Discriminator between the two states of the `Data` member. + /// Discriminator between the two states of the `Data` member. bool DataIsHexString = true; public: @@ -77,7 +77,7 @@ public: BinaryRef(StringRef Data) : Data(reinterpret_cast(Data.data()), Data.size()) {} - /// \brief The number of bytes that are represented by this BinaryRef. + /// The number of bytes that are represented by this BinaryRef. /// This is the number of bytes that writeAsBinary() will write. ArrayRef::size_type binary_size() const { if (DataIsHexString) @@ -85,11 +85,11 @@ public: return Data.size(); } - /// \brief Write the contents (regardless of whether it is binary or a + /// Write the contents (regardless of whether it is binary or a /// hex string) as binary to the given raw_ostream. void writeAsBinary(raw_ostream &OS) const; - /// \brief Write the contents (regardless of whether it is binary or a + /// Write the contents (regardless of whether it is binary or a /// hex string) as hex to the given raw_ostream. /// /// For example, a possible output could be `DEADBEEFCAFEBABE`. diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h index c519a4a824c5166db5b91797eaf77c793a78a77c..d0086bb6d611832effa65ce675f80a24cb04aa80 100644 --- a/include/llvm/Option/Arg.h +++ b/include/llvm/Option/Arg.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Defines the llvm::Arg class for parsed arguments. +/// Defines the llvm::Arg class for parsed arguments. /// //===----------------------------------------------------------------------===// @@ -28,35 +28,35 @@ namespace opt { class ArgList; -/// \brief A concrete instance of a particular driver option. +/// A concrete instance of a particular driver option. /// /// The Arg class encodes just enough information to be able to /// derive the argument values efficiently. class Arg { private: - /// \brief The option this argument is an instance of. + /// The option this argument is an instance of. const Option Opt; - /// \brief The argument this argument was derived from (during tool chain + /// The argument this argument was derived from (during tool chain /// argument translation), if any. const Arg *BaseArg; - /// \brief How this instance of the option was spelled. + /// How this instance of the option was spelled. StringRef Spelling; - /// \brief The index at which this argument appears in the containing + /// The index at which this argument appears in the containing /// ArgList. unsigned Index; - /// \brief Was this argument used to effect compilation? + /// Was this argument used to effect compilation? /// /// This is used for generating "argument unused" diagnostics. mutable unsigned Claimed : 1; - /// \brief Does this argument own its values? + /// Does this argument own its values? mutable unsigned OwnsValues : 1; - /// \brief The argument values, as C strings. + /// The argument values, as C strings. SmallVector Values; public: @@ -74,7 +74,7 @@ public: StringRef getSpelling() const { return Spelling; } unsigned getIndex() const { return Index; } - /// \brief Return the base argument which generated this arg. + /// Return the base argument which generated this arg. /// /// This is either the argument itself or the argument it was /// derived from during tool chain specific argument translation. @@ -88,7 +88,7 @@ public: bool isClaimed() const { return getBaseArg().Claimed; } - /// \brief Set the Arg claimed bit. + /// Set the Arg claimed bit. void claim() const { getBaseArg().Claimed = true; } unsigned getNumValues() const { return Values.size(); } @@ -107,10 +107,10 @@ public: return false; } - /// \brief Append the argument onto the given array as strings. + /// Append the argument onto the given array as strings. void render(const ArgList &Args, ArgStringList &Output) const; - /// \brief Append the argument, render as an input, onto the given + /// Append the argument, render as an input, onto the given /// array as strings. /// /// The distinction is that some options only render their values @@ -120,7 +120,7 @@ public: void print(raw_ostream &O) const; void dump() const; - /// \brief Return a formatted version of the argument and + /// Return a formatted version of the argument and /// its values, for debugging and diagnostics. std::string getAsString(const ArgList &Args) const; }; diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h index a80921fa8421b764ac87ad1f73049079148e884a..687c8cbb02f9e66146e7e46f74c7fea2decd1f71 100644 --- a/include/llvm/Option/ArgList.h +++ b/include/llvm/Option/ArgList.h @@ -85,9 +85,6 @@ public: SkipToNextArg(); } - // FIXME: This conversion function makes no sense. - operator const Arg*() { return *Current; } - reference operator*() const { return *Current; } pointer operator->() const { return Current; } @@ -356,7 +353,7 @@ public: return MakeArgStringRef(Str.toStringRef(Buf)); } - /// \brief Create an arg string for (\p LHS + \p RHS), reusing the + /// Create an arg string for (\p LHS + \p RHS), reusing the /// string at \p Index if possible. const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, StringRef RHS) const; diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h index 20b9bba7e25f5ab82793f256a5098bdb23a472c3..743c4772c98c1d61075104d095b7327ad5cd8c41 100644 --- a/include/llvm/Option/OptTable.h +++ b/include/llvm/Option/OptTable.h @@ -29,7 +29,7 @@ class ArgList; class InputArgList; class Option; -/// \brief Provide access to the Option info table. +/// Provide access to the Option info table. /// /// The OptTable class provides a layer of indirection which allows Option /// instance to be created lazily. In the common case, only a few options will @@ -38,7 +38,7 @@ class Option; /// parts of the driver still use Option instances where convenient. class OptTable { public: - /// \brief Entry for a single option instance in the option data table. + /// Entry for a single option instance in the option data table. struct Info { /// A null terminated array of prefix strings to apply to name while /// matching. @@ -57,7 +57,7 @@ public: }; private: - /// \brief The option information table. + /// The option information table. std::vector OptionInfos; bool IgnoreCase; @@ -86,36 +86,36 @@ protected: public: ~OptTable(); - /// \brief Return the total number of option classes. + /// Return the total number of option classes. unsigned getNumOptions() const { return OptionInfos.size(); } - /// \brief Get the given Opt's Option instance, lazily creating it + /// Get the given Opt's Option instance, lazily creating it /// if necessary. /// /// \return The option, or null for the INVALID option id. const Option getOption(OptSpecifier Opt) const; - /// \brief Lookup the name of the given option. + /// Lookup the name of the given option. const char *getOptionName(OptSpecifier id) const { return getInfo(id).Name; } - /// \brief Get the kind of the given option. + /// Get the kind of the given option. unsigned getOptionKind(OptSpecifier id) const { return getInfo(id).Kind; } - /// \brief Get the group id for the given option. + /// Get the group id for the given option. unsigned getOptionGroupID(OptSpecifier id) const { return getInfo(id).GroupID; } - /// \brief Get the help text to use to describe this option. + /// Get the help text to use to describe this option. const char *getOptionHelpText(OptSpecifier id) const { return getInfo(id).HelpText; } - /// \brief Get the meta-variable name to use when describing + /// Get the meta-variable name to use when describing /// this options values in the help text. const char *getOptionMetaVar(OptSpecifier id) const { return getInfo(id).MetaVar; @@ -174,7 +174,7 @@ public: /// \return true in success, and false in fail. bool addValues(const char *Option, const char *Values); - /// \brief Parse a single argument; returning the new argument and + /// Parse a single argument; returning the new argument and /// updating Index. /// /// \param [in,out] Index - The current parsing position in the argument @@ -192,7 +192,7 @@ public: unsigned FlagsToInclude = 0, unsigned FlagsToExclude = 0) const; - /// \brief Parse an list of arguments into an InputArgList. + /// Parse an list of arguments into an InputArgList. /// /// The resulting InputArgList will reference the strings in [\p ArgBegin, /// \p ArgEnd), and their lifetime should extend past that of the returned @@ -214,7 +214,7 @@ public: unsigned &MissingArgCount, unsigned FlagsToInclude = 0, unsigned FlagsToExclude = 0) const; - /// \brief Render the help text for an option table. + /// Render the help text for an option table. /// /// \param OS - The stream to write the help text to. /// \param Name - The name to use in the usage line. diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h index d9aebd5b07570dad679e5362486e3fc8baf2378e..b09f6043b7a942ddf683808d3ec3adac17e6c99e 100644 --- a/include/llvm/Option/Option.h +++ b/include/llvm/Option/Option.h @@ -95,7 +95,7 @@ public: return OptionClass(Info->Kind); } - /// \brief Get the name of this option without any prefix. + /// Get the name of this option without any prefix. StringRef getName() const { assert(Info && "Must have a valid info!"); return Info->Name; @@ -113,7 +113,7 @@ public: return Owner->getOption(Info->AliasID); } - /// \brief Get the alias arguments as a \0 separated list. + /// Get the alias arguments as a \0 separated list. /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0". const char *getAliasArgs() const { assert(Info && "Must have a valid info!"); @@ -123,13 +123,13 @@ public: return Info->AliasArgs; } - /// \brief Get the default prefix for this option. + /// Get the default prefix for this option. StringRef getPrefix() const { const char *Prefix = *Info->Prefixes; return Prefix ? Prefix : StringRef(); } - /// \brief Get the name of this option with the default prefix. + /// Get the name of this option with the default prefix. std::string getPrefixedName() const { std::string Ret = getPrefix(); Ret += getName(); diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index a29b3771abb4680bf277d6ecf83138444529fcc0..d65347d611eaf792dd0f60c4f92715eb5c7b8129 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -353,18 +353,18 @@ protected: /// If the user specifies the -time-passes argument on an LLVM tool command line /// then the value of this boolean will be true, otherwise false. -/// @brief This is the storage for the -time-passes option. +/// This is the storage for the -time-passes option. extern bool TimePassesIsEnabled; /// isFunctionInPrintList - returns true if a function should be printed via // debugging options like -print-after-all/-print-before-all. -// @brief Tells if the function IR should be printed by PrinterPass. +// Tells if the function IR should be printed by PrinterPass. extern bool isFunctionInPrintList(StringRef FunctionName); /// forcePrintModuleIR - returns true if IR printing passes should // be printing module IR (even for local-pass printers e.g. function-pass) // to provide more context, as enabled by debugging option -print-module-scope -// @brief Tells if IR printer should be printing module IR +// Tells if IR printer should be printing module IR extern bool forcePrintModuleIR(); } // end namespace llvm diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h index 5efcda0a1b4b3386194152919d2b2fa203196ca8..308495a5655a160660cc84ea517f554afb3a794a 100644 --- a/include/llvm/Passes/PassBuilder.h +++ b/include/llvm/Passes/PassBuilder.h @@ -48,7 +48,7 @@ struct PGOOptions { bool SamplePGOSupport; }; -/// \brief This class provides access to building LLVM's passes. +/// This class provides access to building LLVM's passes. /// /// It's members provide the baseline state available to passes during their /// construction. The \c PassRegistry.def file specifies how to construct all @@ -59,7 +59,7 @@ class PassBuilder { Optional PGOOpt; public: - /// \brief A struct to capture parsed pass pipeline names. + /// A struct to capture parsed pass pipeline names. /// /// A pipeline is defined as a series of names, each of which may in itself /// recursively contain a nested pipeline. A name is either the name of a pass @@ -72,7 +72,7 @@ public: std::vector InnerPipeline; }; - /// \brief ThinLTO phase. + /// ThinLTO phase. /// /// This enumerates the LLVM ThinLTO optimization phases. enum class ThinLTOPhase { @@ -84,7 +84,7 @@ public: PostLink }; - /// \brief LLVM-provided high-level optimization levels. + /// LLVM-provided high-level optimization levels. /// /// This enumerates the LLVM-provided high-level optimization levels. Each /// level has a specific goal and rationale. @@ -174,7 +174,7 @@ public: Optional PGOOpt = None) : TM(TM), PGOOpt(PGOOpt) {} - /// \brief Cross register the analysis managers through their proxies. + /// Cross register the analysis managers through their proxies. /// /// This is an interface that can be used to cross register each // AnalysisManager with all the others analysis managers. @@ -183,7 +183,7 @@ public: CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM); - /// \brief Registers all available module analysis passes. + /// Registers all available module analysis passes. /// /// This is an interface that can be used to populate a \c /// ModuleAnalysisManager with all registered module analyses. Callers can @@ -191,7 +191,7 @@ public: /// pre-register analyses and this will not override those. void registerModuleAnalyses(ModuleAnalysisManager &MAM); - /// \brief Registers all available CGSCC analysis passes. + /// Registers all available CGSCC analysis passes. /// /// This is an interface that can be used to populate a \c CGSCCAnalysisManager /// with all registered CGSCC analyses. Callers can still manually register any @@ -199,7 +199,7 @@ public: /// not override those. void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM); - /// \brief Registers all available function analysis passes. + /// Registers all available function analysis passes. /// /// This is an interface that can be used to populate a \c /// FunctionAnalysisManager with all registered function analyses. Callers can @@ -207,7 +207,7 @@ public: /// pre-register analyses and this will not override those. void registerFunctionAnalyses(FunctionAnalysisManager &FAM); - /// \brief Registers all available loop analysis passes. + /// Registers all available loop analysis passes. /// /// This is an interface that can be used to populate a \c LoopAnalysisManager /// with all registered loop analyses. Callers can still manually register any @@ -346,7 +346,7 @@ public: /// registered. AAManager buildDefaultAAPipeline(); - /// \brief Parse a textual pass pipeline description into a \c + /// Parse a textual pass pipeline description into a \c /// ModulePassManager. /// /// The format of the textual pass pipeline description looks something like: @@ -410,7 +410,7 @@ public: /// returns false. bool parseAAPipeline(AAManager &AA, StringRef PipelineText); - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding passes that perform peephole @@ -421,7 +421,7 @@ public: PeepholeEPCallbacks.push_back(C); } - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding late loop canonicalization and @@ -435,7 +435,7 @@ public: LateLoopOptimizationsEPCallbacks.push_back(C); } - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding loop passes to the end of the loop @@ -445,7 +445,7 @@ public: LoopOptimizerEndEPCallbacks.push_back(C); } - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding optimization passes after most of the @@ -455,7 +455,7 @@ public: ScalarOptimizerLateEPCallbacks.push_back(C); } - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding CallGraphSCC passes at the end of the @@ -466,7 +466,7 @@ public: CGSCCOptimizerLateEPCallbacks.push_back(C); } - /// \brief Register a callback for a default optimizer pipeline extension + /// Register a callback for a default optimizer pipeline extension /// point /// /// This extension point allows adding optimization passes before the @@ -487,7 +487,7 @@ public: PipelineStartEPCallbacks.push_back(C); } - /// \brief Register a callback for parsing an AliasAnalysis Name to populate + /// Register a callback for parsing an AliasAnalysis Name to populate /// the given AAManager \p AA void registerParseAACallback( const std::function &C) { @@ -541,7 +541,7 @@ public: } /// @}} - /// \brief Register a callback for a top-level pipeline entry. + /// Register a callback for a top-level pipeline entry. /// /// If the PassManager type is not given at the top level of the pipeline /// text, this Callback should be used to determine the appropriate stack of diff --git a/include/llvm/Passes/PassPlugin.h b/include/llvm/Passes/PassPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..af8f11a7a352e8dacadc1aeb62d96c76dbd9a30b --- /dev/null +++ b/include/llvm/Passes/PassPlugin.h @@ -0,0 +1,114 @@ +//===- llvm/Passes/PassPlugin.h - Public Plugin API -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines the public entry point for new-PM pass plugins. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_PASSES_PASSPLUGIN_H +#define LLVM_PASSES_PASSPLUGIN_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace llvm { +class PassBuilder; + +/// \macro LLVM_PLUGIN_API_VERSION +/// Identifies the API version understood by this plugin. +/// +/// When a plugin is loaded, the driver will check it's supported plugin version +/// against that of the plugin. A mismatch is an error. The supported version +/// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo +/// struct, i.e. when callbacks are added, removed, or reordered. +#define LLVM_PLUGIN_API_VERSION 1 + +extern "C" { +/// Information about the plugin required to load its passes +/// +/// This struct defines the core interface for pass plugins and is supposed to +/// be filled out by plugin implementors. LLVM-side users of a plugin are +/// expected to use the \c PassPlugin class below to interface with it. +struct PassPluginLibraryInfo { + /// The API version understood by this plugin, usually \c + /// LLVM_PLUGIN_API_VERSION + uint32_t APIVersion; + /// A meaningful name of the plugin. + const char *PluginName; + /// The version of the plugin. + const char *PluginVersion; + + /// The callback for registering plugin passes with a \c PassBuilder + /// instance + void (*RegisterPassBuilderCallbacks)(PassBuilder &); +}; +} + +/// A loaded pass plugin. +/// +/// An instance of this class wraps a loaded pass plugin and gives access to +/// its interface defined by the \c PassPluginLibraryInfo it exposes. +class PassPlugin { +public: + /// Attempts to load a pass plugin from a given file. + /// + /// \returns Returns an error if either the library cannot be found or loaded, + /// there is no public entry point, or the plugin implements the wrong API + /// version. + static Expected Load(const std::string &Filename); + + /// Get the filename of the loaded plugin. + StringRef getFilename() const { return Filename; } + + /// Get the plugin name + StringRef getPluginName() const { return Info.PluginName; } + + /// Get the plugin version + StringRef getPluginVersion() const { return Info.PluginVersion; } + + /// Get the plugin API version + uint32_t getAPIVersion() const { return Info.APIVersion; } + + /// Invoke the PassBuilder callback registration + void registerPassBuilderCallbacks(PassBuilder &PB) const { + Info.RegisterPassBuilderCallbacks(PB); + } + +private: + PassPlugin(const std::string &Filename, const sys::DynamicLibrary &Library) + : Filename(Filename), Library(Library), Info() {} + + std::string Filename; + sys::DynamicLibrary Library; + PassPluginLibraryInfo Info; +}; +} + +/// The public entry point for a pass plugin. +/// +/// When a plugin is loaded by the driver, it will call this entry point to +/// obtain information about this plugin and about how to register its passes. +/// This function needs to be implemented by the plugin, see the example below: +/// +/// ``` +/// extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +/// llvmGetPassPluginInfo() { +/// return { +/// LLVM_PLUGIN_API_VERSION, "MyPlugin", "v0.1", [](PassBuilder &PB) { ... } +/// }; +/// } +/// ``` +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo(); + +#endif /* LLVM_PASSES_PASSPLUGIN_H */ diff --git a/include/llvm/ProfileData/Coverage/CoverageMapping.h b/include/llvm/ProfileData/Coverage/CoverageMapping.h index 5a4098cf666c44cd5847b6f2354ff7c2af8c641c..1ca56dcaf9c5aa8860986c05d52fcc39c3dee9c2 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" @@ -506,7 +507,7 @@ public: /// This is the main interface to get coverage information, using a profile to /// fill out execution counts. class CoverageMapping { - StringSet<> FunctionNames; + DenseMap> RecordProvenance; std::vector Functions; std::vector> FuncHashMismatches; std::vector> FuncCounterMismatches; diff --git a/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index 633e51565cd2a001f0df1d1c1b28f8b4170acd4e..c88c71a6d6f40bc5293486d6061891c27ea2886a 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -32,7 +32,7 @@ namespace coverage { class CoverageMappingReader; -/// \brief Coverage mapping information for a single function. +/// Coverage mapping information for a single function. struct CoverageMappingRecord { StringRef FunctionName; uint64_t FunctionHash; @@ -41,7 +41,7 @@ struct CoverageMappingRecord { ArrayRef MappingRegions; }; -/// \brief A file format agnostic iterator over coverage mapping data. +/// A file format agnostic iterator over coverage mapping data. class CoverageMappingIterator : public std::iterator { CoverageMappingReader *Reader; @@ -101,7 +101,7 @@ public: CoverageMappingIterator end() { return CoverageMappingIterator(); } }; -/// \brief Base class for the raw coverage mapping and filenames data readers. +/// Base class for the raw coverage mapping and filenames data readers. class RawCoverageReader { protected: StringRef Data; @@ -114,7 +114,7 @@ protected: Error readString(StringRef &Result); }; -/// \brief Reader for the raw coverage filenames. +/// Reader for the raw coverage filenames. class RawCoverageFilenamesReader : public RawCoverageReader { std::vector &Filenames; @@ -128,7 +128,7 @@ public: Error read(); }; -/// \brief Checks if the given coverage mapping data is exported for +/// Checks if the given coverage mapping data is exported for /// an unused function. class RawCoverageMappingDummyChecker : public RawCoverageReader { public: @@ -138,7 +138,7 @@ public: Expected isDummy(); }; -/// \brief Reader for the raw coverage mapping data. +/// Reader for the raw coverage mapping data. class RawCoverageMappingReader : public RawCoverageReader { ArrayRef TranslationUnitFilenames; std::vector &Filenames; @@ -169,7 +169,7 @@ private: unsigned InferredFileID, size_t NumFileIDs); }; -/// \brief Reader for the coverage mapping data that is emitted by the +/// Reader for the coverage mapping data that is emitted by the /// frontend and stored in an object file. class BinaryCoverageReader : public CoverageMappingReader { public: diff --git a/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h index b6f864ab3de38f88840ff09d826eb8459ec470d1..86fb1bdf177374a8caa7ca564ef814cc8ddd62f8 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h +++ b/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h @@ -25,7 +25,7 @@ class raw_ostream; namespace coverage { -/// \brief Writer of the filenames section for the instrumentation +/// Writer of the filenames section for the instrumentation /// based code coverage. class CoverageFilenamesSectionWriter { ArrayRef Filenames; @@ -34,11 +34,11 @@ public: CoverageFilenamesSectionWriter(ArrayRef Filenames) : Filenames(Filenames) {} - /// \brief Write encoded filenames to the given output stream. + /// Write encoded filenames to the given output stream. void write(raw_ostream &OS); }; -/// \brief Writer for instrumentation based coverage mapping data. +/// Writer for instrumentation based coverage mapping data. class CoverageMappingWriter { ArrayRef VirtualFileMapping; ArrayRef Expressions; @@ -51,7 +51,7 @@ public: : VirtualFileMapping(VirtualFileMapping), Expressions(Expressions), MappingRegions(MappingRegions) {} - /// \brief Write encoded coverage mapping data to the given output stream. + /// Write encoded coverage mapping data to the given output stream. void write(raw_ostream &OS); }; diff --git a/include/llvm/ProfileData/GCOV.h b/include/llvm/ProfileData/GCOV.h index 497f80b87b2671e21bf49d506d3f3038086c05f7..d9ab39e3946e9c7b7b966f53aeb6b2feb925c806 100644 --- a/include/llvm/ProfileData/GCOV.h +++ b/include/llvm/ProfileData/GCOV.h @@ -41,7 +41,7 @@ namespace GCOV { enum GCOVVersion { V402, V404, V704 }; -/// \brief A struct for passing gcov options between functions. +/// A struct for passing gcov options between functions. struct Options { Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N) : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index 88ae0f05e7db76f688be5e18ee6bd7c9ef85a3c0..dd440c6822b3ccd177849da837d4f57736508376 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -544,9 +544,9 @@ Error InstrProfSymtab::create(const NameIterRange &IterRange) { void InstrProfSymtab::finalizeSymtab() { if (Sorted) return; - std::sort(MD5NameMap.begin(), MD5NameMap.end(), less_first()); - std::sort(MD5FuncMap.begin(), MD5FuncMap.end(), less_first()); - std::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first()); + llvm::sort(MD5NameMap.begin(), MD5NameMap.end(), less_first()); + llvm::sort(MD5FuncMap.begin(), MD5FuncMap.end(), less_first()); + llvm::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first()); AddrToMD5Map.erase(std::unique(AddrToMD5Map.begin(), AddrToMD5Map.end()), AddrToMD5Map.end()); Sorted = true; diff --git a/include/llvm/ProfileData/InstrProfData.inc b/include/llvm/ProfileData/InstrProfData.inc index bac8ccecccd918a6a360ff6b065cc102f8c24465..454620ed997af731f178491b3fdd3b109ee6b03d 100644 --- a/include/llvm/ProfileData/InstrProfData.inc +++ b/include/llvm/ProfileData/InstrProfData.inc @@ -308,11 +308,11 @@ typedef struct ValueProfRecord { #ifdef __cplusplus /*! - * \brief Return the number of value sites. + * Return the number of value sites. */ uint32_t getNumValueSites() const { return NumValueSites; } /*! - * \brief Read data from this record and save it to Record. + * Read data from this record and save it to Record. */ void deserializeTo(InstrProfRecord &Record, InstrProfSymtab *SymTab); @@ -458,7 +458,7 @@ getValueProfRecordHeaderSize(uint32_t NumValueSites); #endif /*! - * \brief Return the \c ValueProfRecord header size including the + * Return the \c ValueProfRecord header size including the * padding bytes. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE @@ -471,7 +471,7 @@ uint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites) { } /*! - * \brief Return the total size of the value profile record including the + * Return the total size of the value profile record including the * header and the value data. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE @@ -482,7 +482,7 @@ uint32_t getValueProfRecordSize(uint32_t NumValueSites, } /*! - * \brief Return the pointer to the start of value data array. + * Return the pointer to the start of value data array. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) { @@ -491,7 +491,7 @@ InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) { } /*! - * \brief Return the total number of value data for \c This record. + * Return the total number of value data for \c This record. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) { @@ -503,7 +503,7 @@ uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) { } /*! - * \brief Use this method to advance to the next \c This \c ValueProfRecord. + * Use this method to advance to the next \c This \c ValueProfRecord. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE ValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) { @@ -514,7 +514,7 @@ ValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) { } /*! - * \brief Return the first \c ValueProfRecord instance. + * Return the first \c ValueProfRecord instance. */ INSTR_PROF_VISIBILITY INSTR_PROF_INLINE ValueProfRecord *getFirstValueProfRecord(ValueProfData *This) { diff --git a/include/llvm/ProfileData/ProfileCommon.h b/include/llvm/ProfileData/ProfileCommon.h index 51b065bcdb70086d1e6dc3ab0abb1b059f11a4dc..087588f06340129466173e1c8720b2a8b7270e78 100644 --- a/include/llvm/ProfileData/ProfileCommon.h +++ b/include/llvm/ProfileData/ProfileCommon.h @@ -61,7 +61,7 @@ protected: void computeDetailedSummary(); public: - /// \brief A vector of useful cutoff values for detailed summary. + /// A vector of useful cutoff values for detailed summary. static const ArrayRef DefaultCutoffs; }; diff --git a/include/llvm/ProfileData/SampleProf.h b/include/llvm/ProfileData/SampleProf.h index d79ef3b3a9b1eadbe87ae78c32b3f90d21cd591f..e5bbf34566e772c460292cd6e51bd2152c6e5d6a 100644 --- a/include/llvm/ProfileData/SampleProf.h +++ b/include/llvm/ProfileData/SampleProf.h @@ -387,7 +387,7 @@ public: /// We assume that a single function will not exceed 65535 LOC. static unsigned getOffset(const DILocation *DIL); - /// \brief Get the FunctionSamples of the inline instance where DIL originates + /// Get the FunctionSamples of the inline instance where DIL originates /// from. /// /// The FunctionSamples of the instruction (Machine or IR) associated to diff --git a/include/llvm/ProfileData/SampleProfReader.h b/include/llvm/ProfileData/SampleProfReader.h index 0e9ab2dc60ee1172369278ac9729c9b86d431f49..f1ef76af0e7a5e02c8f666d86ed7fa1ad6b3b8a2 100644 --- a/include/llvm/ProfileData/SampleProfReader.h +++ b/include/llvm/ProfileData/SampleProfReader.h @@ -235,7 +235,7 @@ class raw_ostream; namespace sampleprof { -/// \brief Sample-based profile reader. +/// Sample-based profile reader. /// /// Each profile contains sample counts for all the functions /// executed. Inside each function, statements are annotated with the @@ -269,19 +269,19 @@ public: virtual ~SampleProfileReader() = default; - /// \brief Read and validate the file header. + /// Read and validate the file header. virtual std::error_code readHeader() = 0; - /// \brief Read sample profiles from the associated file. + /// Read sample profiles from the associated file. virtual std::error_code read() = 0; - /// \brief Print the profile for \p FName on stream \p OS. + /// Print the profile for \p FName on stream \p OS. void dumpFunctionProfile(StringRef FName, raw_ostream &OS = dbgs()); - /// \brief Print all the profiles on stream \p OS. + /// Print all the profiles on stream \p OS. void dump(raw_ostream &OS = dbgs()); - /// \brief Return the samples collected for function \p F. + /// Return the samples collected for function \p F. FunctionSamples *getSamplesFor(const Function &F) { // The function name may have been updated by adding suffix. In sample // profile, the function names are all stripped, so we need to strip @@ -291,44 +291,44 @@ public: return nullptr; } - /// \brief Return all the profiles. + /// Return all the profiles. StringMap &getProfiles() { return Profiles; } - /// \brief Report a parse error message. + /// Report a parse error message. void reportError(int64_t LineNumber, Twine Msg) const { Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(), LineNumber, Msg)); } - /// \brief Create a sample profile reader appropriate to the file format. + /// Create a sample profile reader appropriate to the file format. static ErrorOr> create(const Twine &Filename, LLVMContext &C); - /// \brief Create a sample profile reader from the supplied memory buffer. + /// Create a sample profile reader from the supplied memory buffer. static ErrorOr> create(std::unique_ptr &B, LLVMContext &C); - /// \brief Return the profile summary. + /// Return the profile summary. ProfileSummary &getSummary() { return *(Summary.get()); } protected: - /// \brief Map every function to its associated profile. + /// Map every function to its associated profile. /// /// The profile of every function executed at runtime is collected /// in the structure FunctionSamples. This maps function objects /// to their corresponding profiles. StringMap Profiles; - /// \brief LLVM context used to emit diagnostics. + /// LLVM context used to emit diagnostics. LLVMContext &Ctx; - /// \brief Memory buffer holding the profile file. + /// Memory buffer holding the profile file. std::unique_ptr Buffer; - /// \brief Profile summary information. + /// Profile summary information. std::unique_ptr Summary; - /// \brief Compute summary for this profile. + /// Compute summary for this profile. void computeSummary(); }; @@ -337,13 +337,13 @@ public: SampleProfileReaderText(std::unique_ptr B, LLVMContext &C) : SampleProfileReader(std::move(B), C) {} - /// \brief Read and validate the file header. + /// Read and validate the file header. std::error_code readHeader() override { return sampleprof_error::success; } - /// \brief Read sample profiles from the associated file. + /// Read sample profiles from the associated file. std::error_code read() override; - /// \brief Return true if \p Buffer is in the format supported by this class. + /// Return true if \p Buffer is in the format supported by this class. static bool hasFormat(const MemoryBuffer &Buffer); }; @@ -352,17 +352,17 @@ public: SampleProfileReaderBinary(std::unique_ptr B, LLVMContext &C) : SampleProfileReader(std::move(B), C) {} - /// \brief Read and validate the file header. + /// Read and validate the file header. std::error_code readHeader() override; - /// \brief Read sample profiles from the associated file. + /// Read sample profiles from the associated file. std::error_code read() override; - /// \brief Return true if \p Buffer is in the format supported by this class. + /// Return true if \p Buffer is in the format supported by this class. static bool hasFormat(const MemoryBuffer &Buffer); protected: - /// \brief Read a numeric value of type T from the profile. + /// Read a numeric value of type T from the profile. /// /// If an error occurs during decoding, a diagnostic message is emitted and /// EC is set. @@ -370,7 +370,7 @@ protected: /// \returns the read value. template ErrorOr readNumber(); - /// \brief Read a string from the profile. + /// Read a string from the profile. /// /// If an error occurs during decoding, a diagnostic message is emitted and /// EC is set. @@ -381,16 +381,16 @@ protected: /// Read a string indirectly via the name table. ErrorOr readStringFromTable(); - /// \brief Return true if we've reached the end of file. + /// Return true if we've reached the end of file. bool at_eof() const { return Data >= End; } /// Read the contents of the given profile instance. std::error_code readProfile(FunctionSamples &FProfile); - /// \brief Points to the current location in the buffer. + /// Points to the current location in the buffer. const uint8_t *Data = nullptr; - /// \brief Points to the end of the buffer. + /// Points to the end of the buffer. const uint8_t *End = nullptr; /// Function name table. @@ -399,7 +399,7 @@ protected: private: std::error_code readSummaryEntry(std::vector &Entries); - /// \brief Read profile summary. + /// Read profile summary. std::error_code readSummary(); }; @@ -423,13 +423,13 @@ public: SampleProfileReaderGCC(std::unique_ptr B, LLVMContext &C) : SampleProfileReader(std::move(B), C), GcovBuffer(Buffer.get()) {} - /// \brief Read and validate the file header. + /// Read and validate the file header. std::error_code readHeader() override; - /// \brief Read sample profiles from the associated file. + /// Read sample profiles from the associated file. std::error_code read() override; - /// \brief Return true if \p Buffer is in the format supported by this class. + /// Return true if \p Buffer is in the format supported by this class. static bool hasFormat(const MemoryBuffer &Buffer); protected: @@ -441,7 +441,7 @@ protected: template ErrorOr readNumber(); ErrorOr readString(); - /// \brief Read the section tag and check that it's the same as \p Expected. + /// Read the section tag and check that it's the same as \p Expected. std::error_code readSectionTag(uint32_t Expected); /// GCOV buffer containing the profile. diff --git a/include/llvm/ProfileData/SampleProfWriter.h b/include/llvm/ProfileData/SampleProfWriter.h index 86af1038d74e42c2a95d7b62824dc5c1a4e1f2e3..3c5293f13e5f8546a3341e70b47013939afc130f 100644 --- a/include/llvm/ProfileData/SampleProfWriter.h +++ b/include/llvm/ProfileData/SampleProfWriter.h @@ -30,7 +30,7 @@ namespace sampleprof { enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC }; -/// \brief Sample-based profile writer. Base class. +/// Sample-based profile writer. Base class. class SampleProfileWriter { public: virtual ~SampleProfileWriter() = default; @@ -62,21 +62,21 @@ protected: SampleProfileWriter(std::unique_ptr &OS) : OutputStream(std::move(OS)) {} - /// \brief Write a file header for the profile file. + /// Write a file header for the profile file. virtual std::error_code writeHeader(const StringMap &ProfileMap) = 0; - /// \brief Output stream where to emit the profile to. + /// Output stream where to emit the profile to. std::unique_ptr OutputStream; - /// \brief Profile summary. + /// Profile summary. std::unique_ptr Summary; - /// \brief Compute summary for this profile. + /// Compute summary for this profile. void computeSummary(const StringMap &ProfileMap); }; -/// \brief Sample-based profile writer (text format). +/// Sample-based profile writer (text format). class SampleProfileWriterText : public SampleProfileWriter { public: std::error_code write(const FunctionSamples &S) override; @@ -101,7 +101,7 @@ private: SampleProfileFormat Format); }; -/// \brief Sample-based profile writer (binary format). +/// Sample-based profile writer (binary format). class SampleProfileWriterBinary : public SampleProfileWriter { public: std::error_code write(const FunctionSamples &S) override; diff --git a/include/llvm/Support/AMDGPUKernelDescriptor.h b/include/llvm/Support/AMDGPUKernelDescriptor.h index ce2c0c1c959eba1fe0370ffcc4f31aeca486e7e0..496799bca2393fb99ed460e6ac1c5b74e6459b52 100644 --- a/include/llvm/Support/AMDGPUKernelDescriptor.h +++ b/include/llvm/Support/AMDGPUKernelDescriptor.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // /// \file -/// \brief AMDGPU kernel descriptor definitions. For more information, visit +/// AMDGPU kernel descriptor definitions. For more information, visit /// https://llvm.org/docs/AMDGPUUsage.html#kernel-descriptor-for-gfx6-gfx9 // //===----------------------------------------------------------------------===// @@ -38,7 +38,7 @@ namespace llvm { namespace AMDGPU { namespace HSAKD { -/// \brief Floating point rounding modes. +/// Floating point rounding modes. enum : uint8_t { AMDGPU_FLOAT_ROUND_MODE_NEAR_EVEN = 0, AMDGPU_FLOAT_ROUND_MODE_PLUS_INFINITY = 1, @@ -46,7 +46,7 @@ enum : uint8_t { AMDGPU_FLOAT_ROUND_MODE_ZERO = 3, }; -/// \brief Floating point denorm modes. +/// Floating point denorm modes. enum : uint8_t { AMDGPU_FLOAT_DENORM_MODE_FLUSH_SRC_DST = 0, AMDGPU_FLOAT_DENORM_MODE_FLUSH_DST = 1, @@ -54,7 +54,7 @@ enum : uint8_t { AMDGPU_FLOAT_DENORM_MODE_FLUSH_NONE = 3, }; -/// \brief System VGPR workitem IDs. +/// System VGPR workitem IDs. enum : uint8_t { AMDGPU_SYSTEM_VGPR_WORKITEM_ID_X = 0, AMDGPU_SYSTEM_VGPR_WORKITEM_ID_X_Y = 1, @@ -62,7 +62,7 @@ enum : uint8_t { AMDGPU_SYSTEM_VGPR_WORKITEM_ID_UNDEFINED = 3, }; -/// \brief Compute program resource register one layout. +/// Compute program resource register one layout. enum ComputePgmRsrc1 { AMDGPU_BITS_ENUM_ENTRY(GRANULATED_WORKITEM_VGPR_COUNT, 0, 6), AMDGPU_BITS_ENUM_ENTRY(GRANULATED_WAVEFRONT_SGPR_COUNT, 6, 4), @@ -81,7 +81,7 @@ enum ComputePgmRsrc1 { AMDGPU_BITS_ENUM_ENTRY(RESERVED0, 27, 5), }; -/// \brief Compute program resource register two layout. +/// Compute program resource register two layout. enum ComputePgmRsrc2 { AMDGPU_BITS_ENUM_ENTRY(ENABLE_SGPR_PRIVATE_SEGMENT_WAVE_OFFSET, 0, 1), AMDGPU_BITS_ENUM_ENTRY(USER_SGPR_COUNT, 1, 5), @@ -104,7 +104,7 @@ enum ComputePgmRsrc2 { AMDGPU_BITS_ENUM_ENTRY(RESERVED1, 31, 1), }; -/// \brief Kernel descriptor layout. This layout should be kept backwards +/// Kernel descriptor layout. This layout should be kept backwards /// compatible as it is consumed by the command processor. struct KernelDescriptor final { uint32_t GroupSegmentFixedSize; diff --git a/include/llvm/Support/AMDGPUMetadata.h b/include/llvm/Support/AMDGPUMetadata.h index 00039a75c51d4e3b541dcb3d4e1011d1a964c3c4..667fb3f3da436c146eac3453293cc601060581c2 100644 --- a/include/llvm/Support/AMDGPUMetadata.h +++ b/include/llvm/Support/AMDGPUMetadata.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // /// \file -/// \brief AMDGPU metadata definitions and in-memory representations. +/// AMDGPU metadata definitions and in-memory representations. /// // //===----------------------------------------------------------------------===// @@ -29,17 +29,17 @@ namespace AMDGPU { //===----------------------------------------------------------------------===// namespace HSAMD { -/// \brief HSA metadata major version. +/// HSA metadata major version. constexpr uint32_t VersionMajor = 1; -/// \brief HSA metadata minor version. +/// HSA metadata minor version. constexpr uint32_t VersionMinor = 0; -/// \brief HSA metadata beginning assembler directive. +/// HSA metadata beginning assembler directive. constexpr char AssemblerDirectiveBegin[] = ".amd_amdgpu_hsa_metadata"; -/// \brief HSA metadata ending assembler directive. +/// HSA metadata ending assembler directive. constexpr char AssemblerDirectiveEnd[] = ".end_amd_amdgpu_hsa_metadata"; -/// \brief Access qualifiers. +/// Access qualifiers. enum class AccessQualifier : uint8_t { Default = 0, ReadOnly = 1, @@ -48,7 +48,7 @@ enum class AccessQualifier : uint8_t { Unknown = 0xff }; -/// \brief Address space qualifiers. +/// Address space qualifiers. enum class AddressSpaceQualifier : uint8_t { Private = 0, Global = 1, @@ -59,7 +59,7 @@ enum class AddressSpaceQualifier : uint8_t { Unknown = 0xff }; -/// \brief Value kinds. +/// Value kinds. enum class ValueKind : uint8_t { ByValue = 0, GlobalBuffer = 1, @@ -78,7 +78,7 @@ enum class ValueKind : uint8_t { Unknown = 0xff }; -/// \brief Value types. +/// Value types. enum class ValueType : uint8_t { Struct = 0, I8 = 1, @@ -106,29 +106,29 @@ namespace Kernel { namespace Attrs { namespace Key { -/// \brief Key for Kernel::Attr::Metadata::mReqdWorkGroupSize. +/// Key for Kernel::Attr::Metadata::mReqdWorkGroupSize. constexpr char ReqdWorkGroupSize[] = "ReqdWorkGroupSize"; -/// \brief Key for Kernel::Attr::Metadata::mWorkGroupSizeHint. +/// Key for Kernel::Attr::Metadata::mWorkGroupSizeHint. constexpr char WorkGroupSizeHint[] = "WorkGroupSizeHint"; -/// \brief Key for Kernel::Attr::Metadata::mVecTypeHint. +/// Key for Kernel::Attr::Metadata::mVecTypeHint. constexpr char VecTypeHint[] = "VecTypeHint"; -/// \brief Key for Kernel::Attr::Metadata::mRuntimeHandle. +/// Key for Kernel::Attr::Metadata::mRuntimeHandle. constexpr char RuntimeHandle[] = "RuntimeHandle"; } // end namespace Key -/// \brief In-memory representation of kernel attributes metadata. +/// In-memory representation of kernel attributes metadata. struct Metadata final { - /// \brief 'reqd_work_group_size' attribute. Optional. + /// 'reqd_work_group_size' attribute. Optional. std::vector mReqdWorkGroupSize = std::vector(); - /// \brief 'work_group_size_hint' attribute. Optional. + /// 'work_group_size_hint' attribute. Optional. std::vector mWorkGroupSizeHint = std::vector(); - /// \brief 'vec_type_hint' attribute. Optional. + /// 'vec_type_hint' attribute. Optional. std::string mVecTypeHint = std::string(); - /// \brief External symbol created by runtime to store the kernel address + /// External symbol created by runtime to store the kernel address /// for enqueued blocks. std::string mRuntimeHandle = std::string(); - /// \brief Default constructor. + /// Default constructor. Metadata() = default; /// \returns True if kernel attributes metadata is empty, false otherwise. @@ -151,68 +151,68 @@ struct Metadata final { namespace Arg { namespace Key { -/// \brief Key for Kernel::Arg::Metadata::mName. +/// Key for Kernel::Arg::Metadata::mName. constexpr char Name[] = "Name"; -/// \brief Key for Kernel::Arg::Metadata::mTypeName. +/// Key for Kernel::Arg::Metadata::mTypeName. constexpr char TypeName[] = "TypeName"; -/// \brief Key for Kernel::Arg::Metadata::mSize. +/// Key for Kernel::Arg::Metadata::mSize. constexpr char Size[] = "Size"; -/// \brief Key for Kernel::Arg::Metadata::mAlign. +/// Key for Kernel::Arg::Metadata::mAlign. constexpr char Align[] = "Align"; -/// \brief Key for Kernel::Arg::Metadata::mValueKind. +/// Key for Kernel::Arg::Metadata::mValueKind. constexpr char ValueKind[] = "ValueKind"; -/// \brief Key for Kernel::Arg::Metadata::mValueType. +/// Key for Kernel::Arg::Metadata::mValueType. constexpr char ValueType[] = "ValueType"; -/// \brief Key for Kernel::Arg::Metadata::mPointeeAlign. +/// Key for Kernel::Arg::Metadata::mPointeeAlign. constexpr char PointeeAlign[] = "PointeeAlign"; -/// \brief Key for Kernel::Arg::Metadata::mAddrSpaceQual. +/// Key for Kernel::Arg::Metadata::mAddrSpaceQual. constexpr char AddrSpaceQual[] = "AddrSpaceQual"; -/// \brief Key for Kernel::Arg::Metadata::mAccQual. +/// Key for Kernel::Arg::Metadata::mAccQual. constexpr char AccQual[] = "AccQual"; -/// \brief Key for Kernel::Arg::Metadata::mActualAccQual. +/// Key for Kernel::Arg::Metadata::mActualAccQual. constexpr char ActualAccQual[] = "ActualAccQual"; -/// \brief Key for Kernel::Arg::Metadata::mIsConst. +/// Key for Kernel::Arg::Metadata::mIsConst. constexpr char IsConst[] = "IsConst"; -/// \brief Key for Kernel::Arg::Metadata::mIsRestrict. +/// Key for Kernel::Arg::Metadata::mIsRestrict. constexpr char IsRestrict[] = "IsRestrict"; -/// \brief Key for Kernel::Arg::Metadata::mIsVolatile. +/// Key for Kernel::Arg::Metadata::mIsVolatile. constexpr char IsVolatile[] = "IsVolatile"; -/// \brief Key for Kernel::Arg::Metadata::mIsPipe. +/// Key for Kernel::Arg::Metadata::mIsPipe. constexpr char IsPipe[] = "IsPipe"; } // end namespace Key -/// \brief In-memory representation of kernel argument metadata. +/// In-memory representation of kernel argument metadata. struct Metadata final { - /// \brief Name. Optional. + /// Name. Optional. std::string mName = std::string(); - /// \brief Type name. Optional. + /// Type name. Optional. std::string mTypeName = std::string(); - /// \brief Size in bytes. Required. + /// Size in bytes. Required. uint32_t mSize = 0; - /// \brief Alignment in bytes. Required. + /// Alignment in bytes. Required. uint32_t mAlign = 0; - /// \brief Value kind. Required. + /// Value kind. Required. ValueKind mValueKind = ValueKind::Unknown; - /// \brief Value type. Required. + /// Value type. Required. ValueType mValueType = ValueType::Unknown; - /// \brief Pointee alignment in bytes. Optional. + /// Pointee alignment in bytes. Optional. uint32_t mPointeeAlign = 0; - /// \brief Address space qualifier. Optional. + /// Address space qualifier. Optional. AddressSpaceQualifier mAddrSpaceQual = AddressSpaceQualifier::Unknown; - /// \brief Access qualifier. Optional. + /// Access qualifier. Optional. AccessQualifier mAccQual = AccessQualifier::Unknown; - /// \brief Actual access qualifier. Optional. + /// Actual access qualifier. Optional. AccessQualifier mActualAccQual = AccessQualifier::Unknown; - /// \brief True if 'const' qualifier is specified. Optional. + /// True if 'const' qualifier is specified. Optional. bool mIsConst = false; - /// \brief True if 'restrict' qualifier is specified. Optional. + /// True if 'restrict' qualifier is specified. Optional. bool mIsRestrict = false; - /// \brief True if 'volatile' qualifier is specified. Optional. + /// True if 'volatile' qualifier is specified. Optional. bool mIsVolatile = false; - /// \brief True if 'pipe' qualifier is specified. Optional. + /// True if 'pipe' qualifier is specified. Optional. bool mIsPipe = false; - /// \brief Default constructor. + /// Default constructor. Metadata() = default; }; @@ -224,67 +224,67 @@ struct Metadata final { namespace CodeProps { namespace Key { -/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentSize. +/// Key for Kernel::CodeProps::Metadata::mKernargSegmentSize. constexpr char KernargSegmentSize[] = "KernargSegmentSize"; -/// \brief Key for Kernel::CodeProps::Metadata::mGroupSegmentFixedSize. +/// Key for Kernel::CodeProps::Metadata::mGroupSegmentFixedSize. constexpr char GroupSegmentFixedSize[] = "GroupSegmentFixedSize"; -/// \brief Key for Kernel::CodeProps::Metadata::mPrivateSegmentFixedSize. +/// Key for Kernel::CodeProps::Metadata::mPrivateSegmentFixedSize. constexpr char PrivateSegmentFixedSize[] = "PrivateSegmentFixedSize"; -/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign. +/// Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign. constexpr char KernargSegmentAlign[] = "KernargSegmentAlign"; -/// \brief Key for Kernel::CodeProps::Metadata::mWavefrontSize. +/// Key for Kernel::CodeProps::Metadata::mWavefrontSize. constexpr char WavefrontSize[] = "WavefrontSize"; -/// \brief Key for Kernel::CodeProps::Metadata::mNumSGPRs. +/// Key for Kernel::CodeProps::Metadata::mNumSGPRs. constexpr char NumSGPRs[] = "NumSGPRs"; -/// \brief Key for Kernel::CodeProps::Metadata::mNumVGPRs. +/// Key for Kernel::CodeProps::Metadata::mNumVGPRs. constexpr char NumVGPRs[] = "NumVGPRs"; -/// \brief Key for Kernel::CodeProps::Metadata::mMaxFlatWorkGroupSize. +/// Key for Kernel::CodeProps::Metadata::mMaxFlatWorkGroupSize. constexpr char MaxFlatWorkGroupSize[] = "MaxFlatWorkGroupSize"; -/// \brief Key for Kernel::CodeProps::Metadata::mIsDynamicCallStack. +/// Key for Kernel::CodeProps::Metadata::mIsDynamicCallStack. constexpr char IsDynamicCallStack[] = "IsDynamicCallStack"; -/// \brief Key for Kernel::CodeProps::Metadata::mIsXNACKEnabled. +/// Key for Kernel::CodeProps::Metadata::mIsXNACKEnabled. constexpr char IsXNACKEnabled[] = "IsXNACKEnabled"; -/// \brief Key for Kernel::CodeProps::Metadata::mNumSpilledSGPRs. +/// Key for Kernel::CodeProps::Metadata::mNumSpilledSGPRs. constexpr char NumSpilledSGPRs[] = "NumSpilledSGPRs"; -/// \brief Key for Kernel::CodeProps::Metadata::mNumSpilledVGPRs. +/// Key for Kernel::CodeProps::Metadata::mNumSpilledVGPRs. constexpr char NumSpilledVGPRs[] = "NumSpilledVGPRs"; } // end namespace Key -/// \brief In-memory representation of kernel code properties metadata. +/// In-memory representation of kernel code properties metadata. struct Metadata final { - /// \brief Size in bytes of the kernarg segment memory. Kernarg segment memory + /// Size in bytes of the kernarg segment memory. Kernarg segment memory /// holds the values of the arguments to the kernel. Required. uint64_t mKernargSegmentSize = 0; - /// \brief Size in bytes of the group segment memory required by a workgroup. + /// Size in bytes of the group segment memory required by a workgroup. /// This value does not include any dynamically allocated group segment memory /// that may be added when the kernel is dispatched. Required. uint32_t mGroupSegmentFixedSize = 0; - /// \brief Size in bytes of the private segment memory required by a workitem. + /// Size in bytes of the private segment memory required by a workitem. /// Private segment memory includes arg, spill and private segments. Required. uint32_t mPrivateSegmentFixedSize = 0; - /// \brief Maximum byte alignment of variables used by the kernel in the + /// Maximum byte alignment of variables used by the kernel in the /// kernarg memory segment. Required. uint32_t mKernargSegmentAlign = 0; - /// \brief Wavefront size. Required. + /// Wavefront size. Required. uint32_t mWavefrontSize = 0; - /// \brief Total number of SGPRs used by a wavefront. Optional. + /// Total number of SGPRs used by a wavefront. Optional. uint16_t mNumSGPRs = 0; - /// \brief Total number of VGPRs used by a workitem. Optional. + /// Total number of VGPRs used by a workitem. Optional. uint16_t mNumVGPRs = 0; - /// \brief Maximum flat work-group size supported by the kernel. Optional. + /// Maximum flat work-group size supported by the kernel. Optional. uint32_t mMaxFlatWorkGroupSize = 0; - /// \brief True if the generated machine code is using a dynamically sized + /// True if the generated machine code is using a dynamically sized /// call stack. Optional. bool mIsDynamicCallStack = false; - /// \brief True if the generated machine code is capable of supporting XNACK. + /// True if the generated machine code is capable of supporting XNACK. /// Optional. bool mIsXNACKEnabled = false; - /// \brief Number of SGPRs spilled by a wavefront. Optional. + /// Number of SGPRs spilled by a wavefront. Optional. uint16_t mNumSpilledSGPRs = 0; - /// \brief Number of VGPRs spilled by a workitem. Optional. + /// Number of VGPRs spilled by a workitem. Optional. uint16_t mNumSpilledVGPRs = 0; - /// \brief Default constructor. + /// Default constructor. Metadata() = default; /// \returns True if kernel code properties metadata is empty, false @@ -308,40 +308,40 @@ struct Metadata final { namespace DebugProps { namespace Key { -/// \brief Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion. +/// Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion. constexpr char DebuggerABIVersion[] = "DebuggerABIVersion"; -/// \brief Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs. +/// Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs. constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs"; -/// \brief Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR. +/// Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR. constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR"; -/// \brief Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR. +/// Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR. constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR"; -/// \brief Key for +/// Key for /// Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR. constexpr char WavefrontPrivateSegmentOffsetSGPR[] = "WavefrontPrivateSegmentOffsetSGPR"; } // end namespace Key -/// \brief In-memory representation of kernel debug properties metadata. +/// In-memory representation of kernel debug properties metadata. struct Metadata final { - /// \brief Debugger ABI version. Optional. + /// Debugger ABI version. Optional. std::vector mDebuggerABIVersion = std::vector(); - /// \brief Consecutive number of VGPRs reserved for debugger use. Must be 0 if + /// Consecutive number of VGPRs reserved for debugger use. Must be 0 if /// mDebuggerABIVersion is not set. Optional. uint16_t mReservedNumVGPRs = 0; - /// \brief First fixed VGPR reserved. Must be uint16_t(-1) if + /// First fixed VGPR reserved. Must be uint16_t(-1) if /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional. uint16_t mReservedFirstVGPR = uint16_t(-1); - /// \brief Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used + /// Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used /// for the entire kernel execution. Must be uint16_t(-1) if /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional. uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1); - /// \brief Fixed SGPR used to hold the wave scratch offset for the entire + /// Fixed SGPR used to hold the wave scratch offset for the entire /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set /// or SGPR is not used or not known. Optional. uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1); - /// \brief Default constructor. + /// Default constructor. Metadata() = default; /// \returns True if kernel debug properties metadata is empty, false @@ -360,75 +360,75 @@ struct Metadata final { } // end namespace DebugProps namespace Key { -/// \brief Key for Kernel::Metadata::mName. +/// Key for Kernel::Metadata::mName. constexpr char Name[] = "Name"; -/// \brief Key for Kernel::Metadata::mSymbolName. +/// Key for Kernel::Metadata::mSymbolName. constexpr char SymbolName[] = "SymbolName"; -/// \brief Key for Kernel::Metadata::mLanguage. +/// Key for Kernel::Metadata::mLanguage. constexpr char Language[] = "Language"; -/// \brief Key for Kernel::Metadata::mLanguageVersion. +/// Key for Kernel::Metadata::mLanguageVersion. constexpr char LanguageVersion[] = "LanguageVersion"; -/// \brief Key for Kernel::Metadata::mAttrs. +/// Key for Kernel::Metadata::mAttrs. constexpr char Attrs[] = "Attrs"; -/// \brief Key for Kernel::Metadata::mArgs. +/// Key for Kernel::Metadata::mArgs. constexpr char Args[] = "Args"; -/// \brief Key for Kernel::Metadata::mCodeProps. +/// Key for Kernel::Metadata::mCodeProps. constexpr char CodeProps[] = "CodeProps"; -/// \brief Key for Kernel::Metadata::mDebugProps. +/// Key for Kernel::Metadata::mDebugProps. constexpr char DebugProps[] = "DebugProps"; } // end namespace Key -/// \brief In-memory representation of kernel metadata. +/// In-memory representation of kernel metadata. struct Metadata final { - /// \brief Kernel source name. Required. + /// Kernel source name. Required. std::string mName = std::string(); - /// \brief Kernel descriptor name. Required. + /// Kernel descriptor name. Required. std::string mSymbolName = std::string(); - /// \brief Language. Optional. + /// Language. Optional. std::string mLanguage = std::string(); - /// \brief Language version. Optional. + /// Language version. Optional. std::vector mLanguageVersion = std::vector(); - /// \brief Attributes metadata. Optional. + /// Attributes metadata. Optional. Attrs::Metadata mAttrs = Attrs::Metadata(); - /// \brief Arguments metadata. Optional. + /// Arguments metadata. Optional. std::vector mArgs = std::vector(); - /// \brief Code properties metadata. Optional. + /// Code properties metadata. Optional. CodeProps::Metadata mCodeProps = CodeProps::Metadata(); - /// \brief Debug properties metadata. Optional. + /// Debug properties metadata. Optional. DebugProps::Metadata mDebugProps = DebugProps::Metadata(); - /// \brief Default constructor. + /// Default constructor. Metadata() = default; }; } // end namespace Kernel namespace Key { -/// \brief Key for HSA::Metadata::mVersion. +/// Key for HSA::Metadata::mVersion. constexpr char Version[] = "Version"; -/// \brief Key for HSA::Metadata::mPrintf. +/// Key for HSA::Metadata::mPrintf. constexpr char Printf[] = "Printf"; -/// \brief Key for HSA::Metadata::mKernels. +/// Key for HSA::Metadata::mKernels. constexpr char Kernels[] = "Kernels"; } // end namespace Key -/// \brief In-memory representation of HSA metadata. +/// In-memory representation of HSA metadata. struct Metadata final { - /// \brief HSA metadata version. Required. + /// HSA metadata version. Required. std::vector mVersion = std::vector(); - /// \brief Printf metadata. Optional. + /// Printf metadata. Optional. std::vector mPrintf = std::vector(); - /// \brief Kernels metadata. Required. + /// Kernels metadata. Required. std::vector mKernels = std::vector(); - /// \brief Default constructor. + /// Default constructor. Metadata() = default; }; -/// \brief Converts \p String to \p HSAMetadata. +/// Converts \p String to \p HSAMetadata. std::error_code fromString(std::string String, Metadata &HSAMetadata); -/// \brief Converts \p HSAMetadata to \p String. +/// Converts \p HSAMetadata to \p String. std::error_code toString(Metadata HSAMetadata, std::string &String); } // end namespace HSAMD @@ -438,10 +438,10 @@ std::error_code toString(Metadata HSAMetadata, std::string &String); //===----------------------------------------------------------------------===// namespace PALMD { -/// \brief PAL metadata assembler directive. +/// PAL metadata assembler directive. constexpr char AssemblerDirective[] = ".amd_amdgpu_pal_metadata"; -/// \brief PAL metadata keys. +/// PAL metadata keys. enum Key : uint32_t { LS_NUM_USED_VGPRS = 0x10000021, HS_NUM_USED_VGPRS = 0x10000022, @@ -468,10 +468,10 @@ enum Key : uint32_t { CS_SCRATCH_SIZE = 0x1000004a }; -/// \brief PAL metadata represented as a vector. +/// PAL metadata represented as a vector. typedef std::vector Metadata; -/// \brief Converts \p PALMetadata to \p String. +/// Converts \p PALMetadata to \p String. std::error_code toString(const Metadata &PALMetadata, std::string &String); } // end namespace PALMD diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index abd19afa22f062de6c7089942a6d7f1dedd7500f..5186ce0dc25ce3680a0ac2f6120f10f5dfbbd633 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -20,7 +20,7 @@ namespace llvm { /// \struct AlignedCharArray -/// \brief Helper for building an aligned character array type. +/// Helper for building an aligned character array type. /// /// This template is used to explicitly build up a collection of aligned /// character array types. We have to build these up using a macro and explicit @@ -39,7 +39,7 @@ struct AlignedCharArray { #else // _MSC_VER -/// \brief Create a type with an aligned char buffer. +/// Create a type with an aligned char buffer. template struct AlignedCharArray; @@ -124,7 +124,7 @@ union SizerImpl { }; } // end namespace detail -/// \brief This union template exposes a suitably aligned and sized character +/// This union template exposes a suitably aligned and sized character /// array member which can hold elements of any of up to ten types. /// /// These types may be arrays, structs, or any other types. The goal is to diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index 8ed4109c6fa5e2f9835c99e515c171defd89074c..866cad56348c0e21a485768a1e143379572d8145 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -36,7 +36,7 @@ namespace llvm { -/// \brief CRTP base class providing obvious overloads for the core \c +/// CRTP base class providing obvious overloads for the core \c /// Allocate() methods of LLVM-style allocators. /// /// This base class both documents the full public interface exposed by all @@ -44,7 +44,7 @@ namespace llvm { /// set of methods which the derived class must define. template class AllocatorBase { public: - /// \brief Allocate \a Size bytes of \a Alignment aligned memory. This method + /// Allocate \a Size bytes of \a Alignment aligned memory. This method /// must be implemented by \c DerivedT. void *Allocate(size_t Size, size_t Alignment) { #ifdef __clang__ @@ -58,7 +58,7 @@ public: return static_cast(this)->Allocate(Size, Alignment); } - /// \brief Deallocate \a Ptr to \a Size bytes of memory allocated by this + /// Deallocate \a Ptr to \a Size bytes of memory allocated by this /// allocator. void Deallocate(const void *Ptr, size_t Size) { #ifdef __clang__ @@ -75,12 +75,12 @@ public: // The rest of these methods are helpers that redirect to one of the above // core methods. - /// \brief Allocate space for a sequence of objects without constructing them. + /// Allocate space for a sequence of objects without constructing them. template T *Allocate(size_t Num = 1) { return static_cast(Allocate(Num * sizeof(T), alignof(T))); } - /// \brief Deallocate space for a sequence of objects without constructing them. + /// Deallocate space for a sequence of objects without constructing them. template typename std::enable_if< !std::is_same::type, void>::value, void>::type @@ -124,7 +124,7 @@ void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated, } // end namespace detail -/// \brief Allocate memory in an ever growing pool, as if by bump-pointer. +/// Allocate memory in an ever growing pool, as if by bump-pointer. /// /// This isn't strictly a bump-pointer allocator as it uses backing slabs of /// memory rather than relying on a boundless contiguous heap. However, it has @@ -192,7 +192,7 @@ public: return *this; } - /// \brief Deallocate all but the current slab and reset the current pointer + /// Deallocate all but the current slab and reset the current pointer /// to the beginning of it, freeing all memory allocated so far. void Reset() { // Deallocate all but the first slab, and deallocate all custom-sized slabs. @@ -212,7 +212,7 @@ public: Slabs.erase(std::next(Slabs.begin()), Slabs.end()); } - /// \brief Allocate space at the specified alignment. + /// Allocate space at the specified alignment. LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment) { assert(Alignment > 0 && "0-byte alignnment is not allowed. Use 1 instead."); @@ -307,30 +307,30 @@ public: } private: - /// \brief The current pointer into the current slab. + /// The current pointer into the current slab. /// /// This points to the next free byte in the slab. char *CurPtr = nullptr; - /// \brief The end of the current slab. + /// The end of the current slab. char *End = nullptr; - /// \brief The slabs allocated so far. + /// The slabs allocated so far. SmallVector Slabs; - /// \brief Custom-sized slabs allocated for too-large allocation requests. + /// Custom-sized slabs allocated for too-large allocation requests. SmallVector, 0> CustomSizedSlabs; - /// \brief How many bytes we've allocated. + /// How many bytes we've allocated. /// /// Used so that we can compute how much space was wasted. size_t BytesAllocated = 0; - /// \brief The number of bytes to put between allocations when running under + /// The number of bytes to put between allocations when running under /// a sanitizer. size_t RedZoneSize = 1; - /// \brief The allocator instance we use to get slabs of memory. + /// The allocator instance we use to get slabs of memory. AllocatorT Allocator; static size_t computeSlabSize(unsigned SlabIdx) { @@ -341,7 +341,7 @@ private: return SlabSize * ((size_t)1 << std::min(30, SlabIdx / 128)); } - /// \brief Allocate a new slab and move the bump pointers over into the new + /// Allocate a new slab and move the bump pointers over into the new /// slab, modifying CurPtr and End. void StartNewSlab() { size_t AllocatedSlabSize = computeSlabSize(Slabs.size()); @@ -356,7 +356,7 @@ private: End = ((char *)NewSlab) + AllocatedSlabSize; } - /// \brief Deallocate a sequence of slabs. + /// Deallocate a sequence of slabs. void DeallocateSlabs(SmallVectorImpl::iterator I, SmallVectorImpl::iterator E) { for (; I != E; ++I) { @@ -366,7 +366,7 @@ private: } } - /// \brief Deallocate all memory for custom sized slabs. + /// Deallocate all memory for custom sized slabs. void DeallocateCustomSizedSlabs() { for (auto &PtrAndSize : CustomSizedSlabs) { void *Ptr = PtrAndSize.first; @@ -378,11 +378,11 @@ private: template friend class SpecificBumpPtrAllocator; }; -/// \brief The standard BumpPtrAllocator which just uses the default template +/// The standard BumpPtrAllocator which just uses the default template /// parameters. typedef BumpPtrAllocatorImpl<> BumpPtrAllocator; -/// \brief A BumpPtrAllocator that allows only elements of a specific type to be +/// A BumpPtrAllocator that allows only elements of a specific type to be /// allocated. /// /// This allows calling the destructor in DestroyAll() and when the allocator is @@ -435,7 +435,7 @@ public: Allocator.Reset(); } - /// \brief Allocate space for an array of objects without constructing them. + /// Allocate space for an array of objects without constructing them. T *Allocate(size_t num = 1) { return Allocator.Allocate(num); } }; diff --git a/include/llvm/Support/AtomicOrdering.h b/include/llvm/Support/AtomicOrdering.h index e93b755aa63b8cb3675788e3c45125351a7b789a..a679ab30243ee14e9c3937f181c4a59dac25c538 100644 --- a/include/llvm/Support/AtomicOrdering.h +++ b/include/llvm/Support/AtomicOrdering.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Atomic ordering constants. +/// Atomic ordering constants. /// /// These values are used by LLVM to represent atomic ordering for C++11's /// memory model and more, as detailed in docs/Atomics.rst. diff --git a/include/llvm/Support/BinaryByteStream.h b/include/llvm/Support/BinaryByteStream.h index db1ccba1398be4bfe8469f14c703518ebcc31d4b..f39ac4e24135b7fc2b365a48d67a02d55060b662 100644 --- a/include/llvm/Support/BinaryByteStream.h +++ b/include/llvm/Support/BinaryByteStream.h @@ -25,7 +25,7 @@ namespace llvm { -/// \brief An implementation of BinaryStream which holds its entire data set +/// An implementation of BinaryStream which holds its entire data set /// in a single contiguous buffer. BinaryByteStream guarantees that no read /// operation will ever incur a copy. Note that BinaryByteStream does not /// own the underlying buffer. @@ -69,7 +69,7 @@ protected: ArrayRef Data; }; -/// \brief An implementation of BinaryStream whose data is backed by an llvm +/// An implementation of BinaryStream whose data is backed by an llvm /// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in /// question. As with BinaryByteStream, reading from a MemoryBufferByteStream /// will never cause a copy. @@ -83,7 +83,7 @@ public: std::unique_ptr MemBuffer; }; -/// \brief An implementation of BinaryStream which holds its entire data set +/// An implementation of BinaryStream which holds its entire data set /// in a single contiguous buffer. As with BinaryByteStream, the mutable /// version also guarantees that no read operation will ever incur a copy, /// and similarly it does not own the underlying buffer. @@ -131,7 +131,7 @@ private: BinaryByteStream ImmutableStream; }; -/// \brief An implementation of WritableBinaryStream which can write at its end +/// An implementation of WritableBinaryStream which can write at its end /// causing the underlying data to grow. This class owns the underlying data. class AppendingBinaryByteStream : public WritableBinaryStream { std::vector Data; @@ -193,7 +193,7 @@ public: Error commit() override { return Error::success(); } - /// \brief Return the properties of this stream. + /// Return the properties of this stream. virtual BinaryStreamFlags getFlags() const override { return BSF_Write | BSF_Append; } @@ -201,7 +201,7 @@ public: MutableArrayRef data() { return Data; } }; -/// \brief An implementation of WritableBinaryStream backed by an llvm +/// An implementation of WritableBinaryStream backed by an llvm /// FileOutputBuffer. class FileBufferByteStream : public WritableBinaryStream { private: diff --git a/include/llvm/Support/BinaryStream.h b/include/llvm/Support/BinaryStream.h index d69a03eccfdbc434dbe296cea63c854317548724..7677214e48ee59e03ad895e52926e3151060e23b 100644 --- a/include/llvm/Support/BinaryStream.h +++ b/include/llvm/Support/BinaryStream.h @@ -26,7 +26,7 @@ enum BinaryStreamFlags { LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ BSF_Append) }; -/// \brief An interface for accessing data in a stream-like format, but which +/// An interface for accessing data in a stream-like format, but which /// discourages copying. Instead of specifying a buffer in which to copy /// data on a read, the API returns an ArrayRef to data owned by the stream's /// implementation. Since implementations may not necessarily store data in a @@ -39,21 +39,21 @@ public: virtual llvm::support::endianness getEndian() const = 0; - /// \brief Given an offset into the stream and a number of bytes, attempt to + /// Given an offset into the stream and a number of bytes, attempt to /// read the bytes and set the output ArrayRef to point to data owned by the /// stream. virtual Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) = 0; - /// \brief Given an offset into the stream, read as much as possible without + /// Given an offset into the stream, read as much as possible without /// copying any data. virtual Error readLongestContiguousChunk(uint32_t Offset, ArrayRef &Buffer) = 0; - /// \brief Return the number of bytes of data in this stream. + /// Return the number of bytes of data in this stream. virtual uint32_t getLength() = 0; - /// \brief Return the properties of this stream. + /// Return the properties of this stream. virtual BinaryStreamFlags getFlags() const { return BSF_None; } protected: @@ -66,7 +66,7 @@ protected: } }; -/// \brief A BinaryStream which can be read from as well as written to. Note +/// A BinaryStream which can be read from as well as written to. Note /// that writing to a BinaryStream always necessitates copying from the input /// buffer to the stream's backing store. Streams are assumed to be buffered /// so that to be portable it is necessary to call commit() on the stream when @@ -75,15 +75,15 @@ class WritableBinaryStream : public BinaryStream { public: ~WritableBinaryStream() override = default; - /// \brief Attempt to write the given bytes into the stream at the desired + /// Attempt to write the given bytes into the stream at the desired /// offset. This will always necessitate a copy. Cannot shrink or grow the /// stream, only writes into existing allocated space. virtual Error writeBytes(uint32_t Offset, ArrayRef Data) = 0; - /// \brief For buffered streams, commits changes to the backing store. + /// For buffered streams, commits changes to the backing store. virtual Error commit() = 0; - /// \brief Return the properties of this stream. + /// Return the properties of this stream. BinaryStreamFlags getFlags() const override { return BSF_Write; } protected: diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h index 3f5562ba751952494adad861571bb27bb11e165d..d1571cb37fc693c8cc80f47def7ba296878172ab 100644 --- a/include/llvm/Support/BinaryStreamArray.h +++ b/include/llvm/Support/BinaryStreamArray.h @@ -111,7 +111,7 @@ public: bool empty() const { return Stream.getLength() == 0; } - /// \brief given an offset into the array's underlying stream, return an + /// given an offset into the array's underlying stream, return an /// iterator to the record at that offset. This is considered unsafe /// since the behavior is undefined if \p Offset does not refer to the /// beginning of a valid record. diff --git a/include/llvm/Support/BinaryStreamReader.h b/include/llvm/Support/BinaryStreamReader.h index ae5ebb2c36286af1940fc76bfb2dfb20b5c98d86..fe77b550c4537184ce60325d29dce7514fe2a39d 100644 --- a/include/llvm/Support/BinaryStreamReader.h +++ b/include/llvm/Support/BinaryStreamReader.h @@ -24,7 +24,7 @@ namespace llvm { -/// \brief Provides read only access to a subclass of `BinaryStream`. Provides +/// Provides read only access to a subclass of `BinaryStream`. Provides /// bounds checking and helpers for writing certain common data types such as /// null-terminated strings, integers in various flavors of endianness, etc. /// Can be subclassed to provide reading of custom datatypes, although no diff --git a/include/llvm/Support/BinaryStreamRef.h b/include/llvm/Support/BinaryStreamRef.h index 5cf355be6fe9caa5269fa11f2fd305d4bc3dff1d..d8dc1392c01c229d6acd55bf21de22ac4e0d3747 100644 --- a/include/llvm/Support/BinaryStreamRef.h +++ b/include/llvm/Support/BinaryStreamRef.h @@ -147,7 +147,7 @@ protected: Optional Length; }; -/// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It +/// BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It /// provides copy-semantics and read only access to a "window" of the underlying /// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to /// say, it does not inherit and override the methods of BinaryStream. In @@ -266,7 +266,7 @@ public: /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef. operator BinaryStreamRef() const; - /// \brief For buffered streams, commits changes to the backing store. + /// For buffered streams, commits changes to the backing store. Error commit(); }; diff --git a/include/llvm/Support/BinaryStreamWriter.h b/include/llvm/Support/BinaryStreamWriter.h index f31db87c2f3a7f4f7c82f33cf58392a25b0cfb94..6e8a68a30474260b6a72faeea260d694119ea31a 100644 --- a/include/llvm/Support/BinaryStreamWriter.h +++ b/include/llvm/Support/BinaryStreamWriter.h @@ -24,7 +24,7 @@ namespace llvm { -/// \brief Provides write only access to a subclass of `WritableBinaryStream`. +/// Provides write only access to a subclass of `WritableBinaryStream`. /// Provides bounds checking and helpers for writing certain common data types /// such as null-terminated strings, integers in various flavors of endianness, /// etc. Can be subclassed to provide reading and writing of custom datatypes, diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h index 2e75cbdd29c1613dd6616b81f652386d69955586..4b468f7acb322f3a8a40f3c83277075db485444c 100644 --- a/include/llvm/Support/BlockFrequency.h +++ b/include/llvm/Support/BlockFrequency.h @@ -28,32 +28,32 @@ class BlockFrequency { public: BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { } - /// \brief Returns the maximum possible frequency, the saturation value. + /// Returns the maximum possible frequency, the saturation value. static uint64_t getMaxFrequency() { return -1ULL; } - /// \brief Returns the frequency as a fixpoint number scaled by the entry + /// Returns the frequency as a fixpoint number scaled by the entry /// frequency. uint64_t getFrequency() const { return Frequency; } - /// \brief Multiplies with a branch probability. The computation will never + /// Multiplies with a branch probability. The computation will never /// overflow. BlockFrequency &operator*=(BranchProbability Prob); BlockFrequency operator*(BranchProbability Prob) const; - /// \brief Divide by a non-zero branch probability using saturating + /// Divide by a non-zero branch probability using saturating /// arithmetic. BlockFrequency &operator/=(BranchProbability Prob); BlockFrequency operator/(BranchProbability Prob) const; - /// \brief Adds another block frequency using saturating arithmetic. + /// Adds another block frequency using saturating arithmetic. BlockFrequency &operator+=(BlockFrequency Freq); BlockFrequency operator+(BlockFrequency Freq) const; - /// \brief Subtracts another block frequency using saturating arithmetic. + /// Subtracts another block frequency using saturating arithmetic. BlockFrequency &operator-=(BlockFrequency Freq); BlockFrequency operator-(BlockFrequency Freq) const; - /// \brief Shift block frequency to the right by count digits saturating to 1. + /// Shift block frequency to the right by count digits saturating to 1. BlockFrequency &operator>>=(const unsigned count); bool operator<(BlockFrequency RHS) const { diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index b403d7fbf117dbef47bd89993ade8cd8c0000704..3a88e71c24804234c247c51bc98a4889883aecfa 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -73,7 +73,7 @@ public: void dump() const; - /// \brief Scale a large integer. + /// Scale a large integer. /// /// Scales \c Num. Guarantees full precision. Returns the floor of the /// result. @@ -81,7 +81,7 @@ public: /// \return \c Num times \c this. uint64_t scale(uint64_t Num) const; - /// \brief Scale a large integer by the inverse. + /// Scale a large integer by the inverse. /// /// Scales \c Num by the inverse of \c this. Guarantees full precision. /// Returns the floor of the result. diff --git a/include/llvm/Support/CachePruning.h b/include/llvm/Support/CachePruning.h index f38ce1785961e0cb2444a5fb05618f66cad79810..cf3f8ec67a52ce9fd7866b1b2f8467cbcf7ac8e5 100644 --- a/include/llvm/Support/CachePruning.h +++ b/include/llvm/Support/CachePruning.h @@ -52,9 +52,11 @@ struct CachePruningPolicy { /// the number of files based pruning. /// /// This defaults to 1000000 because with that many files there are - /// diminishing returns on the effectiveness of the cache, and some file - /// systems have a limit on how many files can be contained in a directory - /// (notably ext4, which is limited to around 6000000 files). + /// diminishing returns on the effectiveness of the cache. Some systems have a + /// limit on total number of files, and some also limit the number of files + /// per directory, such as Linux ext4, with the default setting (block size is + /// 4096 and large_dir disabled), there is a per-directory entry limit of + /// 508*510*floor(4096/(40+8))~=20M for average filename length of 40. uint64_t MaxSizeFiles = 1000000; }; diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index baa2a814e9a16b68038b1edc8178ca234f7f39ff..3f21e0f9ebc33a316869e6fa8d5a57fe8bc3b99f 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -60,7 +60,7 @@ struct isa_impl { } }; -/// \brief Always allow upcasts, and perform no dynamic check for them. +/// Always allow upcasts, and perform no dynamic check for them. template struct isa_impl< To, From, typename std::enable_if::value>::type> { diff --git a/include/llvm/Support/CodeGenCoverage.h b/include/llvm/Support/CodeGenCoverage.h index d5bd837bff2894c7333653a207d41cba412f61e6..c863be35b82231a6b5888aac16b039143204366e 100644 --- a/include/llvm/Support/CodeGenCoverage.h +++ b/include/llvm/Support/CodeGenCoverage.h @@ -23,15 +23,18 @@ protected: BitVector RuleCoverage; public: + using const_covered_iterator = BitVector::const_set_bits_iterator; + CodeGenCoverage(); void setCovered(uint64_t RuleID); - bool isCovered(uint64_t RuleID); + bool isCovered(uint64_t RuleID) const; + iterator_range covered() const; bool parse(MemoryBuffer &Buffer, StringRef BackendName); bool emit(StringRef FilePrefix, StringRef BackendName) const; void reset(); }; -} // end namespace llvm +} // namespace llvm #endif // ifndef LLVM_SUPPORT_CODEGENCOVERAGE_H diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index f043c112861b8df41a478e165d45b4900fd74eef..799b41fbf8b0fcb2c1e9542f99ec8b4a64ee864c 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -30,6 +30,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" #include #include #include @@ -94,7 +95,7 @@ void PrintOptionValues(); // Forward declaration - AddLiteralOption needs to be up here to make gcc happy. class Option; -/// \brief Adds a new option for parsing and provides the option it refers to. +/// Adds a new option for parsing and provides the option it refers to. /// /// \param O pointer to the option /// \param Name the string name for the option to handle during parsing @@ -362,7 +363,10 @@ public: bool MultiArg = false); // Prints option name followed by message. Always returns true. - bool error(const Twine &Message, StringRef ArgName = StringRef()); + bool error(const Twine &Message, StringRef ArgName = StringRef(), raw_ostream &Errs = llvm::errs()); + bool error(const Twine &Message, raw_ostream &Errs) { + return error(Message, StringRef(), Errs); + } inline int getNumOccurrences() const { return NumOccurrences; } inline void reset() { NumOccurrences = 0; } @@ -1770,7 +1774,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false); // Public interface for accessing registered options. // -/// \brief Use this to get a StringMap to all registered named options +/// Use this to get a StringMap to all registered named options /// (e.g. -help). Note \p Map Should be an empty StringMap. /// /// \return A reference to the StringMap used by the cl APIs to parse options. @@ -1799,7 +1803,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false); /// than just handing around a global list. StringMap